SpringMVC框架

发布于:2022-12-14 ⋅ 阅读:(387) ⋅ 点赞:(0)

目录

一、SpringMVC简介

一、SpringMVC学习目标

二、SpringMVC概述

三、SpringMVC快速入门

四、启动服务器初始化过程

五、Controller加载控制与业务bean加载控制

六、简化Servlet容器开发

二、设置请求映射路径

一、get请求发送参数

 一、解决post请求传递的参数名与后台形参名不一致问题

二、POJO参数:请求参数名与形参对象属性名相同,定义POJO类型形参即可接收参数

 三、嵌套POJO参数:请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数

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

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

 六、总结关于@RequestParam

二、post请求参数

三、发送JSON数据(常用)

一、集合参数

二、POJO参数

 三、POJO集合参数

四、@RequestParam与@RequestBody区别

五、日期类型参数传递

三、响应

一、响应页面(了解)

二、响应文本数据(了解)

三、响应json数据(对象转json)

四、响应json数据(对象集合转json数组)

四、REST风格

一、REST简介

二、入门案例

三、对入门案例进行快速开发优化(RESTful)

四、注解@RequestBody、@RequestParam、@PathVariable区别

五、案例:基于RESTful页面数据交互


一、SpringMVC简介

一、SpringMVC学习目标

1、掌握基于SpringMVC获取请求参数与相应json数据操作;

2、熟练应用基于REST风格的请求路径设置与参数传递;

3、能够根据实际业务建立前后端开发通信协议并进行实现;

4、基于SSM整合技术开发任意业务模块功能。

二、SpringMVC概述

1、SpringMVC技术与Servlet技术功能等同,均属于web层开发技术。相比于Servlet使用简单、开发便捷。

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

 

三、SpringMVC快速入门

步骤①:使用SpringMVC技术需要先导入SpringMVC坐标与Servlet坐标

<dependencies>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.0</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.3.19</version>
    </dependency>
</dependencies>

②:创建SpringMVC控制器类(等同于Servlet功能)

package com.chf.controller;

@Controller
public class UserController{
    //此注解相当于Servlet的@WebServlet("/save"),设置翻墙控制器方法的访问路径。
	@RequestMapping("/save")
    //此注解设置当前控制器方法相应内容为当前返回值,无需解析。
	@ResponseBody
	public String save(){
		System.out.println("user save");
		return "{'info':'SpringMVC'}";//为相应到网页上的内容
	}
}

③:初始化SpringMVC环境(同Spring环境),设定SpringMVC加载对应的bean

package com.chf.config;

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

④:初始化Servlet容器,加载SpringMVC环境,并设置SpringMVC技术处理的请求

package com.chf.config;

//定义一个Servlet容器启动的配置类,在里面加载Spring的配置
public class ServletContainsInitConfig extends AbstractDispatcherServletInitializer {
    //加载SpringMVC容器配置
    @Override
    protected WebApplicationContext createServletApplicationContext() {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(SpringMvcConfig.class);
        return ctx;
    }
    //设置哪些请求归属SpringMVC处理
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};//代表所有请求
    }
    //加载Spring容器配置,可以将上上的方法体复制过来,将SpingMvcConfig改成SpringConfig
    @Override
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }
}

对步骤四进行解释:

1、AbstractDispatcherServletInitializer类是SpringMVC提供的快速初始化Web3.0容器的抽象类;

2、AbstractDispatcherServletInitializer提供三个接口方法供用户实现;

①createServletApplicationContext()方法,创建Servlct容器时,加载SpringMVC对应的bean并放入WebApplicationContext对象范围中,而WebApplicationContext的作用范围为ServlctContext范围,即整个web容器范围。

③getServletMappings()方法,设定SpringMVC对应的请求映射路径,设置为"/"表示拦截所有请求,任意请求都将转入到SpringMVC进行处理。

④createRootApplicationContext()方法,如果创建Serlvet容器时需要加载非SpringMVC对应的bean,使用当前方法进行,使用方式同createServletApplicationContext()方法。

四、启动服务器初始化过程

1、服务器启动,执行ServletContainersInitConfig类,初始化Web容器;

2、执行createServletApplicationContext方法,创建了WebApplicationContext对象;

3、加载SpringMvcConfig;

4、执行@ComponentScan加载对应的bean;

5、加载UserController,每个@RequestMapping的名称对应一个具体的方法;

6、执行 getServletMappings方法,定义所有的请求都通过SpingMVC。

五、Controller加载控制与业务bean加载控制

1、SpringMVC相关bean加载控制:对应的包均在com.chf.controller包内。

2、Spring相关bean加载控制:

①设定扫描范围为精准范围,例如数组方式指定想要扫描的包{"com.chf.service","com.chf.dao"};

②设定扫描范围为com.chf,排除掉controller包内的bean。此时就需要用下图所写的代码(在SpringBoot源码涉及)。excludeFilters:排出扫描路径中加载的bean,需要指定类别(type)与具体(classes)。

package com.chf.config;

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


package com.chf.config;
@Configuation
//@ComponentScan({"com.chf.service","com.chf.dao"})
@ComponentScan(value="con.chf",encludeFilters=@ComponentScan.Filter(
		type=FilterType.ANNOTATION,classes=Controller.class
	)
)
public class SpringConfig{}

六、简化Servlet容器开发

package com.chf.config;

public class ServletContainsInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer{
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringConfig.class};
    }

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

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

二、设置请求映射路径

一、get请求发送参数

我们首先需要了解参数有五种:

①普通参数、②POJO类型参数、③嵌套POJO类型参数、④数组类型参数、⑤集合类型参数

package com.chf.controller;

@Controller
@RequestMapping("/user")
public class UserController{
	@RequestMapping("/save")
	@ResponseBody
	public String save(String username,int age){
		System.out.println("user save");
		return "{'info':'SpringMVC user'}";
	}
}

 一、解决post请求传递的参数名与后台形参名不一致问题

如上例子所示,将代码中的形参名做修改,使用到@RequestParam注解

作用:绑定请求参数与处理器方法形参间的关系

package com.chf.controller;

@Controller
@RequestMapping("/user")
public class UserController{
	@RequestMapping("/save")
	@ResponseBody
	public String save(@RequestParam("username") String name,int age){
		System.out.println("user save");
		return "{'info':'SpringMVC user'}";
	}
}

二、POJO参数:请求参数名与形参对象属性名相同,定义POJO类型形参即可接收参数

package com.chf.service;

@RequestMapping("/domain")
@ResponseBody
public String pojoParam(User user){
    System.out.println("domain参数传递 user ==> "+user);
    return "{'module':'domain param'}";
}

package com.chf.domain;
//domain目录下的实体类
public class User {
    private String name;
    private int age;
    //以下省略toString()方法和setget方法
}

 三、嵌套POJO参数:请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJO属性参数

 

package com.chf.service;

@RequestMapping("/pojoContainPojoParam")
@ResponseBody
public String pojoParam(User user){
    System.out.println("pojo嵌套pojo参数传递 user ==> "+user);
    return "{'module':'pojo contain pojo param'}";
}

package com.chf.domain;
//domain目录下的实体类
public class User {
    private String name;
    private int age;
    private Address address;
    //以下省略toString()方法和setget方法
}
public class Address {
    private String province;
    private String city;
    //以下省略toString()方法和setget方法
}

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

package com.chf.service;

@RequestMapping("/arrayParam")
@ResponseBody
public String arrayParam(String[] likes){
    System.out.println("数组参数传递 likes ==> "+ Arrays.toString(likes));
    return "{'module':'array param'}";
}

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

package com.chf.service;

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

 六、总结关于@RequestParam

①、注解@RequestParam接收的参数是来自requestHeader中,即请求头。

RequestParam可以接受简单类型的属性,也可以接受对象类型。

②、@RequestParam有三个配置参数:

required 表示是否必须,默认为 true,必须。 ​ defaultValue 可设置请求参数的默认值。 ​ value 为接收url的参数名(相当于key值)。 ③、@RequestParam用来处理 Content-Type 为 application/x-www-form-urlencoded 编码的内容,Content-Type默认为该属性。@RequestParam也可用于其它类型的请求,例如:POST、DELETE等请求。

