2处理器方法的参数
处理器方法可以包含以下四类参数,这些参数会在系统调用时由系统自动赋值,即程序
员可在方法内直接使用。
➢ HttpServletRequest
➢ HttpServletResponse
➢ HttpSession
➢ 请求中所携带的请求参数
1. 逐个参数接收
只要保证请求参数名与该请求处理方法的参数名相同即可。
项目:receiveParameters-property。在 requestMapping-method 基础上修改。
-
Step1:修改 index 页面 -- 这个例子用的是第一个form表单
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <p>提交参数给Controller</p> <form action="receiveproperty.do" method="post"> 姓名:<input type="text" name="name"> <br/> 年龄:<input type="text" name="age"> <br/> <input type="submit" value="提交参数"> </form> <br/> <p>请求参数名和处理器方法的形参名不一样</p> <form action="receiveparam.do" method="post"> 姓名:<input type="text" name="rname"> <br/> 年龄:<input type="text" name="rage"> <br/> <input type="submit" value="提交参数"> </form> <br/> <p>使用java对象接收请求参数</p> <form action="receiveobject.do" method="post"> 姓名:<input type="text" name="name"> <br/> 年龄:<input type="text" name="age"> <br/> <input type="submit" value="提交参数"> </form> </body> </html>
-
Step2:修改处理器类 MyController
package com.bjpowernode.controller; import com.bjpowernode.vo.Student; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.xml.ws.RequestWrapper; /** * @RequestMapping: * value : 所有请求地址的公共部分,叫做模块名称 * 位置: 放在类的上面 */ @Controller public class MyController { /** * 逐个接收请求参数: * 要求: 处理器(控制器)方法的形参名和请求中参数名必须一致。 * 同名的请求参数赋值给同名的形参 * 框架接收请求参数 * 1. 使用request对象接收请求参数 * String strName = request.getParameter("name"); * String strAge = request.getParameter("age"); * 2. springmvc框架通过 DispatcherServlet 调用 MyController的doSome()方法 * 调用方法时,按名称对应,把接收的参数赋值给形参 * doSome(strName,Integer.valueOf(strAge)) * 框架会提供类型转换的功能,能把String转为 int ,long , float, double等类型。 * * 400状态码是客户端错误, 表示提交请求参数过程中,发生了问题。 */ @RequestMapping(value = "/receiveproperty.do") public ModelAndView doSome(String name, Integer age){ System.out.println("doSome, name="+name+" age="+age); //可以在方法中直接使用 name , age //处理some.do请求了。 相当于service调用处理完成了。 ModelAndView mv = new ModelAndView(); mv.addObject("myname",name); mv.addObject("myage",Integer.valueOf(age)); //show是视图文件的逻辑名称(文件名称) mv.setViewName("show"); return mv; } // @RequestMapping(value = "/receiveproperty.do") // public ModelAndView doSome(String name, int age){ // System.out.println("doSome, name="+name+" age="+age); // //可以在方法中直接使用 name , age // //处理some.do请求了。 相当于service调用处理完成了。 // ModelAndView mv = new ModelAndView(); // mv.addObject("myname",name); // mv.addObject("myage",age); // //show是视图文件的逻辑名称(文件名称) // mv.setViewName("show"); // return mv; // } /** * 请求中参数名和处理器方法的形参名不一样 * @RequestParam: 逐个接收请求参数中, 解决请求中参数名形参名不一样的问题 * 属性: 1. value 请求中的参数名称 * 2. required 是一个boolean,默认是true * true:表示请求中必须包含此参数。 * 位置: 在处理器方法的形参定义的前面 */ @RequestMapping(value = "/receiveparam.do") public ModelAndView receiveParam(@RequestParam(value = "rname",required = false) String name, @RequestParam(value = "rage",required = false) Integer age){ System.out.println("doSome, name="+name+" age="+age); //可以在方法中直接使用 name , age //处理some.do请求了。 相当于service调用处理完成了。 ModelAndView mv = new ModelAndView(); mv.addObject("myname",name); mv.addObject("myage",age); //show是视图文件的逻辑名称(文件名称) mv.setViewName("show"); return mv; } /** * 处理器方法形参是java对象, 这个对象的属性名和请求中参数名一样的 * 框架会创建形参的java对象, 给属性赋值。 请求中的参数是name,框架会调用setName() * @return */ @RequestMapping(value = "/receiveobject.do") public ModelAndView receiveParam( Student myStudent){ System.out.println("receiveParam, name="+myStudent.getName()+" age="+myStudent.getAge()); //可以在方法中直接使用 name , age //处理some.do请求了。 相当于service调用处理完成了。 ModelAndView mv = new ModelAndView(); mv.addObject("myname",myStudent.getName()); mv.addObject("myage",myStudent.getAge()); mv.addObject("mystudent",myStudent); //show是视图文件的逻辑名称(文件名称) mv.setViewName("show"); return mv; } }
-
Step3:添加 show 页面
在/WEB-INF/jsp 下添加 show.jsp 页面。
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h3>/WEB-INF/view/show.jsp从request作用域获取数据</h3><br/> <h3>myname数据:${myname}</h3><br/> <h3>myage数据:${myage}</h3> <h3>student数据:${mystudent}</h3> </body> </html>
-
测试如下:
2.请求参数中文乱码问题
对于前面所接收的请求参数,若含有中文,则会出现中文乱码问题。Spring 对于请求参Java 框架 SpringMVC5数中的中文乱码问题,给出了专门的字符集过滤器:spring-web-5.2.5.RELEASE.jar 的org.springframework.web.filter 包下的 CharacterEncodingFilter 类。
-
( 1 ) 解决方案
在 web.xml 中注册字符集过滤器,即可解决 Spring 的请求参数的中文乱码问题。不过,最好将该过滤器注册在其它过滤器之前。因为过滤器的执行是按照其注册顺序进行的。
直接在项目 receiveParameters-property 上进行修改。
<!--注册声明过滤器,解决post请求乱码的问题--> <filter> <filter-name>characterEncodingFilter</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> <!--强制请求对象(HttpServletRequest)使用encoding编码的值--> <init-param> <param-name>forceRequestEncoding</param-name> <param-value>true</param-value> </init-param> <!--强制应答对象(HttpServletResponse)使用encoding编码的值--> <init-param> <param-name>forceResponseEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <!-- /*:表示强制所有的请求先通过过滤器处理。 --> <url-pattern>/*</url-pattern> </filter-mapping>
-
( 2 ) 源码分析
字符集设置核心方法:
-
测试:
3. 校正请求参数名 @RequestParam
所谓校正请求参数名,是指若请求 URL 所携带的参数名称与处理方法中指定的参数名不相同时,则需在处理方法参数前,添加一个注解@RequestParam(“请求参数名”),指定请求 URL 所携带参数的名称。该注解是对处理器方法参数进行修饰的。value 属性指定请求参数的名称。
-
Step1:修改处理器类 MyController
/** * 请求中参数名和处理器方法的形参名不一样 * @RequestParam: 逐个接收请求参数中, 解决请求中参数名形参名不一样的问题 * 属性: 1. value 请求中的参数名称 * 2. required 是一个boolean,默认是true * true:表示请求中必须包含此参数。 * 位置: 在处理器方法的形参定义的前面 */ @RequestMapping(value = "/receiveparam.do") public ModelAndView receiveParam(@RequestParam(value = "rname",required = false) String name, @RequestParam(value = "rage",required = false) Integer age){ System.out.println("doSome, name="+name+" age="+age); //可以在方法中直接使用 name , age //处理some.do请求了。 相当于service调用处理完成了。 ModelAndView mv = new ModelAndView(); mv.addObject("myname",name); mv.addObject("myage",age); //show是视图文件的逻辑名称(文件名称) mv.setViewName("show"); return mv; }
-
Step2:修改 index 页面
<form action="receiveparam.do" method="post"> 姓名:<input type="text" name="rname"> <br/> 年龄:<input type="text" name="rage"> <br/> <input type="submit" value="提交参数"> </form>
required 属性:
-
测试:
4.对象参数接收
将处理器方法的参数定义为一个对象,只要保证请求参数名与这个对象的属性同名即可。
项目:receiveParameters-object。在 receiveParameters-property 基础上修改。
-
Step1:定义类 Student
package com.bjpowernode.vo; //保存请求参数值的一个普通类 public class Student { // 属性名和请求中参数名一样 private String name; private Integer age; public Student() { System.out.println("===Student的无参数构造方法==="); } public String getName() { return name; } public void setName(String name) { System.out.println("setName"+name); this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { System.out.println("setAge"+age); this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
-
Step2:修改处理器类 MyController
/** * 处理器方法形参是java对象, 这个对象的属性名和请求中参数名一样的 * 框架会创建形参的java对象, 给属性赋值。 请求中的参数是name,框架会调用setName() * @return */ @RequestMapping(value = "/receiveobject.do") public ModelAndView receiveParam( Student myStudent){ System.out.println("receiveParam, name="+myStudent.getName()+" age="+myStudent.getAge()); //可以在方法中直接使用 name , age //处理some.do请求了。 相当于service调用处理完成了。 ModelAndView mv = new ModelAndView(); mv.addObject("myname",myStudent.getName()); mv.addObject("myage",myStudent.getAge()); mv.addObject("mystudent",myStudent); //show是视图文件的逻辑名称(文件名称) mv.setViewName("show"); return mv; }
-
Step3:修改 show 页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <h3>/WEB-INF/view/show.jsp从request作用域获取数据</h3><br/> <h3>myname数据:${myname}</h3><br/> <h3>myage数据:${myage}</h3> <h3>student数据:${mystudent}</h3> </body> </html>
-
测试如下: