由于日期数据有很多种格式,springmvc 提供@DateTimeFormat注解,自动实现格式转换。
@DateTimeFormat(pattern="yyyy-MM-dd")
private Date ubirthday;
<input type="date" name="ubirthday">
如果form表单提交方式为post,中文请求会出现乱码,底层默认采用的是“ISO8859-1”编码。
可以在web.xml 中添加字符编码过滤器解决。
<filter>
<filter-name>characterEncodingFilterfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
<init-param>
<param-name>forceEncodingparam-name>
<param-value>trueparam-value>
init-param>
filter>
<filter-mapping>
<filter-name>characterEncodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
如果响应的是JSON格式数据,spring4.3及以上版本默认就是UTF-8编码格式,无需特殊处理。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
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-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<context:component-scan base-package="com.bodhixu.web" />
<mvc:annotation-driven />
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="5242880" />
bean>
beans>
修改 form 表单:regist.jsp
提交方式为 “post”
enctype 格式为 “multipart/form-data”
input 类型为"file",name 属性名称必须和 Cotroller 中方法形参名称一致
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title heretitle>
head>
<body>
<form action="${pageContext.request.contextPath }/regist.action"
method="post" enctype="multipart/form-data">
姓名:<input type="text" name="name"><br>
年龄:<input type="text" name="age"><br>
头像:<input type="file" name="picFile"><br><br>
<input type="submit" value="注册"><br>
form>
body>
html>
在方法中接收文件的形参类型为 MultipartFile,形参名称必须和表单文件域名称一致。
@SessionAttributes(types=User.class)
@Controller
public class UserController {
@RequestMapping("regist")
public String regist(User user, MultipartFile headerFile) {
// 获取文件名
String oriName = headerFile.getOriginalFilename();
// 获取图片后缀
String suffix = oriName.substring(oriName.lastIndexOf("."));
// 设置新文件名,可以使用uuid
String picName = UUID.randomUUID().toString();
// 设置保存文件的全路径
String filePath = "E:" + File.separator + "img" + File.separator + picName + suffix;
// 创建新图片文件
File file = new File(filePath);
// 开始图片上传
try {
headerFile.transferTo(file);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// 设置头像地址
user.setUheader(picName + suffix);
// 将文件地址写入数据库,只需要写入 “文件名+后缀名”,略
return "redirect:/jsp/login.jsp";
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title heretitle>
head>
<body>
<h2>${user.uname }h2>
<h2>${user.uage }h2>
<img src="/img/${user.uheader }">
body>
html>
系统的dao、service、controller出现异常如果未手动处理,就会通过throws Exception向上抛出,最后由前端控制器交由异常处理器进行异常处理,流程如下图:
具体实现步骤:
@Controller
public class CustomController {
@RequestMapping("test")
private String query() {
int x = 1/0;
System.out.println(x);
return null;
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title heretitle>
head>
<body>
<h2>系统发生异常h2>
<h4>异常信息为:${msg }h4>
body>
html>
@Component
public class CustomeExceptionResolver implements HandlerExceptionResolver{
/**
* Object obj: 封装了异常发生的位置(包名.类名.方法名(参数))
* Exception e: 捕获到的异常对象
*/
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response, Object obj, Exception e) {
ModelAndView mv = new ModelAndView();
mv.addObject("errorMsg", e.getMessage());
mv.setViewName("/WEB-INF/jsp/error.jsp");
return mv;
}
}
Spring MVC 可以使用拦截器对请求进行拦截处理,用户可以自定义拦截器来实现特定的功能,自定义的拦截器必须实现 HandlerInterceptor 接口。
5.1 HandlerIntercepetor 接口
preHandle()
在 Controller(业务处理器)处理请求之前被调用,在该方法中可以对用户请求进行处理。放行返回true,拦截返回false。可以在该方法中加入登录验证、权限拦截等。
postHandle()
在 Controller 处理请求之后但是向客户端返回响应前(返回视图前)被调用。可以在该方法中对模型数据进行加工,比如加入一些公共信息等。
在 Controller 处理请求之后并且向客户端返回响应后(返回视图)被调用。可以在该方法中获得异常信息,进行日志、资源清理的操作。
public class LoginInterceptor implements HandlerInterceptor{
// 在Controller后并返回视图后调用
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
System.out.println("afterCompletion....");
}
// 在Controller后返回视图前调用
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
throws Exception {
System.out.println("postHandle....");
}
// 在Controller前调用
// 返回false-拦截, 返回true-放行
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
System.out.println("preHandle....");
return true;
}
}
5.2 配置拦截器
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/admin/**"/>
<bean class="com.bodhixu.ssm.interceptor.LoginInterceptor"/>
mvc:interceptor>
mvc:interceptors>
5.3 案例:登录认证
启动程序,默认进入后台主画面。如果未登录,自动跳转到登录画面。
如果将 DispatcherServlet 请求映射配置为 /,则 SpringMVC 将捕获 WEB 容器的所有请求,包括静态资源的请求,则类似于jquery.js等静态资源则加载失败。
解决静态资源的问题,可以在 SpringMVC 的配置文件中配置如下:
<mvc:default-servlet-handler/>