④、可以使前端的参数名和后端控制器的变量名不保持一致

⑤、可以绑定多个参数,如集合或者数组时必须使用。

二、post请求参数

 解决网页post提交后在后台的乱码问题:在Servlet容器中添加过滤器 :

package com.chf.config;

public class ServletContainsInitConfig extends AbstractAnnotationConfigDispatcherServletInitializer{
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class[]{SpringConfig.class};
    }

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

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/"};
    }
    //配置字符编码过滤器
    @Override
    protected Filter[] getServletFilters() {
    	CharacterEncodingFilter filter = new CharacterEncodingFilter();
    	filter.setEncoding("UTF-8");
        return new Filter[]{filter};
    }
}

三、发送JSON数据(常用)

一、集合参数

步骤①在pom.xml中添加以下依赖

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

②在SpringMvcConfig核心配置类中添加注解@EnableWebMvc

注:@EnableWebMvc注解功能强大,该注解整合了多个功能,此处仅使用其中一部分功能,即json数据进行自动类型转换

package com.chf.config;

@Configuration
@ComponentScan("com.chf.controller")
@EnableWebMvc
public class SpringMvcConfig{}

③在postman软件中,先改成body形式紧接着使用raw,在右边的格式改成JSON

 

④后端代码中的形参前面添加@RequestBody注解即可。

总结关于@RequestBody

①、@RequestBody:将请求中请求体所包含的数据传递给请求参数,此注解一个处理器方法只能用一次。

②、注解@RequestBody接收的参数是来自requestBody中,即请求体。一般用于处理非 Content-Type: application/x-www-form-urlencoded编码格式的数据,比如:application/json、application/xml等类型的数据。

③、就application/json类型的数据而言,使用注解@RequestBody可以将body里面所有的json数据传到后端,后端再进行解析。

package com.chf.service;

@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'}";
}

二、POJO参数

package com.chf.service;

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

 三、POJO集合参数

package com.chf.service;

@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'}";
}

四、@RequestParam与@RequestBody区别

1、区别:

①@RequestParam用于接收url地址传参、列表传参【application/x-www-from-urlencoded】

②@RequestBody用于接收json数据【application/json】

2、应用:

①后期开发中,传送json格式数据为主,@RequestBody应用较广

②如果发送非json格式数据,选用@RequestParam接收请求参数

五、日期类型参数传递

接收形参时,根据不同的日期格式设置不同的接收方式。

注解@DateTimeFormat作用:设定日期时间型时间格式

package com.chf.service;

@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'}";
}

三、响应

响应分为:响应页面和响应数据。

响应数据分为:文本数据和json数据。

一、响应页面(了解)

package com.chf.service;

@RequestMapping("/toJumpPage")
public String toJumpPage(){
    System.out.println("跳转页面");
    return "welcome.jsp";//这里编写的即是跳转到的页面名
}

二、响应文本数据(了解)

@ResponseBody:设置当前控制器返回值作为响应体。

但不是Servlet里的response.setContentType("text/html")。

package com.chf.service;

@RequestMapping("/toText")
@ResponseBody
public String toJumpPage(){
    return "response text";
}

三、响应json数据(对象转json)

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

package com.chf.service;

@RequestMapping("/toJsonPOJO")
@ResponseBody
public User toJsonPOJO(){
    System.out.println("返回json对象数据");
    User user = new User();
    user.setName("鸿");
    user.setAge(18);
    return user;
}

四、响应json数据(对象集合转json数组)

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

package com.chf.service;

@RequestMapping("/toJsonList")
@ResponseBody
public List<User> toJsonList(){
    System.out.println("返回json集合数据");
    User user1 = new User();
    user1.setName("鸿");
    user1.setAge(18);
    User user2 = new User();
    user2.setName("a");
    user2.setAge(19);

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

    return userList;
}

四、REST风格

一、REST简介

REST(Representational State Transfer),表现形式状态转换。

        传统风格资源描述形式

        http://localhost/user/getById?id=1

        http://localhost/user/saveUser

        REST风格描述形式

        http://localhost/user/1

        http://localhost/user

