SpringMVC学习笔记

news2025/8/7 9:23:01

目录

SpringMVC

为什么出现了SpringMVC?

什么是SpringMVC?

简单使用

SpringMVC工作流程

设置bean加载控制

在服务器启动时加载SpringConfig 

后台接受五种类型参数传递

REST风格

描述

RESTful入门

新建以下目录

实体类

控制器

统一异常处理

新建Code类用于记录状态码

新建异常处理类

新建异常处理器

模拟异常

结果

拦截器

使用

文件上传

part方式

Multipart方式 

IDEA SpringMVC配置详情

XML方式(常用)

依赖引入

web.xml文件

Application.xml

SpringMVC.xml

路径一览

 纯注解方式

依赖引入

ServletContainersInitConfig

SpringConfig

SpringMVCConfig

注解方式返回给前台的数据乱码的解决


 

SpringMVC

为什么出现了SpringMVC?

因为servlet处理请求和数据的时候,存在的问题是一个servlet只能处理一个请求 针对web层进行了优化,采用了MVC设计模式,将其设计为controller、view和Model’

什么是SpringMVC?

SpringMVC是一种基于Java实现MVC模型的轻量级Web框架

优点是使用简单、开发便捷(相比于Servlet) 灵活性强

简单使用

1 依赖引入

    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
//解决冲突的问题
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>
    </dependencies>

    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

2 建立基本目录

目录如下 

3 新建SpringMVC配置类

package com.learn.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.learn.controller")
public class SpringMVCConfig {
}

4 新建web.xml配置类(用于替换web.xml)

package com.learn.config;

import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.support.AbstractDispatcherServletInitializer;

public class ServletContainersInitConfig extends
        AbstractDispatcherServletInitializer {
    //加载springmvc配置类
    protected WebApplicationContext createServletApplicationContext() {
//初始化WebApplicationContext对象
        AnnotationConfigWebApplicationContext ctx = new
                AnnotationConfigWebApplicationContext();
//加载指定配置类
        ctx.register(SpringMVCConfig.class);
        return ctx;
    }

    //设置由springmvc控制器处理的请求映射路径
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    //加载spring配置类
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }
}

5 新建控制器

package com.learn.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class UserController {
    //浏览器请求的路径
    @RequestMapping("/save")
    //标识发送的数据为JSON格式
    @ResponseBody
    public String save(){
        System.out.println("user save ...");
        return "{'info':'springmvc'}";
    }
}

6 最终目录

7 配置web服务器

添加webapp框架

 配置工件

配置服务器

 8 启动调试

 相关知识点

SpringMVC是基于Spring的,在pom.xml只导入了spring-webmvc jar包的原因是它会自动依赖
spring相关坐标
AbstractDispatcherServletInitializer类是SpringMVC提供的快速初始化Web3.0容器
的抽象类
AbstractDispatcherServletInitializer提供了三个接口方法供用户实现
createServletApplicationContext方法,创建Servlet容器时,加载SpringMVC对应
的bean并放入WebApplicationContext对象范围中,而WebApplicationContext的作用
范围为ServletContext范围,即整个web容器范围
getServletMappings方法,设定SpringMVC对应的请求映射路径,即SpringMVC拦截哪些
请求
createRootApplicationContext方法,如果创建Servlet容器时需要加载非SpringMVC
对应的bean,使用当前方法进行,使用方式和createServletApplicationContext相同。
createServletApplicationContext用来加载SpringMVC环境
createRootApplicationContext用来加载Spring环境

@RequestMapping

SpringMVC控制器类或方法定义上方

设置当前控制器方法请求访问路径

@ResponseBody

SpringMVC控制器类或方法定义上方

设置当前控制器方法响应内容为当前返回值,无需解析

SpringMVC工作流程

1. 发送请求http://localhost/save
2. web容器发现该请求满足SpringMVC拦截规则,将请求交给SpringMVC处理
3. 解析请求路径/save
4. 由/save匹配执行对应的方法save()
上面的第五步已经将请求路径和方法建立了对应关系,通过/save就能找到对应的save方法
5. 执行save()
6. 检测到有@ResponseBody直接将save()方法的返回值作为响应体返回给请求方

