SpringMVC——处理器方法参数的处理

目录

  • 一、处理器方法参数的处理
    • 1、Servlet API 参数
    • 2、简单类型参数
    • 3、POST请求时中文乱码问题
    • 4、RESTful风格传参
    • 5、数组和List类型的参数(一个参数多个值的情况)
    • 6、JavaBean类型的参数
    • 7、ModelAttribute注解
    • 8、请求头信息、Coolie等
    • 9、数据绑定流程
    • 10、多对象封装传递参数
    • 11、JSON数据处理
    • 12、日期类型处理

在这里插入图片描述

一、处理器方法参数的处理

跳转到目录
如何在Controller中获取(前端传过来的数据)请求中的信息呢?

1、Servlet API 参数

跳转到目录

@Controller
@RequestMapping("/request")
public class HandleRequestController {
    // 也可以通过DI注入的方式,因为Controller是单例的,多线程不安全(不建议使用)
    @Autowired
    private ServletContext servletContext;

    // 可以通过参数来操作Servlet的api
    @RequestMapping("/test1")
    public void test1(HttpServletRequest request, HttpServletResponse responser, HttpSession session) {
        System.out.println(request.getParameter("username"));
        System.out.println(request);
        System.out.println(responser);
        System.out.println(session);
        System.out.println(this.servletContext);
    }
}

2、简单类型参数

跳转到目录

  • @RequestParam注解
    SpringMVC——处理器方法参数的处理_第1张图片
@Controller
@RequestMapping("/request")
public class HandleRequestController {
 // 获取请求参数,保证请求参数名称和Controller方法的形参(入参)同名;
    // 这样就可以获得请求的参数内容; 名字不同,得不到
    @RequestMapping("/test2")
    public void test2(String username, int age) {
        System.out.println("username:" + username);
        System.out.println("age:" + age);
    }
    
    // 如果请求参数名称和形参名称不同 ==> 使用RequestParam注解
    // 使用@RequestMapping注解后,名字不同,也可以获取,请求参数的内容
    @RequestMapping("/test3")
    public void test3(@RequestParam("name") String username, @RequestParam(value = "age") Integer age) {
        System.out.println("username:" + username);
        System.out.println("age:" + age);
    }
}

测试如下:
同名:
在这里插入图片描述
在这里插入图片描述
不同名:
在这里插入图片描述
在这里插入图片描述

3、POST请求时中文乱码问题

