SpringMVC处理请求数据
一 处理请求数据简介
- Spring MVC 通过分析处理方法的签名(方法名+ 参数列表),HTTP请 求信息(报文)绑定到处理方法的相应形参中。
- 必要时可以对方法及方法入参标注相应的注解( @PathVariable 、@RequestParam、@RequestHeader 等 。
二 @RequestParam注解
- SpringMVC中默认会将请求参数与方法签名中的形参进行匹配。
- 如请求参数与方法签名中形参一致,会自动注入值。
- 如请求参数与方法签名中形参不一致,会注入null值。(所以不建议使用原生数据类型) - 如请求参数与方法签名中形参不一致时,也需要入参,怎么办?
- 此时使用@RequestParam注解,解决。- eg: @RequestMapping(value="/requestParams") public String requestParams(@RequestParam("username2") String username, @RequestParam("age2") Integer age){ }
- 注意:
- 一旦添加@RequestParam(“age2”)注解,必须为注解中的相应参数传值。
- 因为该注解中的属性设定默认情况如下:boolean required() default true;
- 如未在请求参数中传"age2"这个参数,会报错,400:Required Integer parameter ‘age2’ is not present
- 如当前属性非必须传值时,可以将required属性设置为false。
三 @RequestHeader注解
- 获取请求头信息
四 @CookieValue注解
- 获取Cookie信息(通过Cookie的可以,获取Value)
五 使用POJO对象处理请求参数(重要)
- Spring MVC 会请求参数名和 POJO 属性名进行自动匹配,自动为该对象填充属性值。支持级联属性。
如:dept.deptId、dept.address.tel 等 - 注意:参数名必须与POJO属性名一致,如不一致会注入null值。
六 使用原生Servlet API处理请求参数
- 需要将相应对象,放到参数中即可使用。
eg: @RequestMapping(value="/servletApi",method = RequestMethod.GET) String servletApi(HttpServletRequest request, HttpServletResponse response){ }
七 SpringMVC中处理乱码问题
-
回顾JavaWeb,如何解决乱码问题?自定义Filter
1. POST请求乱码:request.setCharacterEncoding("UTF-8");
3. GET请求乱码: tomcat->server.xml
<Connector URIEncoding="UTF-8" port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
4. 响应乱码:
response.setContentType("text/html;charset=UTF-8"); 同时设置服务器编码与浏览器解码均为:UTF-8 response.setCharacterEncoding("UTF-8"):只能设置服务器编码
-
SpringMVC提供CharacterEncodingFilter过滤器,处理乱码问题
源码解析:CharacterEncodingFilter
1. this.encoding!=null 时,可以处理POST请求乱码
2. forceEncoding==true 时,可以处理响应乱码
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
if (this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) {
request.setCharacterEncoding(this.encoding);
if (this.forceEncoding) {
response.setCharacterEncoding(this.encoding);
}
}
}
- 注意:如果使用SpringMVC提供的过滤器,解决乱码。
必须将该过滤器的位置,注册在第一个过滤器的位置。
主要因为:
一旦有过滤器执行,会默认记录编码及解码到缓存,后续的过滤器均使用缓存中的方式进行相应的编码&解码。
SpringMVC处理响应数据
一 回顾JavaWeb响应数据流程
- 将数据存放到域对象中(request|session|servletContext)
- 转发|重定向
二 SpringMVC处理响应数据
-
使用ModelAndView作为方法的返回值类型,响应数据
源码解析ModelAndView- 属性
private Object view; 视图对象|视图名 private ModelMap model; 模型数据,本质是Map
- 方法
* 处理模型数据 - addObject(String attrName,Object attrValue):设置模型数据 - getModel():获取模型数据 - getModelMap():获取模型数据 - getModelInternal():获取模型数据 * 处理视图对象 - setView(View view) - setViewName(String viewName) - View getView() - String getViewName()
- demo中发现问题
1. 数据存放在哪个域对象中?
* request
* AbstractView中182行 --> request.setAttribute();
2. 转发|重定向?
* 转发
* InternalResourceView:60行 --> exposeModelAsRequestAttributes()
* InternalResourceView:79行 --> rd.forward();
-
使用Map|Model作为方法入参(形参),响应数据
- Map&Model底层均为:org.springframework.validation.support.BindingAwareModelMap
- 该类实现两个接口,Map和Model - Map:与JavaSE学习Map用法一致。(较常用)
- Model:存放数据使用addAttribute()
- Map&Model底层均为:org.springframework.validation.support.BindingAwareModelMap
@Controller
public class ResponseData {
@RequestMapping("/username")
public ModelAndView username(){
ModelAndView mv = new ModelAndView();
mv.addObject("username","张三");
mv.setViewName("list");
return mv;
}
@RequestMapping("/usernameModel")
public String usernameModel(Model model){
model.addAttribute("username","李四");
return "list";
}
@RequestMapping("/usernameMap")
public String usernameMap(Map map){
map.put("username","王五");
return "list";
}
}
<a href="${pageContext.request.contextPath}/username">获取姓名</a>
<a href="${pageContext.request.contextPath}/usernameModel">获取姓名Model</a>
<a href="${pageContext.request.contextPath}/usernameMap">获取姓名Map</a>
SpringMVC视图解析
web.xml
<!-- 注册CharacterEncodingFilter-->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!-- encoding!=null时,开启处理POST请求乱码-->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<!-- forceEncoding==true时,开启处理响应乱码-->
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 注册HiddenHttpMethodFilter-->
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 注册DispatcherServlet-->
<servlet>
<servlet-name>dispatchServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatchServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
springmvc.xml
<!-- 组件扫描-->
<context:component-scan base-package="com.atguigu.springmvc.controller"/>
<!-- 视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>