@RequestMapping注解映射请求
-
SpringMVC使用@RequestMapping注解为控制器指定可以处理哪些URL请求
-
在控制器的类定义及方法定义处都可标注
类定义处:提供初步的请求映射信息。相对于WEB应用的根目录
方法处:提供进一步的细分映射信息,相对于类定义处的URL。若类定义处未定义,则相对于根目录 -
DispatcherServlet截获请求后,就通过控制器上的@RequestMapping提供的映射信息确定请求所对应的处理方法。
springmvcConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--注解扫描包-->
<context:component-scan base-package="com.zx"/>
<!--试图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
AnnotationController.java
package com.zx.controller;
import com.zx.domain.User;
import com.zx.validate.Validate1;
import com.zx.validate.Validate2;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.validation.annotation.Validated;
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.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/*注解形式,需要在xml配置扫描包*/
@Controller
@RequestMapping("/user")
/*包扫描可以识别到处理器,适配器,不需要实现接口*/
public class AnnotationController {
@RequestMapping("/fun1.action")
public ModelAndView fun1() {
ModelAndView modelAndView = new ModelAndView();
/*配置了前缀WEB-INF/jsp和后缀.jsp*/
modelAndView.setViewName("hello");
return modelAndView;
}
}
@RequestMapping除了可以使用请求URL映射请求外,还可以使用请求方法、请求参数、及请求头映射请求。
- value表示请求URL
- method表示请求方法
- params表示请求参数
- headers表示请求头的映射条件
params 和 headers支持简单的表达式:
param1: 表示请求必须包含名为 param1 的请求参数
!param1: 表示请求不能包含名为 param1 的请求参数
param1 != value1: 表示请求包含名为 param1 的请求参数,但其值不 能为 value1
{“param1=value1”, “param2”}: 请求必须包含名为 param1 和 param2 的两个请求参数,且 param1 参数的值必须为 value1
controller方法的返回值
返回值类型:
1. ModelAndView
对象中可添加 model数据、指定view
AnnotationController.java
/*注解形式,需要在xml配置扫描包*/
@Controller
@RequestMapping("/user")
/*包扫描可以识别到处理器,适配器,不需要实现接口*/
public class AnnotationController {
public ModelAndView fun1() {
ModelAndView modelAndView = new ModelAndView();
/*配置了前缀WEB-INF/jsp和后缀.jsp*/
modelAndView.setViewName("hello");
List<String> users = new ArrayList<>();
users.add("AA");
users.add("BB");
users.add("CC");
modelAndView.addObject("users", users);
return modelAndView;
}
}
pom.xml标准标签库
<!--c-->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
2.字符串
返回字符串时,有三种含义 :
- 返回逻辑视图名
- redirect重定向
- forward页面转发
1.逻辑视图名
/*返回值类型*/
@RequestMapping("/fun2.action")
public String fun2() {
return "fun2";
}
2.redirect重定向
redirect重定向特点:浏览器地址栏中的url会变化。修改提交的 request数据无法传到重定向的地址。因为重定向后重新进行request( request无法共享)
不能使用视图解析器
@RequestMapping("/fun5.action")
public String fun5() {
return "redirect:/index.jsp";
}
3.forward页面转发
通过forward进行页面转发,浏览器地址栏url不变,request可以共享
不能使用视图解析器
@RequestMapping("/fun4.action")
public String fun4() {
return "forward:/WEB-INF/jsp/fun2.jsp";
}
3. void
@RequestMapping("/fun3.action")
public void fun3(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
httpServletRequest.getRequestDispatcher("/WEB-INF/jsp/fun2.jsp").forward(httpServletRequest, httpServletResponse);
}
不能使用视图解析器
当返回void时,在controller方法形参上可以定义request和 response,使用request或response指定响应结果:
- 使用request转向页面,如下:
request.getRequestDispatcher("页面路径").forward(request, response);
- 可以通过response页面重定向:
response.sendRedirect("url")
- 可以通过response指定响应结果,例如响应json数据如下:
response.setCharacterEncoding("utf-8");
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("json串");
参数绑定过程
从客户端请求key/value数据,经过参数绑定,将key/value数据绑定到 controller方法的形参上。springmvc中,接收页面提交的数据是通过方法形参来接收,而不是在 controller类定义成员变量接收。
默认支持的类型
处理器形参中添加如下类型的参数,处理适配器会默认识别并进行赋 值
- HttpServletRequest
通过request对象获取请求信息 - HttpServletResponse
通过response处理响应信息 - HttpSession
通过session对象得到session中存放的对象 - Model/ModelMap
ModelMap是Model接口的实现类,将model数据填充到request域,向页面传递 数据
简单类型绑定
支持整型、字符串、单精度/双精度、布尔型
当请求的参数名称和处理器形参名称一致时会将请求参数与形参进行绑 定
通过@RequestParam对简单类型的参数进行绑定。
如果不使用@RequestParam,要求request传入参数名称和controller方法的形参名称一致,方可绑定成功。
如果使用@RequestParam,不用限制request传入参数名称和controller方法的形参名称一致
**@RequestParam的参数 **
value:参数名字,即入参的请求参数名字,如value=“item_id”表示 请求的参数中的名字为item_id的参数的值将传入;
required:是否必须,默认是true,表示请求中一定要有相应的参数, 否则将报 defaultValue:默认值,表示如果请求中没有同名参数时的默认值
login.jsp 设置E-L表达式 isELIgnored=“false”
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>Login</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/user/login.action"method="post">
<input name="username"/>
<input type="password" name="password"/>
<input type="submit" value="login"/>
</form>
</body>
</html>
controller
@RequestMapping("/login.action")
/*形参名称和jsp页面的参数name一样*/
/*不一样的加注解*/
public String login( String username, String password){
System.out.println(username+" "+password);
return "";
}
结果
POJO类型绑定
1 简单的POJO绑定
将pojo对象中的属性名与传递进来的参数名对应
如果传进来的参数名称和对象中的属性名称一致,则将参数值设置在 pojo对象中
User.java
public class User implements Serializable {
private Integer id;
private String userName;
private String password;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
controller
@RequestMapping("/login.action")
public String login( User user) {
model.addAttribute("user",user);
return "index";
}
index.jsp
2.包装POJO绑定
将pojo对象作为一个包装对象的属性,controller方法中以该包装对象 作为形参。
Car.java
package com.zx.domain;
import java.io.Serializable;
public class Car implements Serializable {
private String name;
private Double price;
@Override
public String toString() {
return "Car{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
}
User.java
package com.zx.domain;
import com.zx.validate.Validate1;
import com.zx.validate.Validate2;
import org.hibernate.validator.constraints.Email;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.Size;
import java.io.Serializable;
import java.time.LocalDate;
public class User implements Serializable {
private Integer id;
private String userName;
private String password;
private Car car;
public Car getCar() {
return car;
}
public void setCar(Car car) {
this.car = car;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
controller
public String login(User user) {
model.addAttribute("user",user);
System.out.println("1 "+user.getUserName()+"2 "+user.getPassword()+"3 "+user.getCar().getName()+"4 "+user.getCar().getPrice());
return "index";
}
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>Login</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/user/login.action"method="post">
<input name="userName"/>
<input type="password" name="password"/>
<input name="car.name"/>
<input name="car.price"/>
<input type="submit" value="login"/>
</form>
</body>
</html>
自定义参数绑定
- 根据业务需求使用自定义参数绑定
- 需要向处理器适配器中注入自定义的参数绑定组件
- 对于controller形参中pojo对象,如果属性中有日期类型,需要自定 义参数绑定
将请求日期数据串转成日期类型,要转换的日期类型和pojo中日期属性的类型保持一致
用户发送过来的数据类型都是字符串类型
没有配置转换器,传日期类型的参数会出400异常
自定义日期类型转换器
package com.zx.converter;
import org.springframework.core.convert.converter.Converter;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class DateConverter implements Converter<String,LocalDate> {
@Override
public LocalDate convert(String s) {
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-mm-dd");
try {
return LocalDate.parse(s);
}catch (Exception e){
e.printStackTrace();
}
return null;
}
}
springmvcConfi.xml配置转换器
<!--时间转换器注解-->
<mvc:annotation-driven conversion-service="conversionService" />
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<!--此声明一个对象,注入自定义的转换器-->
<property name="converters">
<list>
<bean class="com.zx.converter.DateConverter"/>
</list>
</property>
</bean>
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>Login</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/user/login.action"method="post">
<input name="userName"/>
<input type="password" name="password"/>
<input name="birthDate"/>
<input type="submit" value="login"/>
</form>
</body>
</html>
集合类型绑定
deleteItem.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/user/deleteItem.action"method="post">
<input type="checkbox" name="hobby" value="1"/>
<input type="checkbox" name="hobby" value="2"/>
<input type="checkbox" name="hobby" value="3"/>
<input type="submit" value="delete"/>
</form>
</body>
</html>
controller
@RequestMapping("/deleteItem.action")
public void deleteItem(int[] hobby) {
for (int i = 0; i < hobby.length; i++) {
System.out.println(hobby[i]);
}
}
List中存放对象,并将定义的List放在包装类中,controller方法中使 用包装对象接收