设置bean加载控制

1 修改Spring配置类,设定扫描范围为精准范围。

2 修改Spring配置类,设定扫描范围为com.itheima,排除掉controller包中的bean

@Configuration
@ComponentScan(value="com.itheima",
excludeFilters=@ComponentScan.Filter(
type = FilterType.ANNOTATION,
classes = Controller.class
)
)
public class SpringConfig {
}
excludeFilters属性:设置扫描加载bean时,排除的过滤规则
type属性:设置排除规则,当前使用按照bean定义时的注解类型进行排除
ANNOTATION:按照注解排除
ASSIGNABLE_TYPE:按照指定的类型过滤
ASPECTJ:按照Aspectj表达式排除,基本上不会用
REGEX:按照正则表达式排除
CUSTOM:按照自定义规则排除
大家只需要知道第一种ANNOTATION即可
classes属性:设置排除的具体注解类,当前设置排除@Controller定义的bean

在服务器启动时加载SpringConfig 

1 更改ServletContainersInitConfig 配置类

public class ServletContainersInitConfig extends
AbstractDispatcherServletInitializer {
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new
AnnotationConfigWebApplicationContext();
ctx.register(SpringMvcConfig.class);
return ctx;
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
protected WebApplicationContext createRootApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new
AnnotationConfigWebApplicationContext();
ctx.register(SpringConfig.class);
return ctx;
}
}
1

2 ServletContainersInitConfig 的内容替换成如下

public class ServletContainersInitConfig extends
AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
}

后台接受五种类型参数传递

普通参数

  public String commonParam(@RequestParam("name") String name, int age)
    {
        System.out.println("普通参数传递 name ==> "+name);
        System.out.println("普通参数传递 age ==> "+age);
        return "{'module':"+name+"}";
    }

POJO类型参数

  //POJO类型的参数,直接使用实体类接受,但是注意,实体类中的字段必须和参数名相同
    public String commonParam(User user)
    {
        System.out.println("普通参数传递 name ==> "+user.getName());
        System.out.println("普通参数传递 age ==> "+user.getAge());
        return "{'module':"+user.getName()+"}";
    }

嵌套POJO类型参数

实体

public class Ts {
    User user;
    Address address;
}
    //POJO类型的嵌套参数,直接使用实体类接受,但是注意,实体类中的字段必须和参数名相同
    public String commonParam(Ts ts)
    {
        System.out.println("普通参数传递 name ==> "+ts.getUser().getName());
        System.out.println("普通参数传递 age ==> "+ts.getUser().getAge());
        return "{'module':"+ts.getUser().getName()+"}";
    }

请求写法

数组类型参数

    //数组参数:同名请求参数可以直接映射到对应名称的形参数组对象中
    public void commonParam(String[] array)
    {
        System.out.println(Arrays.toString(array));
    }

请求参数的名,必须要和后台的数组名相同 

集合类型参数

    public String listParam(@RequestParam List<String> likes){
        System.out.println("集合参数传递 likes ==> "+ likes);
        return "{'module':'list param'}";
    }

 请求参数的名,必须要和后台的集合名相同

JSON传输参数 

SpringMVC接收JSON数据的实现步骤为:

(1)导入jackson包

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.0</version>
        </dependency>

(2)使用PostMan发送JSON数据

(3)开启SpringMVC注解驱动,在配置类上添加@EnableWebMvc注解

@EnableWebMvc
@RequestMapping("/listPojoParamForJson")
@ResponseBody
public String listPojoParamForJson(@RequestBody List<User> list){
System.out.println("list pojo(json)参数传递 list ==> "+list);
return "{'module':'list pojo for json param'}";
}

(4)Controller方法的参数前添加@RequestBody注解

@RequestParam与@RequestBody的区别:
 

@RequestParam用于接收url地址传参,表单传参【application/x-www-formurlencoded】 @RequestBody用于接收json数据【application/json】 @RequestMapping("/listPojoParamForJson") @ResponseBody public String listPojoParamForJson(@RequestBody List list){ System.out.println("list pojo(json)参数传递 list ==> "+list); return "{'module':'list pojo for json param'}"; } 应用 后期开发中,发送json格式数据为主,@RequestBody应用较广 如果发送非json格式数据,选用@RequestParam接收请求参数

