控制器用于处理业务请求,而适配器用于寻找应该使用什么样的控制器。
1、SimpleControllerHandlerAdapter:用于寻找实现了 Controller 接口的 action 类;是 springmvc 默认使用的适配器;
表单页面:
<form action="${pageContext.request.contextPath}/add.action" method="post">
员工姓名:<input type="text" name="username">
<input type="submit" value="提交">
</form>
springmvc.xml 配置文件:
<!-- 注册 action -->
<bean name="/add.action" class="com.springmvc.user.UserAction"></bean>
<!-- 配置适配器:
SimpleControllerHandlerAdapter:寻找实现了 Controller 接口的 action 类;
(springmvc 的默认配置,不写也行)
-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
实现了 Controller 接口的 action 类(控制器):
/**
* 控制器:实现了 Controller 接口
* */
public class UserAction implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) throws Exception {
// 设置中文编码
httpServletRequest.setCharacterEncoding("utf-8");
ModelAndView modelAndView = new ModelAndView();
// 获取表单提交的数据
String username = httpServletRequest.getParameter("username");
System.out.println("username:" + username);
// 封装数据
modelAndView.addObject("message", username);
// 封装路径
modelAndView.setViewName("/jsp/success.jsp");
return modelAndView;
}
}
web.xml:
<!-- 注册 springmvc 核心控制器 -->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置初始化参数:到指定目录下加载 springmvc.xml 配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- classpath:表示到 src 目录下查找配置文件 -->
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
实现 Controller 接口的 action 类的缺点:
a)、代码耦合(spring 框架中用到了传统 servlet);
b)、如果表单提交的参数过多,收集起来不便;
2、现在有一个需求,我想从一个 jsp 页面直接跳转到另一个位于 WEB-INF 路径下的 jsp 页面;
此时,就不需要我们自己去写 控制器了,可以使用 springmvc 提供的控制器 ParameterizableViewController 实现;
注意:不能直接跳转到位于 WEB-INF 路径下的 jsp 页面;
跳转的超链接:
<a href="${pageContext.request.contextPath}/index.action" style="text-decoration: none">返回主页</a>
springmvc.xml 配置文件:
<!-- action 不用配置 -->
<!-- 映射器 不用配置 -->
<!-- 适配器 不用配置 -->
<!-- 视图解析器 不用配置 -->
<!-- 需要配置一个专用于 jsp 页面到 jsp/html 页面的 转发控制器 -->
<bean name="/index.action" class="org.springframework.web.servlet.mvc.ParameterizableViewController">
<!-- 转发到的真实视图名 -->
<property name="viewName" value="/WEB-INF/index.jsp"/>
</bean>
3、实现 Controller 接口的 action 类,如果想接收表单提交的数据,只能通过 httpServletRequest.getParameter("username"); 方法接收,如果提交的参数过多,接收起来就会比较麻烦;
如果我想用一个实体类接收 表单提交的数据,可以使用 AbstractCommandController 来实现;
继承于 AbstractCommandController 的 action 类:
/**
* 控制器:继承了 AbstractCommandController 类
* */
public class EmpAction extends AbstractCommandController {
// 构造函数
public EmpAction(){
// 自动将表单提交的数据封装到 Emp 对象中,然后传给 handle 方法中的 第三个参数
this.setCommandClass(Emp.class);
System.out.println("EmpAction()...");
}
/**
* 自定义类型转换器,将表单提交的 String 类型的数据转换成 Date 类型(yyyy-MM-dd)
*/
@Override
protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception {
/**
* 向 springmvc 内部注册一个自定义的类型转换器:
* 参数一:将 String 类型的数据转换成什么类型的 字节码;
* 参数二:属性编辑器,即我们自定义的转换规则;
* yyyy-MM-dd 表示转换的日期格式;
* true 表示字段可为空,false 表示不可为空;
*/
binder.registerCustomEditor(Date.class,
new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
}
/**
* 重写父类的方法
* @param o 表示封装后的实体
* @param e 表示封装时产生的异常
*/
@Override
protected ModelAndView handle(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse, Object o, BindException e) throws Exception {
System.out.println("handle()...");
// 将 参数3 强转为 Emp 对象
Emp emp = (Emp) o;
System.out.println(emp);
// 封装数据和路径
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("message", "增加员工成功!");
modelAndView.addObject("emp", emp); // 将封装表单数据的对象传到页面
modelAndView.setViewName("/jsp/success.jsp");
return modelAndView;
}
}
实体类 Emp.java:
package com.springmvc.emp;
import java.util.Date;
public class Emp {
private String username; // 用户名
private String gender; // 性别
private Date hiredate; // 入职时间
public Emp() {
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Date getHiredate() {
return hiredate;
}
public void setHiredate(Date hiredate) {
this.hiredate = hiredate;
}
@Override
public String toString() {
return "Emp{" +
"username='" + username + '\'' +
", gender='" + gender + '\'' +
", hiredate=" + hiredate +
'}';
}
}
表单页面:
<form action="${pageContext.request.contextPath}/add.action" method="post">
<table border="2" align="center">
<tr>
<th>姓名</th>
<td><input type="text" name="username"></td>
</tr>
<tr>
<th>性别</th>
<td>
<input type="radio" name="gender" value="男">男
<input type="radio" name="gender" value="女" checked>女
</td>
</tr>
<tr>
<th>入职时间</th>
<td><input type="text" name="hiredate" value="2019-11-20"></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="提交"></td>
</tr>
</table>
</form>
springmvc.xml 配置文件:
<!-- 注册 action -->
<bean name="/add.action" class="com.springmvc.emp.EmpAction"></bean>
<!-- 映射器 不用配置 -->
<!-- 适配器:SimpleControllerHandlerAdapter,去找实现了 Controller 接口的 action,
也可以去找继承了 AbstractCommandController 类的 action; -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
<!-- 视图解析器 不用配置 -->
/jsp/success.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
success.jsp<br>
<%-- 输出控制器中传过来的数据 --%>
${requestScope.message}<br>
姓名:${requestScope.emp.username}<br>
性别:${requestScope.emp.gender}<br>
入职时间:${requestScope.emp.hiredate}<br> <%-- 默认显示的时间格式:Wed Nov 20 00:00:00 CST 2019--%>
<%--
使用格式化标签显示:
value:表示需要格式化的值;
type:
值为 date 表示显示日期;
值为 time 表示显示时间;
值为 both 表示日期和时间都显示
dateStyle:
取值为 short、medium、long、full、default
--%>
入职时间:
<fmt:formatDate value="${requestScope.emp.hiredate}" type="date" dateStyle="full"/>
</body>
</html>
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 注册 springmvc 核心控制器 -->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置初始化参数:到指定目录下加载 springmvc.xml 配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- classpath:表示到 src 目录下查找配置文件 -->
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- springmvc 提供的,专用于解决 POST 提交中文乱码问题,指定编码为 UTF-8 -->
<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>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
表单界面:
提交结果: