1. springMVC类型转换器配置方法
1.1. 自定义类型转换器:将字符串转换为时间
//自定义类型转换器
public class DateConvertor implements Converter<String, Date> {
DateFormat[] dfs = {
new SimpleDateFormat("yyyy-MM-dd"),
new SimpleDateFormat("yyyy/MM/dd"),
new SimpleDateFormat("yyyy.MM.dd") };
@Override
public Date convert(String str) {
for (int i = 0; i < dfs.length; i++) {
try {
return dfs[i].parse(str);
} catch (ParseException ex) {
continue;
}
}
return new Date();
}
}
1.2. 在springmvc-serlvet.xml中注册自定义转换器
<!-- 注入自定义的类型转换器 -->
<bean id="dateConvertor" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.convertor.DateConvertor"></bean>
</set>
</property>
</bean>
<!-- conversion-service 指定自定义转换器在注解中生效 -->
<mvc:annotation-driven conversion-service="dateConvertor"></mvc:annotation-driven>
2. springMVC异常处理
2.1. SimpleMappingExceptionResolver
在springmvc-servlet.xml配置简单映射异常解析器
<!-- 配置简单映射异常解析器 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver" >
<!-- 指定项目报错后默认的错误页面的视图名 -->
<property name="defaultErrorView" value="error"></property>
<!-- 指定错误页面中用来显示错误信息的变量名 -->
<property name="exceptionAttribute" value="msg"></property>
<!-- 列举可能出现的所有异常的全称
ArithmeticException
IndexOutOfBoundsException
NullPointerException
-->
<property name="exceptionMappings">
<props>
<!-- arith_error 出现ArithmeticException异常,则跳转的目标页面的名称 -->
<prop key="java.lang.ArithmeticException" >arith_error</prop>
<prop key="java.lang.IndexOutOfBoundsException" >index_error</prop>
<prop key="java.lang.NullPointerException" >null_error</prop>
<prop key="com.exception.MyException" >error</prop>
</props>
</property>
</bean>
Arith_error.jsp
<!-- msg是在后台自动将当前的异常对象保存到msg中
对应配置<property name="exceptionAttribute" value="msg"></property>
-->
除零异常:${msg}
UserController代码
@RequestMapping("/f1")
public String fun1() {
int i = 9;
int j = 0;
System.out.println(i / j);
return "index";
}
可以设置自定义异常对象
public class MyException extends Exception {
private String message;
public MyException(String message) {
this.message = message;
}
}
@RequestMapping("/f3")
public String fun3() throws MyException {
int age = 200;
if (age > 0 && age < 120) {
return "index";
} else {
throw new MyException("年龄范围在0-120");
}
}
Error.jsp
<!-- 显示自定义异常的信息 -->
业务异常:${ex.message}
2.2. HandlerExceptionResolver
//自定义的异常处理器:统一处理异常
public class MyExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(
HttpServletRequest request,
HttpServletResponse response,
Object obj,
Exception ex) {
ModelAndView mv=new ModelAndView();
String msg="";
System.out.println(obj);
//获取当前发生的异常对象,根据不同异常,进行不同处理
if (ex instanceof ArithmeticException) {
msg="0不能做除数";
mv.setViewName("arith_error");
}else if (ex instanceof IndexOutOfBoundsException) {
msg="数组索引越界";
mv.setViewName("index_error");
}else if (ex instanceof NullPointerException) {
msg="对象为空";
mv.setViewName("null_error");
}else{
mv.setViewName("error");
}
mv.addObject("msg", msg);
//自定义MyException的信息需要通过属性来显示,将当前异常对象保存在作用域中
mv.addObject("ex", ex);
return mv;
}
}
Springmvc-servlet.xml注册MyExceptionResolver
<bean class="com.exception.MyExceptionResolver"></bean>
3. springMVC拦截器
3.1. 拦截请求,在交给对应的Controller对象处理业务的前后,进行其他操作
3.2. 拦截器流程图
3.3. 拦截器基本语法
public class MyInterceptor implements HandlerInterceptor {
//当前请求全部完成后执行
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object obj, Exception ex)
throws Exception {
System.out.println("进入afterCompletion");
}
//请求进入Controller之后执行的方法
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object obj, ModelAndView mv)
throws Exception {
System.out.println("进入postHandle");
}
//请求进入Controller之前执行的方法
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object obj) throws Exception {
System.out.println("进入preHandle");
}
}
4. 使用拦截器实现权限控制
4.1. 拦截器只拦截请求路径,不拦截页面路径,例如index.jsp不会被拦截
4.2. 如果完全实现路径的权限控制,请求路径由拦截器拦截,页面路径通过将页面放置到WEB-INF文件夹实现
4.3. 定义拦截某种类型的路径的拦截器
//拼写完整服务器路径
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
//获取当前请求路径,例如“springmvc2018/user/*”
//如果当前是登录请求,则放行
//项目名/user/login
String str=request.getRequestURI();
//截取代表当前要进行的业务的字符串
str=str.substring(str.lastIndexOf("/")+1);
//如果当前用户的信息保存在session中,或者当前请求的业务就是登陆
//这两种情况都可以不被拦截
if (request.getSession().getAttribute("user")!=null||str.equals("login")) {
return true;
}else{
response.sendRedirect(basePath+"login.jsp");
return false;
}
4.4. 在springmvc-serlvet.xml注册拦截器
<!-- 注册自定义的拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/user/*" />
<bean class="com.interceptor.MyInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
5. Springmvc框架下配置访问静态资源
5.1. 页面引用css,js,image等资源需要单独配置资源的路径映射关系,否则页面无法引用任何资源
5.2. Springmvc-servlet.xml配置
<!-- 设置静态资源的映射路径
/css/ 样式表在项目中的路径 http://localhost:8080/项目名/css/
/c/** 允许在页面上引用样式表示,可以使用的路径别名 http://localhost:8080/项目名/c/index.css
-->
<mvc:resources location="/css/" mapping="/a/**"></mvc:resources>
<mvc:resources location="/js/" mapping="/b/**"></mvc:resources>
<mvc:resources location="/images/" mapping="/c/**"></mvc:resources>
5.3. 将页面放置在WEB-INF下,则页面之间跳转需要后台Controller来控制
<a href="${basePath}user/toPage?url=b">跳转到b页面</a>
@RequestMapping("/toPage")
public String toPage(String url){
return url;
}
6. Springmvc+fileupload实现上传
6.1. 前台页面使用form元素传递文件
<form action="${basePath}user/add" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username" />
密码:<input type="text" name="userpwd" />
头像:<input type="file" name="face" />
<input type="submit" value="添加" />
</form>
6.2. Controller接收文件数据以及其他表单元素的数据
@RequestMapping("/add")
public String addUser(
HttpServletRequest request,
//获取用户其他文本信息
Tuser user,
//与表单文件元素file的name属性值一致
@RequestParam("face")
CommonsMultipartFile face
) {...}
6.3. Springmvc-serlvet.xml注入解析文件对象的解析器
<!-- 设置文件解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 上传最大字节数,单位byte -->
<property name="maxUploadSize" value="2097152"></property>
<!-- 上传文件字符编码 -->
<property name="defaultEncoding" value="UTF-8"></property>
</bean>
6.4. 上传:将获取用户文件复制到Tomcat服务器路径下的项目文件夹下指定存放图片的文件夹
String suffix=face.getOriginalFilename().substring(face.getOriginalFilename().lastIndexOf("."));
//定义目标文件的文件名
String targetFileName=System.currentTimeMillis()+suffix;
//获取项目所在的Tomcat的绝对路径
String projectPath=request.getServletContext().getRealPath("face");
6.5. 使用Java的io技术读取文件,写入目标文件
//获取上传文件的输入流对象
InputStream is=face.getInputStream();
//将目标文件对象保存到输出流中
OutputStream os=new FileOutputStream(projectPath+"//"+targetFileName);
int i=-1;
while ((i=is.read())!=-1) {
os.write(i);
}
os.flush();
6.6. 通过在数据库保存用户信息时,将上传文件的文件名保存在该用户图片列,方便后期读取用户对应的图片
//u.userpic 用户信息表中存放上传图片的列值
<img width="100px" height="100px" alt="" src="${basePath}face/${u.userpic}"><br/>
6.7. 注意:需要配置静态资源映射关系,才能在页面上访问图片