SpringMVC入门

avatar
作者
筋斗云
阅读量:0

目录

SpringMVC概述

SpringMVC快速入门

第一步:创建Maven工程,并导入相关的依赖

第二步:创建控制器类

第三步:初始化SpringMVC环境

第四步:创建Tomcat的Servlet容器配置类

第五步:导入tomcat插件,并设置war方式打包

第六步:启动

测试

注意:需要在main目录下面新建一个webapp目录 

请求路径优化

 指定请求方法

请求参数处理

六种常规类型

第一种:普通请求参数

第二种:pojo类型请求参数

第三种:数组类型请求参数

第四种:List集合类型

 第五种:map集合类型

日期请求参数传递

文件类型参数传递 

1.先导入依赖

2.编写文件解析器,并交给SringMVC管理(第三方bean)使用注解@Bean

 JSON类型参数传递

第一步:导入解析json对象的依赖

第二步:让SpringMVC开启辅助功能,如日期类型转换,json类型转换

第三步:编写Controller类,并使用注解@RequestBody,一个方法只能使用一次(解析前端传来的json对象)

​编辑 数组类型的pojo类型

处理中文请求乱码问题

 1.GET请求乱码问题

2.解决POST请求乱码

 响应数据

响应一个页面

响应JSON对象,也要使用@Response注解

响应JSON对象数组

RESful风格


SpringMVC概述

MVC(Model View Controller),一种用于创建web应用程序的表现层的模式

        1.Model(模型):数据模型,用于封装数据

        2.View(视图):页面视图,用于展示数据

  •                 jsp
  •                 html

        3.Controller(控制器):处理用户交互的调度器,用于根据用户需求处理程序逻辑

SpringMVC快速入门

第一步:创建Maven工程,并导入相关的依赖

springMVC的依赖

<!--        springMVC的依赖-->         <dependency>             <groupId>org.springframework</groupId>             <artifactId>spring-webmvc</artifactId>             <version>5.2.10.RELEASE</version>         </dependency>

servlet-api

注意:需要指定作用范围

<dependency>             <groupId>javax.servlet</groupId>             <artifactId>javax.servlet-api</artifactId>             <version>3.1.0</version> <!--            需要指定作用范围-->             <scope>provided</scope>         </dependency>

我们可以发现springMVC的依赖包括了spring-context的依赖

第二步:创建控制器类

/* 1.需要交给spring管理 2.定义处理请求的方法 3.设置当前方法的访问路径 4.设置返回数据类型为String  */ @Controller public class UserController {     @RequestMapping("/save")     @ResponseBody     public String save(){         System.out.println("user save");         return "springMVC";     } } 

 创建控制器类也需要四步:

第一步:需要交给spring管理,即添加@Controller注解

第二步:定义处理请求的方法-->public String save()

第三步:设置当前方法的访问路径-->使用注解@RequestMapping("/save")

第四步:设置返回数据类型为String-->使用注解@ResponseBody

第三步:初始化SpringMVC环境

 这是一个设置扫描范围的配置类(主配置类)

@Configuration @ComponentScan("com.hhh") public class SpringMvcConfig { } 

第四步:创建Tomcat的Servlet容器配置类

public class ServletContainerInitConfig extends AbstractDispatcherServletInitializer {     //创建SpringMVC容器(spring容器)     @Override     protected WebApplicationContext createServletApplicationContext() {         //ApplicationContext ctx =new AnnotationConfigApplicationContext();         //加载配置类,创建SpringMVC容器         AnnotationConfigWebApplicationContext ctx =new AnnotationConfigWebApplicationContext();         ctx.register(SpringMvcConfig.class);         return ctx;     }     //设置哪些请求交给springMVC管理     @Override     protected String[] getServletMappings() {         //这里设置了所有请求都交给SpringMVC管理         return new String[]{"/"};      }     //创建Spring容器     @Override     protected WebApplicationContext createRootApplicationContext() {         return null;     } } 

第五步:导入tomcat插件,并设置war方式打包

 <build>         <plugins>             <plugin>                 <groupId>org.apache.tomcat.maven</groupId>                 <artifactId>tomcat7-maven-plugin</artifactId>                 <version>2.1</version>                 <configuration>                     <!-- 指定端口 -->                     <port>8080</port>                     <!-- 请求路径 -->                     <path>/</path> <!--                    &lt;!&ndash;这个名称需要,在maven插件中显示应用名称&ndash;&gt;--> <!--                    <server>tomcat7</server>-->                 </configuration>             </plugin>         </plugins>     </build>
<packaging>war</packaging>