跳转到目录
在web.xml中配置


    <filter>
        <filter-name>CharacterEncodingFilterfilter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
        <init-param>
            <param-name>encodingparam-name>
            <param-value>utf-8param-value>
        init-param>
        
        <init-param>
            <param-name>forceRequestEncodingparam-name>
            <param-value>trueparam-value>
        init-param>
        <init-param>
            <param-name>forceResponseEncodingparam-name>
            <param-value>trueparam-value>
        init-param>
    filter>
    <filter-mapping>
        <filter-name>CharacterEncodingFilterfilter-name>
        <url-pattern>/*url-pattern>
    filter-mapping>

SpringMVC——处理器方法参数的处理_第2张图片

4、RESTful风格传参

跳转到目录

  • @PathVariable注解
    SpringMVC——处理器方法参数的处理_第3张图片
/delete?id=11   以前的方式
/delete/11      RESTfull方式
@PathVariable: 可以将URL中占位符绑定到方法的形参中
	// 请求地址为 http://localhost:8080/request/delete/3
    @RequestMapping("delete/{id}")
    public void test4(@PathVariable("id") Long id){
        System.out.println(id);
    }

测试如下:
在这里插入图片描述
在这里插入图片描述

5、数组和List类型的参数(一个参数多个值的情况)

跳转到目录

    // 接受一个参数有多个值的情况
    // 批量删除; /batchDelete?ids=10&ids=20&ids=30
    // 使用数组: 可以直接接收传递的多个参数
    @RequestMapping("/batchDelete")
    public void batchDelete(Long[] ids){
        System.out.println(Arrays.asList(ids));
    }
    // 使用集合List: 不能直接接受,可以在对象中存在一个集合
    @RequestMapping("/batchDelete2")
    public void batchDelete2(FormBean fb){
        System.out.println(fb.getIds());
    }
    //操作一个参数有多个值的情况,一般直接使用数组接受就可以了,或者使用JavaBean对象来封装数据.

SpringMVC——处理器方法参数的处理_第4张图片

6、JavaBean类型的参数

跳转到目录
SpringMVC——处理器方法参数的处理_第5张图片

    //把数据直接封装到JavaBean对象
    @RequestMapping("/test4")
    public void test4(User u) {
        System.out.println(u);
    }

测试如下:
在这里插入图片描述
在这里插入图片描述
默认会把符合类型参数共享到视图中,共享的key名为参数类型首字母小写; 如果要修改共享数据的key名; 使用ModelAttribute注解

7、ModelAttribute注解

跳转到目录
ModelAttribute注解

  • 给共享的Model数据设置key名,贴在形参上,也可以贴在方法上针对复合类型(非简单类型)参数,缺省情况下就会放到model中(共享),缺省的key就是类型首字母小写
  • 我们也可以在参数上贴@ModelAttribute,设置一个model的key名;
    @RequestMapping("/zy1")
    public String test1(User u){
        System.out.println(u);
        return "welcome";
    }
    @RequestMapping("/zy2")
    public String test2(@ModelAttribute("zyuser") User u){
        System.out.println(u);
        return "welcome";
    }

welcome.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>welcometitle>
head>
<body>

    retult:
        ${user}<br>
        ${zyuser}<br>
body>
html>

测试如下:
SpringMVC——处理器方法参数的处理_第6张图片
SpringMVC——处理器方法参数的处理_第7张图片

8、请求头信息、Coolie等

跳转到目录
SpringMVC——处理器方法参数的处理_第8张图片

// 操作其他的请求信息
@Controller
@RequestMapping("/other")
@SessionAttributes("errorMsg")
public class OtherController {

    // 获取请求头中的User-Agent和Cookie信息
    // 以前的方式
    @RequestMapping("zy1")
    public void test0(HttpServletRequest request){
        String header = request.getHeader("User-Agent");
        String jsessionid = request.getHeader("Cookie");
        System.out.println(header);
        System.out.println(jsessionid);
    }

    // 现在的方式
    @RequestMapping("zy2")
    public void test1(@RequestHeader("User-Agent") String userAgent, @CookieValue("JSESSIONID") String cookieName){
        System.out.println("User-Agent:" + userAgent);
        System.out.println("cookieName" + cookieName);
    }


    // 操作HttpSession;
    // 默认情况下Model数据是放到request中共享的,如果我想在session共享---->SessionAttributes注解
    @RequestMapping("/zy3")
    public String test2(Model model){
        model.addAttribute("errorMsg", "错误信息!");
        //默认肯定不能共享数据的,因为是重定向;之前讲过的那个Flash共享也仅仅只是在Controller之间共享
        return "redirect:/abc.jsp";
    }
}

abc.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Titletitle>
head>
<body>

    result:
            ${requestScope.errorMsg}<br>
            ${sessionScope.errorMsg}<br>
            ${errorMsg}<br>

body>
html>

测试如下:
SpringMVC——处理器方法参数的处理_第9张图片

9、数据绑定流程

跳转到目录
SpringMVC——处理器方法参数的处理_第10张图片
SpringMVC通过反射机制对目标处理方法的签名进行分析,将请求信息绑定到处理方法的形参中,数据绑定的核心组件是DataBinder类

数据绑定流程:

1、框架把ServletRequest对象和请求参数传递给DataBinder ;

2、DataBinder 首先调用Spring Web环境中的ConversionService组件,进行数据类型转换和格式化等操作,将ServletRequest中的信息填充到形参对象中;

3、DataBinder 然后调用Validator组件对已经绑定了请求消息数据的形参对象进行数据合法性校验;

4、DataBinder 最后输出数据绑定结果对象BindingResult.

BindingResult包含了已完成数据绑定的形参对象和校验错误信息对象。
最终SpringMVC框架会把BindingResult中的数据,分别赋给相应的处理方法。

10、多对象封装传递参数

跳转到目录
SpringMVC——处理器方法参数的处理_第11张图片

  • 当需要把表单数据封装到多个不同对象中去的时候,如果各个对象中都有相同的属性如name ,此时请求参数name就不清楚到底该把值封装到哪一个对象中去。 更何况缺省情况下SpringMVC也不支持Struts2中类似于对象名.属性名传参方式。

此时需要我们来对象数据设置绑定规则。

InitBinder注解:自定义数据绑定注册支持,用于将请求参数转换到命令对象属性的对应类型;

由@InitBinder注解标注的方法,可以对WebDataBinder对象进行初始化。而WebDataBinder是DataBinder的子类,用于完成由请求参数到JavaBean的属性绑定。

注意点:
@InitBinder标注的方法不能有返回值,它必须声明为void。
@InitBinder标注的方法的参数通常是WebDataBinder.

input.html


<html>
<head>
    <meta charset="UTF-8">
    <title>Insert title heretitle>
head>
<body>
<form action="/save" method="POST">
    狗狗姓名:<input type="text" name="dog.name"/><br/>
    狗狗年龄:<input type="text" name="dog.age"/><br/>
    猫猫姓名:<input type="text" name="cat.name"/><br/>
    猫猫年龄:<input type="text" name="cat.age"/><br/>
    <input type="submit" value="提交"/>
form>
body>
html>

Java代码

// 处理多个对象的封装
@Controller
public class MultiObjectParamController {

    /*
	 	需要把表单数据封装到多个对象中去,如果各个对象都有相同的属性,此时要出问题.
	 		不知道该把哪一个参数封装到哪一个对象中去.

	 */
    // 参数-->对象,封装规则需要我们来设置

    // 把以dog.开头的参数封装到dog对象中
    @InitBinder("dog") // 自定义数据绑定注册,用于将请求参数转换到对应的对象的属性中去
    public void initBinderDogyType(WebDataBinder binder){
        binder.setFieldDefaultPrefix("dog.");
    }

    @InitBinder("cat")
    public void initBinderCatType(WebDataBinder binder){
        binder.setFieldDefaultPrefix("cat.");
    }

    @RequestMapping("/save")
    public ModelAndView save(Cat cat, Dog dog){
        System.out.println(cat);
        System.out.println(dog);
        return null;
    }
}

