目录
SpringMVC HelloWorld
SpringMVC 接收表单数据
SpringMVC 客户端跳转
SpringMVC Session
SpringMVC 中文问题
SpringMVC 上传文件
SpringMVC 拦截器
项目目录截图:
maven 文件:
org.springframework
spring-webmvc
5.1.7.RELEASE
web.xml 文件
Archetype Created Web Application
encodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
forceEncoding
true
encodingFilter
/*
dispatcherServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc.xml
1
dispatcherServlet
/
springmvc.xml 配置文件:
controller:
@Controller
@RequestMapping("/first")
public class FirstController {
@RequestMapping("/index")
public ModelAndView index(){
ModelAndView mv=new ModelAndView("first/index");
mv.addObject("message","first message");
return mv;
}
}
index.jsp
<%@page contentType="text/html; UTF-8" language="java" pageEncoding="utf-8" isELIgnored="false" %>
首个页面
${message}
FormController:
@Controller
@RequestMapping("/form")
public class FormController {
@RequestMapping("/index")
public ModelAndView index(Student student){
ModelAndView mv=new ModelAndView("form/index");
//参数student会默认被当做值加入到ModelAndView 中
return mv;
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" isELIgnored="false" %>
表单测试
提交数据如下:
姓名:${student.name}
年龄:${student.age}
ModelAndView mv=new ModelAndView("redirect:form/index");
pom.xml
javax.servlet
javax.servlet-api
4.0.1
provided
SessionController
@Controller
@RequestMapping("/session")
public class SessionController {
@RequestMapping("/index")
public ModelAndView index(HttpSession session){
Integer i=(Integer) session.getAttribute("count");
if(i==null){
i=0;
}
i++;
session.setAttribute("count",i);
ModelAndView mv=new ModelAndView("session/index");
return mv;
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" isELIgnored="false" %>
session 测试
访问了:${count}
web.xml
encodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
forceEncoding
true
encodingFilter
/*
pom.xml
org.apache.commons
commons-lang3
3.9
commons-fileupload
commons-fileupload
1.4
springmvc.xml
实体类 UploadImageFile:
public class UploadImageFile {
private MultipartFile image;
public MultipartFile getImage() {
return image;
}
public void setImage(MultipartFile image) {
this.image = image;
}
}
控制器 UploadController:
@Controller
@RequestMapping("/upload")
public class UploadController {
@RequestMapping(value="/index",method = RequestMethod.GET)
public ModelAndView index(HttpServletRequest request){
ModelAndView mv= new ModelAndView("upload/index");
return mv;
}
@RequestMapping(value="/index",method = RequestMethod.POST)
public ModelAndView index(HttpServletRequest request, UploadImageFile file) throws IOException {
String newName= RandomStringUtils.randomAlphabetic(10)+".jpg";
File newFile=new File(request.getServletContext().getRealPath("/image"),newName);
newFile.getParentFile().mkdirs();
file.getImage().transferTo(newFile);
ModelAndView mv=new ModelAndView("upload/index");
mv.addObject("imageUrl","image/"+newName);
return mv;
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" isELIgnored="false" %>
文件上传测试
上传的图片为:
springMVC拦截器的实现一般有两种方式
第一种方式是要定义的Interceptor类要实现了Spring的HandlerInterceptor 接口
第二种方式是继承实现了HandlerInterceptor接口的类,比如Spring已经提供的实现了HandlerInterceptor接口的抽象类HandlerInterceptorAdapter
HandlerInterceptor 接口中定义了三个方法,我们就是通过这三个方法来对用户的请求进行拦截处理的。
preHandle(): 这个方法在业务处理器处理请求之前被调用,SpringMVC 中的Interceptor 是链式的调用的,在一个应用中或者说是在一个请求中可以同时存在多个Interceptor 。每个Interceptor 的调用会依据它的声明顺序依次执行,而且最先执行的都是Interceptor 中的preHandle 方法,所以可以在这个方法中进行一些前置初始化操作或者是对当前请求的一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。该方法的返回值是布尔值Boolean 类型的,
当它返回为false 时,表示请求结束,后续的Interceptor 和Controller 都不会再执行;并且从当前拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链,
当返回值为true 时,就会继续调用下一个Interceptor 的preHandle 方法,如果已经是最后一个Interceptor 的时候就会是调用当前请求的Controller 方法。
postHandle():这个方法在当前请求进行处理之后,也就是Controller 方法调用之后执行,但是它会在DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作。postHandle 方法被调用的方向跟preHandle 是相反的,也就是说先声明的Interceptor 的postHandle 方法反而会后执行。
afterCompletion():该方法也是需要当前对应的Interceptor 的preHandle 方法的返回值为true 时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。
下面来看我们的Interceptor类
package com.joe.interceptor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
public class CommonInterceptor extends HandlerInterceptorAdapter {
/**
* 在业务处理器处理请求之前被调用
* 如果返回false
* 从当前的拦截器往回执行所有拦截器的afterCompletion(),再退出拦截器链
*
* 如果返回true
* 执行下一个拦截器,直到所有的拦截器都执行完毕
* 再执行被拦截的Controller
* 然后进入拦截器链,
* 从最后一个拦截器往回执行所有的postHandle()
* 接着再从最后一个拦截器往回执行所有的afterCompletion()
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle(), 在访问Controller之前被调用");
return true;
}
/**
* 在业务处理器处理请求执行完成后,生成视图之前执行的动作
* 可在modelAndView中加入数据,比如当前时间
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle(), 在访问Controller之后,访问视图之前被调用,这里可以注入一个时间到modelAndView中,用于后续视图显示");
modelAndView.addObject("date","由拦截器生成的时间:" + new Date());
}
/**
* 在DispatcherServlet完全处理完请求后被调用,可用于清理资源等
* 当有拦截器抛出异常时,会从当前拦截器往回执行所有的拦截器的afterCompletion()
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion(), 在访问视图之后被调用");
}
}
多个拦截器执行结果:
preHandle(), 在访问Controller之前被调用
second preHandle 被调用
second postHandler 被调用
postHandle(), 在访问Controller之后,访问视图之前被调用,这里可以注入一个时间到modelAndView中,用于后续视图显示
second afterCompletion 被调用
afterCompletion(), 在访问视图之后被调用
码云地址:源码下载