 完整pom.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>com.hhh</groupId>     <artifactId>spring_day6_MVC</artifactId>     <version>1.0-SNAPSHOT</version>     <packaging>war</packaging>      <properties>         <maven.compiler.source>21</maven.compiler.source>         <maven.compiler.target>21</maven.compiler.target>         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>     </properties>     <dependencies>         <dependency>             <groupId>javax.servlet</groupId>             <artifactId>javax.servlet-api</artifactId>             <version>3.1.0</version> <!--            需要指定作用范围-->             <scope>provided</scope>         </dependency> <!--        springMVC的依赖-->         <dependency>             <groupId>org.springframework</groupId>             <artifactId>spring-webmvc</artifactId>             <version>5.2.10.RELEASE</version>         </dependency>     </dependencies>     <build>         <plugins>             <plugin>                 <groupId>org.apache.tomcat.maven</groupId>                 <artifactId>tomcat7-maven-plugin</artifactId>                 <version>2.1</version>                 <configuration>                     <!-- 指定端口 -->                     <port>8080</port>                     <!-- 请求路径 -->                     <path>/</path> <!--                    &lt;!&ndash;这个名称需要,在maven插件中显示应用名称&ndash;&gt;--> <!--                    <server>tomcat7</server>-->                 </configuration>             </plugin>         </plugins>     </build>  </project>

第六步:启动

 点击加号,选择maven,然后再Run里填写tomcat7:run,最后点击apply

结果:

测试

启动成功

注意:需要在main目录下面新建一个webapp目录 

请求路径优化

添加一个新的类

@Controller public class BookController {     @RequestMapping("/save")     @ResponseBody     public String save(){         System.out.println("book save");         return "bookSpringMVC";     } } 

请求路径与之前的一样,会报错

所以这样添加目录

但是这样子每个方法都要添加一级目录,比较麻烦,所以我们可以在这个类上使用注解@RequestMapping注解

@Controller @RequestMapping("/book") public class BookController {     @RequestMapping("/save")     @ResponseBody     public String save(){         System.out.println("book save");         return "bookSpringMVC";     } } 
@Controller @RequestMapping("/user") public class UserController {     @RequestMapping("/save")     @ResponseBody     public String save(){         System.out.println("user save");         return "springMVC";     } } 

测试:

 指定请求方法

现在我们使用的式@RequestMapping注解,这个注解支持GET,POST请求,但是我们要指定请求方法要怎么做呢?

@Controller @RequestMapping("/book") public class BookController {     @RequestMapping(value = "/save",method = RequestMethod.GET)//这样子只能使用GET请求     @ResponseBody     public String save(){         System.out.println("book save");         return "bookSpringMVC";     } } 

请求参数处理

六种常规类型

第一种:普通请求参数

请求参数的key值与方法的形参名一致

后端:

@Controller public class ParamController {     //普通类型参数     @RequestMapping("/commonParam")     @ResponseBody     public String commonParam(@RequestParam("name") String username, Integer age){//请求参数名和变量名一致即可         System.out.println("username="+username);         System.out.println("age="+age);         return "CommonParam";     }  } 

使用postman向后端发送请求

如果前端请求参数名字与后端形参名不一致时,使用@RequestParam注解。

SpringMVC会自动把String类型的age转换成Integer类型

第二种:pojo类型请求参数

pojo类的成员变量名字与前端的key值一致 

User类

public class User {     private String name;     private Integer age;     private Address address;      public String getName() {         return name;     }      public void setName(String name) {         this.name = name;     }      public Integer getAge() {         return age;     }      public void setAge(Integer age) {         this.age = age;     }      public Address getAddress() {         return address;     }      public void setAddress(Address address) {         this.address = address;     }           @Override     public String toString() {         return "User{" +                 "name='" + name + '\'' +                 ", age=" + age +                 ", address=" + address +                 '}';     } }

 Address类型

public class Address {     private String province;     private String city;      public String getProvince() {         return province;     }      public void setProvince(String province) {         this.province = province;     }      public String getCity() {         return city;     }      public void setCity(String city) {         this.city = city;     }      @Override     public String toString() {         return "Address{" +                 "province='" + province + '\'' +                 ", city='" + city + '\'' +                 '}';     } } 

后端:
 

@Controller public class ParamController {        //pojo嵌套类型     @RequestMapping("/pojoContainPojoParam")     @ResponseBody     public String pojoContainPojoParam(User user){         System.out.println(user);         return "pojoContainPojoParam";    } 

前端:

可以发现如果成员变量也是pojo类型,就要使用成员变量名.成员变量名的方法

结果:

原理:SpringMVC会使用构造器实例化出一个pojo类对象,即User对象(new User()),然后使用User类里的setXxx()方法进行赋值,如果没有构造器会报错,没有set方法那么这个成员变量就为空null值

如果使用注解@RequestParam

就会报错:

因为@RequestParam是直接把请求参数与形参进行绑定,并直接赋值,这样一来User类型对象并没有实例化,所以就会报错

第三种:数组类型请求参数

前端使用多个相同名字的key值与形参变量名一致

@Controller public class ParamController {       //数组类型     @RequestMapping("/arrayParam")     @ResponseBody     public String arrayParam(String[]list){         System.out.println(Arrays.toString(list));         return "arrayParam";     }  } 

 前端:

结果:

第四种:List集合类型

@Controller public class ParamController {          //集合类型     @RequestMapping("/listParam")     @ResponseBody     public String listParam(@RequestParam List<String>list){         //因为List不是简单类型,所以springMVC会直接把List看成pojo类型,然后会实例化list,但是List集合没有构造器,就会报错         //所以添加@RequestParam注解,这样一来spring会直接给list赋值,而不是实例化去使用set()方法         System.out.println(list);         return "listParam";     }    } 

 前端:

可以发现我们后端的形参中使用了@RequestParam注解,因为这个注解的作用就是绑定形参变量,直接进行赋值,因为List集合不是简单类型,所以SpringMVC会把List集合看出pojo类型,会先实例化List集合再进行set方法赋值,但是List集合并没有构造器,因此不加@RequestParam注解就会报错:

 第五种:map集合类型

@Controller public class ParamController {     //map集合类型     @RequestMapping("/mapParam")     @ResponseBody     public String mapParam(@RequestParam Map<String,String> map){         //@RequestParam把请求参数与形参绑定,直接赋值         //System.out.println(map);         map.forEach((key,value)-> System.out.println(key+"->"+value));         return "mapParam";     } }

前端:

结果:

日期请求参数传递

@Controller public class DateController {     @RequestMapping("/dateParam")     @ResponseBody     public String dateParam(Date date){         System.out.println(date);         return "dateParam";     } } 

前端:

结果:

可以发现时期使用的是/来间隔,如果使用-来间隔,会报错:

不能把String类型转换成Date类型,所以我们要使用注解@DateTimeFormat的pattern属性来指定日期类型格式

@Controller public class DateController {     @RequestMapping("/dateParam")     @ResponseBody     public String dateParam(Date date,@DateTimeFormat(pattern = "yyyy-MM-dd") Date date1){         System.out.println(date);         System.out.println(date1);         return "dateParam";     } } 

如果要运行成功,还需要再主配置类中添加@EnableWebMvc,让SpringMVC开启辅助功能

@Configuration @ComponentScan("com.hhh") @EnableWebMvc//让SpringMVC开启辅助功能 public class SpringMvcConfig { } 

结果:

文件类型参数传递 

1.先导入依赖

<!--        文件解析的依赖-->         <dependency>             <groupId>commons-fileupload</groupId>             <artifactId>commons-fileupload</artifactId>             <version>1.3.3</version>         </dependency>

2.编写文件解析器,并交给SringMVC管理(第三方bean)使用注解@Bean

@Configuration @ComponentScan("com.hhh") @EnableWebMvc//让SpringMVC开启辅助功能 public class SpringMvcConfig {     //配置文件解析器,并交给SpringMVC管理     @Bean("multipartResolver")//这个解析器类型的Bean id必须是multipartResolver,源码是通过id名来获取bean的     public MultipartResolver multipartResolver(){         CommonsMultipartResolver commonsMultipartResolver=new CommonsMultipartResolver();         commonsMultipartResolver.setMaxUploadSize(1024*1024);//单位是字节(byte)         //设置文件最大为1MB         return  commonsMultipartResolver;     } } 

 注意:这个解析器类型的Bean id必须是multipartResolver,源码是通过id名来获取这个类型的bean

后端

@Controller public class FileController {     @RequestMapping("/fileParam")     @ResponseBody     public String fileParam(MultipartFile file) throws IOException {         if(!file.isEmpty()){             file.transferTo(new File("D://test.txt"));//把文件另存为         }         return "fileParam";     } } 

前端

 请求方法只能选择post,文件类型要选择form-data,其他类型选择的是右边那个长的

结果:
D盘出现该文件,成功

