SpringMVC学习笔记

1、概述

  1. 基于java实现的实现mvc模型的轻量级web框架
  2. SpringMVC是一种表现层的框架技术,用于web层的功能开发,是对Servlet进行的封装
  3. 主要的作用是接收请求和数据,响应结果,所以如何处理请求和响应是SpringMVC的重点

​ 之前的开发将后端服务器Servlet拆分成三层,分别是webservicedao;web层主要由servlet来处理,负责页面请求和数据的收集以及响应结果给前端;service层主要负责业务逻辑的处理;dao层主要负责数据的增删改查操作;servlet处理请求和数据的时候,存在的问题是一个servlet只能处理一个请求

​ 之后针对web层进行了优化,采用MVC设计模式,将其设计为controllerviewModel;controller负责请求和数据的接收,接收后将其转发给service进行业务处理;service根据需要会调用dao对数据进行增删改查;dao把数据处理完后将结果交给service,service再交给controller;controller根据需求组装成Model和View,Model和View组合起来生成页面转发给前端浏览器(jsp模式)

​ 随着互联网的发展,上面的模式因为是同步调用,性能慢慢的跟不上需求,异步调用慢慢的走到了前台,后端不需要返回view视图;前端如果通过异步调用的方式进行交互,后台就需要将返回的数据转换成json格式进行返回

  web                          controller
                            view       Model
service		   -->		        service
       
  dao							  dao                            
HTML                              contorller
CSS      <---json--<--model---     service
VUE	       -----异步请求---->	      dao
ElementUI

2、依赖说明

2.1 Spring开发MVC:servlet+spring-webmvc+tomcat7

servlet

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

spring-webmvc

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

tomcat7

<!--tomcat7-->
<plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.1</version>
    <configuration>
        <port>80</port>
        <path>/</path>
    </configuration>
</plugin>
2.2 SpringBoot开发MVC
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.0</version>
    </parent>
    
    <groupId>com.itheima</groupId>
    <artifactId>springboot_01_quickstart</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <java.version>8</java.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

3、配置说明

3.1 Spring开发MVC

web3.0 的配置类

public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    protected Class<?>[] getRootConfigClasses() {
        return new Class[0];
    }

    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMvcConfig.class};
    }

    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    //乱码处理
    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("UTF-8");
        return new Filter[]{filter};
    }
}

servlet的配置类

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() {
      return null;
    }
}

SpringMVC的配置类

@Configuration
@ComponentScan("com.itheima.controller")
//开启json数据类型自动转换
@EnableWebMvc
public class SpringMvcConfig {
}
3.2 SpringBoot开发MVC

引入对应起步依赖即可

3.3 中文乱码问题
  • GET请求中文乱码

如果我们传递的参数中有中文:http://localhost/commonParam?name=张三&age=18;接收到的参数会出现中文乱码问题。

Tomcat8.5以后的版本已经处理了中文乱码的问题,但是IDEA中的Tomcat插件目前只到Tomcat7,所以需要修改pom.xml来解决GET请求中文乱码问题

<plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.1</version>
    <configuration>
        <port>80</port><!--tomcat端口号-->
        <path>/</path> <!--虚拟目录-->
        <uriEncoding>UTF-8</uriEncoding><!--访问路径编解码字符集-->
    </configuration>
</plugin>
  • POST请求中文乱码

接收参数控制台打印,会发现有中文乱码问题。

通过配置过滤器解决:spring-web包/CharacterEncodingFilter

public class ServletContainersInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
    protected Class<?>[] getRootConfigClasses() {
        return new Class[0];
    }

    protected Class<?>[] getServletConfigClasses() {
        return new Class[]{SpringMvcConfig.class};
    }

    protected String[] getServletMappings() {
        return new String[]{"/"};
    }

    //乱码处理
    @Override
    protected Filter[] getServletFilters() {
        CharacterEncodingFilter filter = new CharacterEncodingFilter();
        filter.setEncoding("UTF-8");
        return new Filter[]{filter};
    }
}

4、注解说明

@ComponentScan
  1. 类定义上方,设置spring配置类扫描路径,用于加载使用注解格式定义的bean
  2. excludeFilters=排除扫描路径中加载的bean,需要指定类别(type)和具体项(classes);includeFilters=加载指定的bean,需要指定类别(type)和具体项(classes)
@EnableWebMvc
  1. SpringMVC配置类注解,开启SpringMVC多项辅助功能
@Controller
  1. SpringMVC控制器类定义上方,设定SpringMVC的核心控制器bean
@RequestMapping
  1. SpringMVC控制器类或方法定义上方,设置当前控制器方法请求访问路径
  2. value(默认),请求访问路径
@DateTimeFormat
  1. SpringMVC控制器方法形参前面,设置事件类型参数的格式
  2. pattern:指定日期时间格式字符串;"yyyy-MM-dd","yyyy/MM/dd HH:mm:ss"
  • 原理