时间类型参数

如果格式不一致,需要我们使用@DateTimeFormat来进行格式化

@RequestMapping("/dataParam")
@ResponseBody
public String dataParam(Date date,
@DateTimeFormat(pattern="yyyy-MM-dd") Date date1,
@DateTimeFormat(pattern="yyyy/MM/dd HH:mm:ss") Date
date2)
System.out.println("参数传递 date ==> "+date);
System.out.println("参数传递 date1(yyyy-MM-dd) ==> "+date1);
System.out.println("参数传递 date2(yyyy/MM/dd HH:mm:ss) ==> "+date2);
return "{'module':'data param'}";
}

响应

controller在接受请求后可以转发给service,从而获得一些响应内容,我们需要把他们返回给前台

@EnableWebMvc
@Controller
public class UserController {
@RequestMapping("/toJsonList")
@ResponseBody
public List<User> toJsonList(){
System.out.println("返回json集合数据");
User user1 = new User();
user1.setName("传智播客");
user1.setAge(15);
User user2 = new User();
user2.setName("黑马程序员");
user2.setAge(12);
List<User> userList = new ArrayList<User>();
userList.add(user1);
userList.add(user2);
return userList;
}
}

返回值为实体类对象,设置返回值为实体类类型,即可实现返回对应对象的json数据,需要依赖 @ResponseBody注解和@EnableWebMvc注解

返回jsp页面

@Controller
public class UserController {
@RequestMapping("/toJumpPage")
//注意
//1.此处不能添加@ResponseBody,如果加了该注入,会直接将page.jsp当字符串返回前端
//2.方法需要返回String
public String toJumpPage(){
System.out.println("跳转页面");
return "page.jsp";
}
}

返回纯文本

@Controller
public class UserController {
@RequestMapping("/toText")
//注意此处该注解就不能省略,如果省略了,会把response text当前页面名称去查找,如果没有
回报404错误
@ResponseBody
public String toText(){
System.out.println("返回纯文本数据");
return "response text";
}
}

REST风格

描述

rest:表现形式状态转换,它是一种软件架构风格
当我们想表示一个网络资源的时候,可以使用两种方式:
传统风格资源描述形式
http://localhost/user/getById?id=1 查询id为1的用户信息
http://localhost/user/saveUser 保存用户信息
REST风格描述形式
http://localhost/user/1
http://localhost/user
传统方式一般是一个请求url对应一种操作,这样做不仅麻烦,也不安全,因为会程序的人读取了你的
请求url地址,就大概知道该url实现的是一个什么样的操作。
查看REST风格的描述,你会发现请求地址变的简单了,并且光看请求URL并不是很能猜出来该URL的
具体功能
所以REST的优点有:
隐藏资源的访问行为,无法通过地址得知对资源是何种操作
书写简化

根据REST风格对资源进行访问称为RESTful

RESTful入门

新建以下目录

其中配置文件可看(就在文章的下面)--》IDEA SpringMVC配置详情《---

实体类

public class Book {private String name;
    private double price;}


    public class User {
        private String name;
        private int age;
    }

控制器


@RestController
@RequestMapping("/books")
public class BookController {
    @Autowired
    private BookService bookService;
    @PostMapping
    public Result save(@RequestBody Book book) {
        boolean b = bookService.save(book);
        return new Result(b?Code.SAVE_OK:Code.SAVE_ERR);
    }
    @PutMapping
    public Result update(@RequestBody Book book) {
        boolean b = bookService.update(book);
        return new Result(b?Code.UPDATE_OK:Code.UPDATE_ERR);
    }
}

统一异常处理

新建Code类用于记录状态码

package com.learn.entity;

public class Code {
    public static final Integer SAVE_OK = 20011;
    public static final Integer DELETE_OK = 20021;
    public static final Integer UPDATE_OK = 20031;
    public static final Integer GET_OK = 20041;
    public static final Integer SAVE_ERR = 20010;
    public static final Integer DELETE_ERR = 20020;
    public static final Integer UPDATE_ERR = 20030;
    public static final Integer GET_ERR = 20040;

