请求处理方法签名
1) Spring MVC 通过分析处理方法的签名,将HTTP请求信息绑定到处理方法的相应入参中。
2) Spring MVC 对控制器处理方法签名的限制是很宽松的,几乎可以按喜欢的任何方式对方法进行签名。
@RequestParam注解
在处理方法入参处使用 @RequestParam 可以把请求参数传递给请求方法
- value:参数名
- required:是否必须。默认为 true, 表示请求参数中必须包含对应的参数,若不存在,将抛出异常
- defaultValue: 默认值,当没有传递参数时使用该值
使用POJO作为参数
1) 使用 POJO 对象绑定请求参数值
2) Spring MVC 会按请求参数名和 POJO 属性名进行自动匹配,自动为该对象填充属性值。支持级联属性。如:dept.deptId、dept.address.tel 等
使用Servlet原生API作为参数
MVC 的 Handler 方法可以接受哪些 ServletAPI 类型的参数:
1. HttpServletRequest
2. HttpServletResponse
3. HttpSession
4. java.security.Principal
5. Locale
6. InputStream
7. OutputStream
8. Reader
9. Write
代码示例:
(项目仍是在前两篇博客中相同的项目)
使用POJO需要的实体类:
Employee:
package com.learn.springmvc.entities;
public class Employee {
private Integer id;
private String lastName;
private String email;
private Department dept;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Department getDept() {
return dept;
}
public void setDept(Department dept) {
this.dept = dept;
}
@Override
public String toString() {
return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", dept=" + dept + "]";
}
}
Department:
package com.learn.springmvc.entities;
public class Department {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Department [id=" + id + ", name=" + name + "]";
}
}
index.jsp发送相应的请求:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<a href="${pageContext.request.contextPath }/hello">Hello SpringMVC</a><br>
<a href="${pageContext.request.contextPath }/testValue2">Test value</a><br>
<a href="${pageContext.request.contextPath }/testMethod">Test method</a><br>
<form action="${pageContext.request.contextPath }/testMethod" method="post">
<input type="submit" value="Test Method">
</form>
<%-- <a href="${pageContext.request.contextPath }/testRequestParam?username=admin&age=18">Test RequestParam</a><br> --%>
<a href="${pageContext.request.contextPath }/testRequestParam?username=admin">Test RequestParam</a><br>
<form action="${pageContext.request.contextPath }/testPOJO" method="post">
员工工号:<input type="text" name="id"><br>
员工姓名:<input type="text" name="lastName"><br>
员工邮箱:<input type="text" name="email"><br>
部门编号:<input type="text" name="dept.id"><br>
部门名称:<input type="text" name="dept.name"><br>
<input type="submit" value="Test POJO">
</form>
<a href="${pageContext.request.contextPath }/testServletAPI?username=admin">Test ServletAPI</a><br>
</body>
</html>
三种方法都在SpringMVCHandler.java中,以完成index.jsp中的测试请求:
package com.learn.springmvc.helloworld;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
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 com.learn.springmvc.entities.Employee;
@Controller
public class SpringMVCHandler {
/*
* @RequestMapping注解中的属性
* 1.value:用来设置映射的请求地址,值得类型是String类型的数组
* 如果只映射一个请求地址,那么value的值不需要添加大括号{},value属性名可以省略不写
* 2.method:用来设置要映射的请求方式
* 如果没有设置该属性,那么只看映射的请求地址,不管请求方式
*/
@RequestMapping(value= {"/testValue","/testValue2"})
public String testValue() {
System.out.println("测试@RequestMapping注解value属性");
return "success";
}
// @RequestMapping(value="/testMethod",method=RequestMethod.GET,params="age=18")
@RequestMapping(value="/testMethod",method=RequestMethod.POST)
public String testMethod() {
System.out.println("测试@RequestMapping注解method属性");
return "success";
}
/*
* @RequestParam注解:
* -用来映射请求参数
* 如果Handler的方法的入参的参数名与请求参数的参数名一致,那么该该注解可以省略
* -该注解的属性:
* 1.value:
* 设置请求参数的名字
* 2.required:
* 设置该请求参数是否是必须的,,默认是true
* 3.defaultValue:
* 这只请求参数的默认值,如果没有传入请求参数将使用该值
*/
@RequestMapping("/testRequestParam")
// public String testRequestParam(String username, Integer age) {
public String testRequestParam(@RequestParam(value="username") String user,
@RequestParam(value="age",required=false,defaultValue="0") Integer age) {
System.out.println("用户名是:"+user);
System.out.println("年龄是:"+age);
return "success";
}
/*
* Spring MVC会按请求参数名和 POJO 属性名进行自动匹配,自动为该对象填充属性值。支持级联属性
*/
@RequestMapping("/testPOJO")
public String testPOJO(Employee employee) {
System.out.println("员工信息是:"+employee);
return "success";
}
/*
* MVC 的 Handler 方法可以接受哪些 ServletAPI 类型的参数
1) *HttpServletRequest
2) *HttpServletResponse
3) *HttpSession
4) java.security.Principal
5) Locale
6) InputStream
7) OutputStream
8) Reader
9) Write
*/
@RequestMapping("/testServletAPI")
public String testServletAPI(HttpServletRequest request, HttpServletResponse response) {
//获取请求参数
String username = request.getParameter("username");
System.out.println(username);
return "success";
}
}
解决POST请求中文乱码问题
index.jsp页面中存在的表单,提交时提交到服务器会出现中文乱码问题,无法正常显示,此时就需要相应的解决办法。
我以前的博客中也提到过类似问题的解决办法,但在Spring MVC中可以使用Spring提供的CharacterEncodingFilter过滤器中的doFilterInternal方法
CharacterEncodingFilter:
public class CharacterEncodingFilter extends OncePerRequestFilter {
private String encoding;
private boolean forceEncoding = false;
public void setEncoding(String encoding) {
this.encoding = encoding;
}
public void setForceEncoding(boolean forceEncoding) {
this.forceEncoding = forceEncoding;
}
@Override
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);
}
}
filterChain.doFilter(request, response);
}
}
要使用在web.xml中配置过滤器即可
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- 配置解决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>
<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>
<!-- 配置前端控制器:DispatcherServlet
快捷键:alt + / 选中倒数第二项
-->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- 配置SpringMVC配置文件的路径 -->
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<!-- 配置映射的请求地址:"/" -->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>