@FunctionalInterface
public interface Converter<S,T>{
    @Nullable
    T convert(S source);
}

有很多实现类做转换StringToInteger,StringToData

@EnableWebMvc可以按照类型匹配对应的类型转换器

@ResponseBody
  1. 写在方法或类上;写在类上,该类的所有方法都有该注解功能
  2. 设置当前控制器返回值作为响应体
  3. 相关属性:
    1. pattern:指定日期时间格式字符串
  4. 方法的返回值为字符串,会将其作为文本内容直接响应给前端;方法的返回值为对象,会将对象转换成JSON响应给前端
  5. 内部通过Converter接口的实现类完成类型转换,Converter接口可以实现实体类POJO转json、集合转json

还可以写在SpringMVC控制器方法形参定义前面,将请求中请求体所包含的数据传递给请求参数,此注解一个处理器方法只能使用一次

  • 原理

HttpMessageconverter接口

专用转换http的消息

public interface HttpMessageconverter<T>{
    boolean canRead(class<?>clazz,@Nullable MediaType mediaType);
    boolean canWrite(class<?>clazz,@Nullable MediaType mediaType);
    List<MediaType>getSupportedMediaTypes();
    T read(class<?extends T> clazz,HttpInputMessage inputMessage)
        throws IOException,HttpMessageNotReadableException;
    void write(T t, @Nullable MediaType contentType, HttpoutputMessage outputMessage)
        throws IOException,HttpMessageNotWritableException;
}
@RequestBody
  1. SpringMVC控制器方法形参定义前面,将请求中请求体所包含的数据传递给请求参数,此注解一个处理器方法只能使用一次
@RequestParam
  1. SpringMVC控制器方法形参定义前面。绑定请求参数与处理器方法形参间的关系
  2. required:是否为必传参数;defaultValue:参数默认值,不指定defaultValue属性,可以接受可选的请求参数。如果请求中没有提供该参数,方法参数将为null

关于接收参数,我们学过三个注解@RequestBody@RequestParam@PathVariable,这三个注解之间的区别和应用分别是什么?

  • 区别
    • @RequestParam用于接收url地址传参或表单传参【application/x-www-form-urlencoded】
    • @RequestBody用于接收json数据【application/json】
    • @PathVariable用于接收路径参数,使用{参数名称}描述路径参数
  • 应用
    • 后期开发中,发送请求参数超过1个时,以json格式为主,@RequestBody应用较广
    • 如果发送非json格式数据,选用@RequestParam接收请求参数
    • 采用RESTful进行开发,当参数数量较少时,例如1个,可以采用@PathVariable接收请求路径变量,通常用于传递id值

5、请求传递参数

5.1 普通参数

普通的参数,相同名称的能自动映射,通过@RequestParam映射

单个参数:localhost/commonParam?param=xxx

@Controller
@ResponseBody
public Class UserController {
        @RequestMapping(value = "/commonParam" , method = RequestMethod.GET)
    public String getCommonParam(String param) {
        System.out.println("普通参数传递 param ==> "+param);
        return "{'module':'commonParam'}";
    }  
}

多个参数:localhost/commonParam?param=xxx&param2=xxx

@Controller
@ResponseBody
public Class UserController {
    @RequestMapping("/commonParam")
    public String getCommonParam(String param,String param2) {
        System.out.println("普通参数传递 param ==> "+param);
        System.out.println("普通参数传递 param2 ==> "+param2);
        return "{'module':'commonParam'}";
    }
}

参数不一致:localhost/commonParamDifferentName?name=张三&age=18

@RequestMapping("/commonParamDifferentName")
@ResponseBody
public String commonParamDifferentName(@RequestParam("name") String userName , int age){
    System.out.println("普通参数传递 userName ==> "+userName);
    System.out.println("普通参数传递 age ==> "+age);
    return "{'module':'common param different name'}";
}
5.2 实体类参数

简单数据类型一般处理的是参数个数比较少的请求,如果参数比较多,可以使用实体类封装数据

请求参数名与形参对象属性名相同,定义实体类形参即可接收参数

请求参数key的名称要和实体类中属性的名称一致,否则无法封装。

localhost/commonParamDifferentName?name=张三&age=18

请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数:localhost/commonParamDifferentName?name=张三&age=18&address.province=beijing

@RequestMapping("/pojoParam")
@ResponseBody
public String pojoParam(User user){
    return "{'module':'pojo param'}";
}
5.3 数组类型参数

请求参数名与形参对象属性名相同且请求参数为多个,定义数组类型即可接收参数

同名请求参数可以直接映射到对应名称的形参数组对象中

localhost/param?likes=game&likes=music

@RequestMapping("/arrayParam")
@ResponseBody
public String arrayParam(String[] likes){
    System.out.println(Arrays.toString(likes));
    return "{'module':'array param'}";
}
5.4 集合类型参数