    //异常处理状态码
    public static final Integer SYSTEM_ERR = 50001;
    public static final Integer SYSTEM_TIMEOUT_ERR = 50002;
    public static final Integer SYSTEM_UNKNOW_ERR = 59999;
    public static final Integer BUSINESS_ERR = 60002;
}

新建异常处理类

package com.learn.exception;
//让自定义异常类继承RuntimeException的好处是,后期在抛出这两个异常的时候,就不用在
//try...catch...或throws了
//自定义异常类中添加code属性的原因是为了更好的区分异常是来自哪个业务的

public class BusinessException extends RuntimeException{
    private Integer code;
    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
    public BusinessException(Integer code, String message) {
        super(message);
        this.code = code;
    }
    public BusinessException(Integer code, String message, Throwable cause) {
//        这里的super直接传到了Throwable类的身上
        super(message, cause);
        this.code = code;
    }
}
package com.learn.exception;

public class SystemException extends RuntimeException{
    private Integer code;
    public Integer getCode() {
        return code;
    }
    public void setCode(Integer code) {
        this.code = code;
    }
    public SystemException(Integer code, String message) {
        super(message);
        this.code = code;
    }
    public SystemException(Integer code, String message, Throwable cause) {
        super(message, cause);
        this.code = code;
    }
}

新建异常处理器

package com.learn.exception;

import com.learn.entity.Code;
import com.learn.entity.Result;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;


@RestControllerAdvice
public class ProjectExceptionAdvice {
    //@ExceptionHandler用于设置当前处理器类对应的异常类型
    @ExceptionHandler(SystemException.class)
    public Result doSystemException(SystemException ex){
        //记录日志
        //发送消息给运维
        //发送邮件给开发人员,ex对象发送给开发人员
        return new Result(null,ex.getCode(),ex.getMessage());
    }

    @ExceptionHandler(BusinessException.class)
    public Result doBusinessException(BusinessException ex){
        return new Result(null,ex.getCode(),ex.getMessage());
    }

    //除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常
    @ExceptionHandler(Exception.class)
    public Result doOtherException(Exception ex){
    //记录日志
    //发送消息给运维
    //发送邮件给开发人员,ex对象发送给开发人员
        return new Result(null,Code.SYSTEM_UNKNOW_ERR,"系统繁忙,请稍后再试!");
    }
}

模拟异常

    @DeleteMapping("/{id}")
    public Result delete(@PathVariable Integer id)
    {
        if(id==1)
        {
            //抛出异常后下面的delete程序就不会再执行了
            throw new BusinessException(Code.BUSINESS_ERR,"有人想干掉管理员!",new Throwable());
        }
        boolean b = bookService.delete(id);
        return new Result(b?Code.DELETE_OK:Code.DELETE_ERR);
    }

结果

拦截器

(1)浏览器发送一个请求会先到Tomcat的web服务器
(2)Tomcat服务器接收到请求以后,会去判断请求的是静态资源还是动态资源
(3)如果是静态资源,会直接到Tomcat的项目部署目录下去直接访问
(4)如果是动态资源,就需要交给项目的后台代码进行处理
(5)在找到具体的方法之前,我们可以去配置过滤器(可以配置多个),按照顺序进行执行
(6)然后进入到到中央处理器(SpringMVC中的内容),SpringMVC会根据配置的规则进行拦截
(7)如果满足规则,则进行处理,找到其对应的controller类中的方法进行执行,完成后返回结果
(8)如果不满足规则,则不进行处理
(9)这个时候,如果我们需要在每个Controller方法执行的前后添加业务,具体该如何来实现?
这个就是拦截器要做的事。
拦截器(Interceptor)是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法
的执行
作用:
在指定的方法调用前后执行预先设定的代码
阻止原始方法的执行
总结:拦截器就是用来做增强

使用

新建拦截器ProjectInterceptor

package com.learn.interceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Component
public class ProjectInterceptor implements HandlerInterceptor {
    @Override
    //原始方法调用前执行的内容
    public boolean preHandle(HttpServletRequest request, HttpServletResponse
            response, Object handler) throws Exception {
        System.out.println("preHandle...");
        //获取请求头
        String header = request.getHeader("Content-Type");
        System.out.println("请求头为:"+header);
        HandlerMethod method=(HandlerMethod)handler;
        System.out.println("执行的方法是:"+method.getMethod().getName());
        //如果返回为fasle则此拦截器中的方法将不再执行
        return true;
    }
    @Override
    //原始方法调用后执行的内容
    public void postHandle(HttpServletRequest request, HttpServletResponse
            response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle...");
        HandlerMethod method=(HandlerMethod)handler;
        System.out.println("执行的方法是:"+method.getMethod().getName());
    }
    @Override
    //原始方法调用完成后执行的内容
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response, Object handler, Exception ex) throws Exception
    {
        System.out.println("afterCompletion...");
        HandlerMethod method=(HandlerMethod)handler;
        System.out.println("执行的方法是:"+method.getMethod().getName());
    }

}

在springmvc中配置拦截器

<!--    拦截器配置-->
    <!-- 配置拦截器 -->
    <mvc:interceptors>
        <!-- 配置一个全局拦截器,拦截所有请求 -->
        <bean class="com.learn.interceptor.ProjectInterceptor" />
        <mvc:interceptor>
            <!-- 配置拦截器作用的路径 -->
            <mvc:mapping path="/**" />
            <!-- 配置不需要拦截作用的路径 -->
            <mvc:exclude-mapping path="/a" />
            <!-- 定义<mvc:interceptor>元素中,表示匹配指定路径的请求才进行拦截 -->
            <bean class="com.learn.interceptor.ProjectInterceptor" />
        </mvc:interceptor>
        <mvc:interceptor>
            <!-- 配置拦截器作用的路径 -->
            <mvc:mapping path="/gotoTest" />
            <!-- 定义在<mvc:interceptor>元素中,表示匹配指定路径的请求才进行拦截 -->
            <bean class="com.learn.interceptor.ProjectInterceptor" />
        </mvc:interceptor>
    </mvc:interceptors>

 

文件上传

part方式

新建文件上传控制器

package com.learn.controller;

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.Part;
import java.util.Collection;

@RestController
@CrossOrigin(origins = "*", maxAge = 3600)
public class FileUpdateController {

    //    part方式单文件上传
    @GetMapping("/updateImg")
    private String imgUpdate(HttpServletRequest request) {
        try {
            Part image = request.getPart("image");
            String realPath = request.getServletContext().getRealPath("/WEB-INF/img");
            image.write(realPath + image.getSubmittedFileName());
            return "success";
        } catch (Exception e) {
            System.out.println("图片上传失败");
            return "fail";
        }
    }

    //    part方式多文件上传
    @GetMapping("/updateImgs")
    private String imgsUpdate(HttpServletRequest request) {
        try {
            Collection<Part> requestParts = request.getParts();
            //获取上传路径(web目录中的)
            String realPath = request.getServletContext().getRealPath("/WEB-INF/img");
            requestParts.forEach(part -> {
                try {
                    part.write(realPath + part.getSubmittedFileName());
                } catch (Exception e) {
                    System.out.println(part.getSubmittedFileName() + "上传出错!");
                }
            });
            return "success";
        } catch (Exception e) {
            System.out.println("图片上传失败");
            return "fail";
        }
    }
}

web.xml配置

    <servlet>
<!--        配置文件上传-->
        <multipart-config>
<!--            单位为字节-->
<!--            单个文件大小-->
            <max-file-size>5242880</max-file-size>
<!--            一次请求所有文件大小-->
            <max-request-size>52428800</max-request-size>
        </multipart-config>
    </servlet>

Multipart方式 

以下的代码可能会上传失败

依赖引入

<!--        springmvc文件上传-->
        <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.11.0</version>
        </dependency>

springmvc.xml

<!--    配置视图解析器-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"></bean>

编写控制器

package com.learn.controller;

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;

@RestController
@CrossOrigin(origins = "*", maxAge = 3600)
public class FileUpdate2Controller {
    @GetMapping("/fileUpdate")
    protected String fileUpdate(HttpServletRequest request, MultipartFile multipartFile)
    {
        try {
            String realPath = request.getServletContext().getRealPath("/WEB-INF/img/");
            String filename = multipartFile.getOriginalFilename();
            multipartFile.transferTo(new File(realPath,filename));
            return "success";
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
            return "fail";
        }
    }
}