优点:①隐藏资源的访问行为,无法通过地址得知对资源是何种操作;②书写简化

二、入门案例

①:设定http请求动作(动词)

package com.chf.service;

@RequestMapping(value = "/users",method = RequestMethod.POST)
@ResponseBody
public String save(){
   System.out.println("user save...");
   return "{'module':'user save'}";
}
@RequestMapping(value = "/users",method = RequestMethod.PUT)
@ResponseBody
public String update(@RequestBody User user){
    System.out.println("user update..."+user);
    return "{'module':'user update'}";
}

②设定请求参数(路径变量)

注解@PathVariable用于形参注解,放在形参定义的前面。

作用:绑定路径参数与处理器方法形参间的关系,要求路径参数名与形参名一一对应。

package com.chf.service;

@RequestMapping(value = "/users/{id}",method = RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable Integer id){
    System.out.println("user delete..." + id);
    return "{'module':'user delete'}";
}

三、对入门案例进行快速开发优化(RESTful)

package com.chf.service;

@RequestMapping("/users")
@RestController
public class UserController{
	@PostMapping        //使用@PostMapping简化Post请求方法对应的映射配置
	public String save(){
  	 System.out.println("user save...");
   	return "{'module':'user save'}";
	}
	@PutMapping         //使用@PutMapping简化Put请求方法对应的映射配置
	public String update(@RequestBody User user){
    	System.out.println("user update..."+user);
    	return "{'module':'user update'}";
	}
    @DeleteMapping("/{id}")     //使用@DeleteMapping简化DELETE请求方法对应的映射配置
	public String delete(@PathVariable Integer id){
   	 	System.out.println("user delete..." + id);
    	return "{'module':'user delete'}";
	}
}

①@RestController注解,用于类注解。

作用:设置当前控制器类为RESTful风格,等同于@Controller与@ResponseBody两个注解组合功能。

②@GetMapping、@PostMapping、@PutMapping、@DeleteMapping,用于方法注解。

作用:设置当前控制器方法请求访问路径与请求动作,每种对应一个请求动作,其中value默认为默认访问路径

四、注解@RequestBody、@RequestParam、@PathVariable区别

区别:

        ①@RequestParam用于接收url地址传参或者表单传参

        ②@RequestBody用于接收json数据

        ③@PathVariable用于接收路径参数,使用{参数名称}描述路径参数

应用:

        ①后期开发中,发送请求参数超过1个时,以json格式为主,@RequestBody应用较广

        ②如果发送非json格式数据,选用@RequestParam接收请求参数

        ③采用RESTful进行开发,但参数数量较少时,例如1个,可以采用@PathVariable接收请求路径变量。

五、案例:基于RESTful页面数据交互

①:制作SpringMVC控制器,并通过PostMan测试接口功能。

package com.chf.service;

@RestController
@RequestMapping("/books")
public class BookController {
    @PostMapping
    public String save(@RequestBody Book book){
        System.out.println("book save ==> "+ book);
        return "{'module':'book save success'}";
    }

    @GetMapping
    public List<Book> getAll(){
        System.out.println("book getAll is running ...");
        List<Book> bookList = new ArrayList<Book>();

        Book book1 = new Book();
        book1.setType("计算机");
        book1.setName("SpringMVC入门教程");
        book1.setDescription("小试牛刀");
        bookList.add(book1);

        Book book2 = new Book();
        book2.setType("计算机");
        book2.setName("SpringMVC实战教程");
        book2.setDescription("一代宗师");
        bookList.add(book2);

        Book book3 = new Book();
        book3.setType("计算机丛书");
        book3.setName("SpringMVC实战教程进阶");
        book3.setDescription("一代宗师呕心创作");
        bookList.add(book3);

        return bookList;
    }
}

②:设置对静态资源的访问放行

package com.chf.config;

@Configuration
public class SpringMvcSupport extends WebMvcConfigurationSupport {
    //设置静态资源访问过滤,当前类需要设置为配置类,并被扫描加载
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        //当访问/pages/????时候,从/pages目录下查找内容
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
        registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
    }
}

本文含有隐藏内容,请 开通VIP 后查看