同名请求参数可以使用@RequestParam注解映射到对应名称的集合对象中作为数据

SpringMVC将List看做是一个POJO对象来处理,将其创建一个对象并准备把前端的数据封装到对象中,但是List是一个接口无法创建对象,使用@RequestParam注解

集合保存普通参数:请求参数名与形参集合对象名相同且请求参数为多个,@RequestParam绑定参数关系

对于简单数据类型使用数组会比集合更简单些。

localhost/param?likes=game&likes=music

@RequestMapping("/listParam")
@ResponseBody
public String listParam(@RequestParam List<String> likes){
    System.out.println(likes);
    return "{'module':'list param'}";
}
5.5 日期类型参数

localhost/dataParam?date=2088/08/08&date1=2088-08-08&date2=2088/08/08 8:08:08

@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'}";
}
5.6 接收JSON数据类型【重点】

导入jackson依赖;开启SpringMVC注解驱动,在配置类上添加@EnableWebMvc注解,开启json数据类型自动转换

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.0</version>
</dependency>
@Configuration
@ComponentScan("com.itheima.controller")
//开启json数据类型自动转换
@EnableWebMvc
public class SpringMvcConfig {
}

JSON集合:["value1","value2","value3",...]

使用@RequestBody注解将外部传递的json数组数据映射到形参的集合对象中作为数据

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

JSON对象数据:

{
	"name":"itcast",
	"age":15,
    "address":{
        "province":"beijing",
        "city":"beijing"
    }
}
@RequestMapping("/pojoParamForJson")
@ResponseBody
public String pojoParamForJson(@RequestBody User user){
    System.out.println(user);
    return "{'module':'pojo for json param'}";
}

JSON对象数组:[{key1:value1,...},{key2:value2,...}]

[
    {"name":"itcast","age":15},
    {"name":"itheima","age":12}
]
@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'}";
}

6、响应数据/页面

用户查询,新增,修改,删除的请求等,SpringMVC接收到请求或数据后,经过一定的处理,响应给前端,现在主流的是异步调用,所以主要是响应json数据;

也可以响应页面或文本数据

6.1 响应JSON数据

设置返回值为实体类对象,可以实现返回该对象的json数据

@EnableWebMvc,jackson依赖

@ResponseBody

@Controller
public class UserController {
    @RequestMapping("/toJsonPOJO")
    @ResponseBody
    public User toJsonPOJO(){
        User user = new User();
        user.setName("lm");
        user.setAge(18);
        return user;
    }
}
@Controller
public class UserController {
    @RequestMapping("/toJsonList")
    @ResponseBody
    public List<User> toJsonList(){
        User user1 = new User();
        user1.setName("lm");
        user1.setAge(20);
        
        User user2 = new User();
        user2.setName("lw");
        user2.setAge(18);

        List<User> userList = new ArrayList<User>();
        userList.add(user1);
        userList.add(user2);

        return userList;
    }
}
6.2 响应页面[了解]
  1. 在Spring MVC中,返回字符串表示要转发或重定向到名为返回字符串的视图。Spring MVC 将会尝试解析这个字符串并找到对应的视图实现,然后渲染为最终的响应页面。

JSP(Java Server Pages)是一种用于创建动态网页的技术。.jsp 文件是一种文本文件,其中包含HTML以及Java代码片段(或表达式),它们在服务器端被解析和执行,然后生成HTML响应发送给客户端浏览器。所以,JSP 文件实际上是服务器端代码,但最终在客户端浏览器中显示为HTML。

返回名为 page.jsp 的视图:当在Spring MVC中返回字符串 "page.jsp" 时,Spring MVC 将查找名为 page.jsp 的JSP文件,并将其解析为HTML以响应客户端的请求。

方法上不能加@ResponseBody,否则会直接将page.jsp当字符串返回前端;方法需要返回String

@Controller
public class UserController {
    @RequestMapping("/toJumpPage")
    public String toJumpPage(){
        return "page.jsp";
    }
}   
6.3 返回文本数据[了解]
  1. 如果省略@ResponseBody,会把text当成视图名称去查找,如果没有会报404错误
@Controller
public class UserController {
   	@RequestMapping("/toText")
    @ResponseBody
    public String toText(){
        return "text";
    }
}

7、SSM整合【mini_springmvc文件】

项目构建说明

  1. 创建meven工程,导入相关依赖
  2. 配置:
    1. Spring:SpringConfig
    2. Mybatis:MybatisConfig、jdbcConfig、jdbc.properties
    3. SpringMVC:ServletConfig、SpringMvcConfig
  3. 功能模块:
    1. dao(接口+自动代理)
    2. service(接口+实现类)JUnit测试
    3. controller,PostMan测试
posted @ 2024-04-03 23:34  燕子去了  阅读(9)  评论(0编辑  收藏  举报

Powered by .NET 8.0 on Kubernetes

我会翻山越岭,到每一个我想去的地方

...