IDEA SpringMVC配置详情

XML方式(常用)

依赖引入

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>SSM2</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <!--spring相关的依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>
        <!-- aspectjweaver-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.6</version>
            <scope>runtime</scope>
        </dependency>
        <!--Mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.16</version>
        </dependency>

        <!--单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

        <!--json-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>

<!--        springmvc文件上传-->
        <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.11.0</version>
        </dependency>

    </dependencies>

    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>
</project>

web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <!--需要给ContextLoaderListener指定Spring配置文件-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:Application.xml</param-value>
    </context-param>
    <!--    tomcat整合SpringMVC-->

    <!--SpringMVC容器,核心:DispatcherServlet-->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:SpringMVC.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>

<!--        配置文件上传-->
        <multipart-config>
<!--            单位为字节-->
<!--            单个文件大小-->
            <max-file-size>5242880</max-file-size>
<!--            一次请求所有文件大小-->
            <max-request-size>52428800</max-request-size>
        </multipart-config>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!--Filter处理乱码-->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceRequestEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <!--      Todo  注意这里如果过滤器不生效,请去掉*号-->
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

Application.xml

 Spring配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-4.2.xsd
     http://www.springframework.org/schema/tx
      http://www.springframework.org/schema/tx/spring-tx.xsd">

    <context:component-scan base-package="com.learn">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>


    <context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${jdbc.driveClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
    <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.learn.dao"/>
    </bean>
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <tx:annotation-driven transaction-manager="transactionManager"/>

</beans>

SpringMVC.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd">


    <context:component-scan base-package="com.learn.controller"/>

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**" />
            <bean class="com.learn.interceptor.ProjectInterceptor" />
        </mvc:interceptor>
    </mvc:interceptors>

    <mvc:annotation-driven>
        <mvc:message-converters>

            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes">
                <list>
                    <value>text/html;charset=utf-8</value>
                    <value>application/json;charset=UTF-8</value>
                </list>
             </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>
    
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="5242880" />
        <property name="maxInMemorySize" value="4096" />
        <property name="defaultEncoding" value="UTF-8"></property>
    </bean>

    <mvc:default-servlet-handler/>

    <mvc:cors>
        <mvc:mapping path="/**" />
    </mvc:cors>
</beans>

路径一览

 纯注解方式

(返回给前台的中文可能会出现乱码)

依赖引入

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>SSM2</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <!--spring相关的依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.2.10.RELEASE</version>
        </dependency>
        <!-- aspectjweaver-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.6</version>
            <scope>runtime</scope>
        </dependency>
        <!--Mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.6</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.16</version>
        </dependency>

        <!--单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

        <!--json-->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>

<!--        springmvc文件上传-->
        <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.11.0</version>
        </dependency>

    </dependencies>

    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>
</project>

ServletContainersInitConfig

package com.learn.config;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import javax.servlet.Filter;

public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer
    {
        protected Class<?>[] getServletConfigClasses() {
            return new Class[]{SpringMVCConfig.class};
        }
        protected String[] getServletMappings() {
            return new String[]{"/"};
        }
        protected Class<?>[] getRootConfigClasses() {
            return new Class[0];
        }
        //乱码处理(只能处理后台接受到的参数乱码问题,返回给前台的json数据不会乱码)
        @Override
        protected Filter[] getServletFilters() {
            CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
            encodingFilter.setEncoding("UTF-8");
            encodingFilter.setForceRequestEncoding(true);
            HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();
            return new Filter[]{encodingFilter, hiddenHttpMethodFilter};
        }

    }

SpringConfig

package com.learn.config;

import com.learn.controller.UserController;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;

@Configuration
@ComponentScan(value = "com.learn",excludeFilters = @ComponentScan.Filter(
        type = FilterType.ANNOTATION,
        classes = UserController.class
))
public class SpringConfig {
}

SpringMVCConfig

package com.learn.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.learn.controller")
public class SpringMVCConfig {

}

注解方式返回给前台的数据乱码的解决

就是要在 @RequestMapping上加上produces = "text/html;charset=utf-8"

给个实例

package com.learn.controller;
import com.learn.entity.Ts;
import com.learn.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Arrays;
import java.util.List;

@Controller
public class UserController {
    //浏览器请求的路径
    @RequestMapping(value = "/getdata",produces = "text/html;charset=utf-8")
    //标识发送的数据为JSON格式
    @ResponseBody
    //如果前端传的参数和后端不一样可以使用注解,@RequestParam
    public String commonParam(@RequestParam("name") String name, int age)
    {
        System.out.println("普通参数传递 name ==> "+name);
        System.out.println("普通参数传递 age ==> "+age);
        return "{'module':"+name+"}";
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/15627.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c#反序列化json

语句&#xff1a;JsonConvert.DeserializeObject(json); json字符串&#xff1a; [ { "id": "130000", "cityList": [ { "cityList": [ { …

Linux root用户忘记密码的恢复方法

日常运维工作中可能会遇到服务器忘记root密码的问题&#xff0c;本次以红帽8为例&#xff0c;讲解在忘记root密码后如何绕过密码登录然后重新设置密码的办法 目录 准备工作 问题复现 启动并进入引导 进入修复模式 修改用户密码文件 重置密码 准备工作 下载与系统匹配的…

Python编程 元组的创建

作者简介&#xff1a;一名在校计算机学生、每天分享Python的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.元组知识点 二.元组(tuple) 1.元组介绍(掌握) 2.元组创建(掌握) 3.…

第十四届蓝桥杯校模拟赛-编程大题详解+代码(二)

前言&#xff1a;这几天有不少小伙伴催促我尽快更新后五道编程题题解&#xff0c;然鄙人实在水平有限&#xff0c;实事求是&#xff0c;能力不足&#xff0c;不堪众望。思索良久&#xff0c;第九题有解题思路且已完成部分解题&#xff0c;但未完全完成&#xff0c;第十题尚未有…

python 数据挖掘与机器学习核心技术

近年来&#xff0c;Python编程语言受到越来越多科研人员的喜爱&#xff0c;在多个编程语言排行榜中持续夺冠。同时&#xff0c;伴随着深度学习的快速发展&#xff0c;人工智能技术在各个领域中的应用越来越广泛。机器学习是人工智能的基础&#xff0c;因此&#xff0c;掌握常用…

《FFmpeg Basics》中文版-11-格式之间转换

正文 ffmpeg工具的最常见用法是从一种音频或视频格式转换为另一种相关的格式。 格式参数在输出文件之前由-f选项设置&#xff0c;或者在输入文件之前也有原始输入&#xff0c;具体的可用格式信息在[显示帮助和功能]一章中列出来了。 多媒体格式介绍 文件格式 媒体格式是能够…

OpenSSH移植到Linux开发板

OpenSSH移植到Linux开发板 文章目录OpenSSH移植到Linux开发板前言一、移植zlib库二、 移植openssl库三、 移植openssh库1. 在开发板中创建目录2. 将文件拷贝到对应目录下3. 创建对应软连接4. 开发板上生成密钥文件5. 开启SSH前言 在Linux开发中&#xff0c;有时候需要远程登录…

BLE学习(2):广播包报文格式详解

文章目录1 广播通道2 广播包参考手册&#xff1a; BLUETOOTH SPECIFICATION Version 5.0为了能够充分理解蓝牙的广播&#xff0c;我们先了解一下BLE架构的GAP(Generic Access Profile)层。 GAP层提供决定蓝牙设备之间如何交互的框架&#xff0c;包括&#xff1a; 蓝牙设备的角…

PHP 底层的运行机制和工作原理

阅读目录阐述一、PHP的设计理念及特点PHP 为什么没有多线程&#xff1f;1、PHP 与多线程2、PHP是单线程&#xff0c;多进程模型3、 php为什么选择多进程&#xff0c;而不是多线程4、场景二、PHP 四层体系1、上层应用2、Sapi3、Extensions&#xff08;扩展&#xff09;4、Zend 引…

【目标检测】Fast R-CNN论文详细解读

目录&#xff1a;Fast R-CNN论文解读一、前言1. R-CNN的步骤及缺点2. SPP Net的步骤二、Fast R-CNN1. R-CNN的缺点2. SPPNet的缺点3. Fast R-CNN的优点4. Fast R-CNN的模型结构和训练流程5. 初始化预训练网络结构6. 微调7. 多任务损失函数8. ROI层的反向传播9. SGD超参数选择10…

Java后端面试到底要如何准备?

我把面试准备拆成以下几个步骤&#xff1a; 1.写简历 2.整理好自己最熟悉的项目&#xff0c;相对有代表性的项目。 3.整理自己的技术栈 4.收拾好自己的自我介绍 5.被八股文 6.模拟面试 7.针对模拟面试表现出来的问题进行改进 8.开始投投简历 本人 10 年开发经验&#…

jsp课程设计管理系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 课程设计管理系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql&#xff0c;使…

单片机毕业设计 stm32智能手环

文章目录1 简介1 项目背景意义2 系统方案的设计3 系统总体结构4 系统硬件设计4.1 主控模块4.2 姿态解算模块&#xff1a;MPU60504.3 DS3231实物图4.4 TFT显示模块4.5 硬件连接效果5 跌倒检测算法原理5.1 跌倒检测的判定流程5.2 关键算法实现1 简介 &#x1f525; Hi&#xff0…

CIPU落地专有云:是“小众需求”还是“机会之门”?

2022 年 11 月&#xff0c;云栖大会主论坛&#xff0c;阿里巴巴集团副总裁、阿里云智能基础产品事业部负责人蒋江伟分享了阿里云专有云的一项新进展 —— CIPU 落地飞天企业版。在分析师峰会上&#xff0c;阿里巴巴集团研究员、阿里云专有云总经理刘国华也向分析师们详细介绍了…

双一流高校全球通邮经验:Coremail安全海外中继提升科研效率

在这个“后疫情时代”&#xff0c;高校间的国际交流合作更应架起桥梁&#xff0c;承担起文明交流互鉴的责任&#xff0c;邮件往来交流作为学术交流的重要工具&#xff0c;保障全球高校学术交流安全畅通&#xff0c;是Coremail针对高校教育邮件服务的重点之一。 针对高校行业面临…

python一键采集高质量陪玩,心动主播随心选......

人生苦短&#xff0c;我用python 北京时间11月6日上午&#xff0c;2022英雄联盟全球总决赛&#xff08;S12&#xff09;冠亚军决赛在美国旧金山大通中心球馆进行&#xff0c;随着DRX的成功夺冠&#xff0c;在全球进一步掀起了电竞热潮。 newzoo 《2022电竞市场报告》显示&…

《MySQL实战45讲》——学习笔记18 “索引失效、函数/隐式转换“【建议收藏】

本文介绍几种MYSQL中索引失效的典型SQL用法&#xff0c;包括对索引字段使用函数、索引字段隐式类型转换&#xff08;如字符串转数值类型&#xff0c;实质上也是使用CAST函数&#xff09;、索引字段隐式字符编码转换&#xff08;如utf8mb4字符集与utf8字符集的等值判断&#xff…

Leetcode101:对称二叉树

原文链接&#xff1a;101. 对称二叉树 - 力扣&#xff08;LeetCode&#xff09; 题目 给你一个二叉树的根节点 root &#xff0c; 检查它是否轴对称。 示例 1&#xff1a; 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true 示例 2&#xff1a; 输入&#xff1a;r…

日志异常检测准确率低?一文掌握日志指标序列分类

背景 目前&#xff0c;日志异常检测算法采用基于时间序列的方法检测异常&#xff0c;具体为&#xff1a;日志结构化->日志模式识别->时间序列转换->异常检测。异常检测算法根据日志指标时序数据的周期性检测出历史新增、时段新增、时段突增、时段突降等多种异常。 然…

那么多优秀的自动化测试工具,而你只知道Selenium?

如今&#xff0c;作为一名软件测试工程师&#xff0c;几乎所有人都需要具备自动化测试相关的知识&#xff0c;并且懂得如何去利用工具&#xff0c;来为企业减少时间成本和错误成本。这是为什么呢&#xff1f; 在以前&#xff0c;测试人员一般都只需要扮演终端用户&#xff0c;…