测试如下:
SpringMVC——处理器方法参数的处理_第12张图片
SpringMVC——处理器方法参数的处理_第13张图片
在这里插入图片描述

11、JSON数据处理

跳转到目录

Jackson

Jackson 是一个Java开源的JSON工具库,性能很高,可以轻松将Java对象转换成Json对象xml文档,同样也可以将json、xml转换成Java对象

首先导入Jackson的Maven依赖

<dependency>
     <groupId>com.fasterxml.jackson.coregroupId>
     <artifactId>jackson-databindartifactId>
     <version>2.9.10version>
 dependency>
 <dependency>
     <groupId>com.fasterxml.jackson.coregroupId>
     <artifactId>jackson-coreartifactId>
     <version>2.9.10version>
 dependency>
 <dependency>
     <groupId>com.fasterxml.jackson.coregroupId>
     <artifactId>jackson-annotationsartifactId>
     <version>2.9.10version>
 dependency>

SpringMVC——处理器方法参数的处理_第14张图片
Java代码测试

// 处理JSON
@Controller
@RequestMapping("/json")
public class HandleJsonController {

	/*
	 	处理JSON的注解:
	 		ResponseBody: 处理响应,把对象转换为JSON字符串.
	 			贴到方法上:只针对当前方法做JSON处理.
	 			贴到类上   : 会对当前类中所有的方法做JSON处理.

	 		RestController = Controller + ResponseBody

	 		RequestBody: 处理请求,用于读取HTTP请求的内容,把JSON格式的请求数据封装成对象.

	 		一般的请求的数据格式:
	 			application/x-www-form-urlencoded: 传统的key-value格式,处理起来非常方便. 不需要RequestBody都可以,贴上也可以.
	 			application/multipart:文件上传的请求,SpringMVC装设设计模式,.既能处理文件上传,也能处理普通表单数据.
	 			application/json:	参数是JSON格式的,此时必须使用RequestBody.

	 */

	// 把单个对象/Map转换为JSON格式
    @RequestMapping("/test1")
    @ResponseBody
    public User test1() {
        User u = new User();
        u.setUsername("桂朝阳");
        u.setAge(22);
        return u;
    }

    // 把集合转为JSON格式
    @RequestMapping("/test2")
    @ResponseBody
    public List<User> test2() {
        User u = new User();
        u.setUsername("桂阳");
        u.setAge(22);
        return Arrays.asList(u, u, u);
    }

SpringMVC——处理器方法参数的处理_第15张图片

注意 : Jackson包导入后可能没有加载上,后台会报500错误; 注意看这个地方是否有jar包
SpringMVC——处理器方法参数的处理_第16张图片

12、日期类型处理

跳转到目录
方式一

@Controller
@RequestMapping("/date")
public class HandleDateController {
    // 从前台--->后台传递参数: String ---> java.util.Date  // http://localhost:8080/date/test1?d=2010-11-1
    @RequestMapping("/test1")
    public ModelAndView test1(@DateTimeFormat(pattern = "yyyy-MM-dd") Date d){
        System.out.println(d);
        return null;
    }
}

方式二

@Data
public class User {
    private Long id;
    private String username;
    private Integer age;

    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date hiredate;
}

@Controller
@RequestMapping("/date")
public class HandleDateController {
    // http://localhost:8080/date/test1?id=2&username=zy&age=23&hiredate=2020-2-1
    @RequestMapping("/test2")
    public ModelAndView test2(User user){
        System.out.println(user);
        return null;
    }
}

方式三
@ControllerAdvice注解

@Data
public class User {
    private Long id;
    private String username;
    private Integer age;
    private Date hiredate;
}

@ControllerAdvice
public class DateFormatAdvice {
	//如果不想每次都在Date类型上@DateTimeFormat
	@InitBinder
	public void initBinderDateType(WebDataBinder binder) {
		SimpleDateFormat sdf = new SimpleDateFormat();
		sdf.applyPattern("yyyy-MM-dd");
		binder.registerCustomEditor(java.util.Date.class, new CustomDateEditor(sdf, true));
	}
}

测试如下:
在这里插入图片描述
在这里插入图片描述

SpringMVC——处理器方法参数的处理_第17张图片
SpringMVC——处理器方法参数的处理_第18张图片

// 处理JSON
@Controller
@RequestMapping("/json")
public class HandleJsonController {

    @RequestMapping("/test3")
    @ResponseBody
    public User test3(){
        User user = new User();
        user.setUsername("will");
        user.setAge(82);
        user.setHiredate(new Date());
        return user;
    }
}

测试如下:
在这里插入图片描述

你可能感兴趣的:(SpringMVC)