 JSON类型参数传递

第一步:导入解析json对象的依赖

<!--        解析json的依赖-->         <dependency>             <groupId>com.fasterxml.jackson.core</groupId>             <artifactId>jackson-databind</artifactId>             <version>2.9.0</version>         </dependency>

第二步:让SpringMVC开启辅助功能,如日期类型转换,json类型转换

@Configuration @ComponentScan("com.hhh") @EnableWebMvc//让SpringMVC开启辅助功能,如日期类型转换,json类型转换 public class SpringMvcConfig {     //配置文件解析器,并交给SpringMVC管理     @Bean("multipartResolver")//这个解析器类型的Bean id必须是multipartResolver,源码是通过id名来获取bean的     public MultipartResolver multipartResolver(){         CommonsMultipartResolver commonsMultipartResolver=new CommonsMultipartResolver();         commonsMultipartResolver.setMaxUploadSize(1024*1024);//单位是字节(byte)         //设置文件最大为1MB         return  commonsMultipartResolver;     } } 

第三步:编写Controller类,并使用注解@RequestBody,一个方法只能使用一次(解析前端传来的json对象)

@Controller public class JsonController {     @RequestMapping("/pojoParamForJson")     @ResponseBody     public String pojoParamForJson(@RequestBody User user){         System.out.println(user);         return "pojoParamForJson";     } } 

前端

 

结果:

 数组类型的pojo类型

   @RequestMapping("/arrayPojoParam")     @ResponseBody     public String arrayPojoParam(@RequestBody List<User>list){         System.out.println(list);         return "arrayPojoParam";     }

前端

数组使用[]

结果

处理中文请求乱码问题

 1.GET请求乱码问题

   <build>         <plugins>             <plugin>                 <groupId>org.apache.tomcat.maven</groupId>                 <artifactId>tomcat7-maven-plugin</artifactId>                 <version>2.1</version>                 <configuration>                     <!-- 指定端口 -->                     <port>8080</port>                     <!-- 请求路径 -->                     <path>/</path> <!--                    &lt;!&ndash;这个名称需要,在maven插件中显示应用名称&ndash;&gt;--> <!--                    <server>tomcat7</server>-->                     <uriEncoding>utf-8</uriEncoding>                 </configuration>             </plugin>         </plugins>     </build> 

添加<uriEncoding>utf-8</uriEncoding>

2.解决POST请求乱码

为web容器添加过滤器并指定字符集

public class ServletContainerInitConfig extends AbstractDispatcherServletInitializer {     //创建SpringMVC容器(spring容器)     @Override     protected WebApplicationContext createServletApplicationContext() {         //ApplicationContext ctx =new AnnotationConfigApplicationContext();         //加载配置类,创建SpringMVC容器         AnnotationConfigWebApplicationContext ctx =new AnnotationConfigWebApplicationContext();         ctx.register(SpringMvcConfig.class);         return ctx;     }     //设置哪些请求交给springMVC管理     @Override     protected String[] getServletMappings() {         //这里设置了所有请求给SpringMVC管理         return new String[]{"/"};     }     //创建Spring容器     @Override     protected WebApplicationContext createRootApplicationContext() {         return null;     }      //设置参数编码为utf-8,解决post请求乱码     @Override     protected Filter[] getServletFilters() {         CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();         characterEncodingFilter.setEncoding("UTF-8");         return new Filter[]{characterEncodingFilter};     } } 

 添加
    //设置参数编码为utf-8,解决post请求乱码
    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("UTF-8");
        return new Filter[]{characterEncodingFilter};
    }

 响应数据

响应一个页面

创建一个jsp文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head>     <title>Title</title> </head> <body> <div>hello</div> </body> </html> 
@Controller public class ResponseController {     //不加@ResponseBody就会去找页面名为page.jsp的页面     @RequestMapping("/toPage")     public String toPage(){         System.out.println("toPage");         return "page.jsp";     } }

如果加了@ResponseBody

 @RequestMapping("/toText")     @ResponseBody     public String toText(){         System.out.println("toText");         return "page.jsp";     }

返回的就是字符串本身

 所以@Response注解(使用在方法上)的作用就是设置当前控制器的返回值作为响应体。

不加这个注解就会去找对应名字的页面,并返回给前端 

响应JSON对象,也要使用@Response注解

返回类型是对象

@Controller public class ResponseController {      @RequestMapping("/toJson")     @ResponseBody     public User toJson(){         User user = new User();         user.setName("hhh");         user.setAge(19);         Address address = new Address();         address.setProvince("河北");         address.setCity("石家庄");         user.setAddress(address);         return user;     }   } 

 

响应JSON对象数组

@Controller public class ResponseController {      @RequestMapping("/toJsonArray")     @ResponseBody     public List<User> toJsonArray(){         User user1 = new User();         user1.setName("hhh");         user1.setAge(19);         Address address = new Address();         address.setProvince("河北");         address.setCity("石家庄");         user1.setAddress(address);          User user2 = new User();         user2.setName("aaa");         user2.setAge(19);         Address address2 = new Address();         address2.setProvince("河北");         address2.setCity("石家庄");         user2.setAddress(address2);         List<User>list=new ArrayList<>();         Collections.addAll(list,user1,user2);         return list;      }  } 

 

注意:跟解析请求JSON对象一样,也要导入json解析所需要的依赖,也需要使用注解@EnableWebMvc//让SpringMVC开启辅助功能,如日期类型转换,json类型转换

RESful风格

@Controller public class UserController {     //新增,保存操作     @RequestMapping(value = "/users",method = RequestMethod.POST)     @ResponseBody    public String save(){        return "save";    }    //修改,更新    @RequestMapping(value = "/users",method = RequestMethod.PUT)    @ResponseBody    public String update(){         return "update";    }    //查询全部     @RequestMapping(value = "/users",method = RequestMethod.GET)     @ResponseBody     public String getAll(){         return "getAll";     }     //查询某一个     @RequestMapping(value = "/users/{id}",method = RequestMethod.GET)     @ResponseBody     public String getById(@PathVariable("id") Integer id){//通过请求路径获取值,而不是通过请求参数         System.out.println("id="+id);         return "getById";     }     //删除某一个     @RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)     @ResponseBody     public String delete(@PathVariable("id") Integer id){         System.out.println("id="+id);         return "delete";     } } 

我们可以发现每个@RequestMapping都要写/users,比较麻烦,我们可以直接在类上使用注解 @RequestMapping

每个方法都要写@Response比较麻烦,我们可以直接在类上使用注解 @ResponseBody

@Controller @RequestMapping("/users") @ResponseBody public class UserController {     //新增,保存操作     @RequestMapping(method = RequestMethod.POST)    public String save(){        return "save";    }    //修改,更新    @RequestMapping(method = RequestMethod.PUT)    public String update(){         return "update";    }    //查询全部     @RequestMapping(method = RequestMethod.GET)     public String getAll(){         return "getAll";     }     //查询某一个     @RequestMapping(value = "/{id}",method = RequestMethod.GET)     public String getById(@PathVariable("id") Integer id){//通过请求路径获取值,而不是通过请求参数         System.out.println("id="+id);         return "getById";     }     //删除某一个     @RequestMapping(value = "/{id}",method = RequestMethod.DELETE)     public String delete(@PathVariable("id") Integer id){         System.out.println("id="+id);         return "delete";     } } 

然后我们还发现每个@RequsetMapping都要写一个method属性来指定请求方法,比较麻烦,所以,Post请求就使用@PostMapping,以此类推

@ResponseBody和@Controller这两个注解放在一起可以使用@RestController注解来替代

 //@Controller //@ResponseBody @RestController @RequestMapping("/users") public class UserController {     //新增,保存操作     //@RequestMapping(method = RequestMethod.POST)     @PostMapping    public String save(){        return "save";    }    //修改,更新    //@RequestMapping(method = RequestMethod.PUT)     @PutMapping    public String update(){         return "update";    }    //查询全部    // @RequestMapping(method = RequestMethod.GET)     @GetMapping     public String getAll(){         return "getAll";     }     //查询某一个     //@RequestMapping(value = "/{id}",method = RequestMethod.GET)     @GetMapping("/{id}")     public String getById(@PathVariable("id") Integer id){//通过请求路径获取值,而不是通过请求参数         System.out.println("id="+id);         return "getById";     }     //删除某一个     //@RequestMapping(value = "/{id}",method = RequestMethod.DELETE)     @DeleteMapping("/{id}")     public String delete(@PathVariable("id") Integer id){         System.out.println("id="+id);         return "delete";     } }

@Configuration public class SpringWebSupport extends WebMvcConfigurationSupport {     //设置静态资源不走SpringMvc控制器     @Override     protected void addResourceHandlers(ResourceHandlerRegistry registry) {         registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");         registry.addResourceHandler("/css/**").addResourceLocations("/css/");     } } 

 

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!