目录
一、文件上传(多媒体视图解析器)
1 servlet的文件上传
2.CommonsMultipartResolver
1.在spring中配置多媒体视图的解析器
2.MultipartFile 可以作为请求参数,根据名称会将多媒体组件封装在该类型的参数中
3.多文件上传
二、视图解析器
三、拦截器(拦截不了jsp页面)
1 应用场景
2 过滤器和拦截器的区别
3步骤
3.1定义拦截器 实现HandlerInterceptor接口
3.2将拦截器交给spring管理
3.3 配置拦截器
4 拦截器链
5 无法拦截jsp
6 拦截jsp的解决方案:
7.不拦截静态资源(推荐使用)
8 应用场景的例子
1.权限设置(拦截器版本)
2.性能监控(监控请求的执行时间和响应时间)
四、全局异常处理器
1.步骤
1.1 创建类 实现HandlerExceptionResolver接口
2.2 将类交给spring管理
2.3 自定义异常
2.4 方法中抛出异常
一、文件上传(多媒体视图解析器)
springmvc多媒视图解析器,快速的使用commons-fileupload进行文件上传,并且简化了传统commons-fileupload文件上传的代码编写
1 servlet的文件上传
springmvc多媒视图解析器,快速的使用commons-fileupload进行文件上传,并且简化了传统commons-fileupload文件上传的代码编写
首先添加 commons-io.jar commons-fileupload.jar
//文件上传 手动写
@ResponseBody
@PostMapping("/upload")
public String testLoad(HttpServletRequest request,HttpServletResponse response) throws Exception {
//多媒体enctype 无法使用 requestParameter("")
//创建diskfileitemfactory处理文件的上传路径和大小限制;
DiskFileItemFactory factory =new DiskFileItemFactory();
// factory可选方法
// factory.setSizeThreshold(1024*1024);//factory的set不用写有默认值
// factory.setRepository(tmpFile);//设置临时仓库
//准备完成后创建文件上载对象
ServletFileUpload upload =new ServletFileUpload(factory);
//将发送来的数据表单中的对象通过upload对象解析成FileitemList
List items = upload.parseRequest(request);
//遍历每个List中的对象判断需要上载的文件
User user =new User();
for (FileItem item : items) {
//判断对象是否是表单中的普通类还是文件类
if(item.isFormField()) {
//普通组件
// getFieldName是获得表单中输入框的name
String name=item.getFieldName();
String value=item.getString("UTF-8");//乱码处理
if("userName".equals(name)) {
user.setUserName(value);
}
if("userAge".equals(name)) {
user.setUserAge(Integer.parseInt(value));
}
}else {
//多媒体组件
//获取客户端的文件名称
String fileName =item.getName();
String newFileName =UUID.randomUUID().toString();
//UUID保证名称不同 + 获取文件后面的.后缀
newFileName=newFileName+fileName.substring(fileName.lastIndexOf("."),fileName.length());
//获取到真实路径 d:tomacat/项目名/
String path=request.getRealPath("/");
path=path+"upload/";
File pathFile =new File(path);
//如果不存在就创建
if(!pathFile.exists()) {
pathFile.mkdir();
}
//客户端写入文件
item.write(new File(path+newFileName));
}
}
return "success";
}
注意:前端的from表单的enctype一定要是 multipart/from-date格式
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
问题
1.需要手动创建工厂并手动解析请求
2.非多媒体类型的请求 参数因为enctype的改变 ,导致传统的获取方式不能使用(即 request.parameter)
3.并且不能进行请求参数的封装
2.CommonsMultipartResolver
1.在spring中配置多媒体视图的解析器
2.MultipartFile 可以作为请求参数,根据名称会将多媒体组件封装在该类型的参数中
@ResponseBody
@PostMapping("/upload2")
//MultipartFile 可以作为请求参数 ,根据名称会将多媒体组件封装在该类型的参数中
//名字与前端的 file的name相同
public String testLoad2(MultipartFile cord ,User user,HttpServletRequest request,HttpServletResponse response) throws Exception {
String fileName =cord.getOriginalFilename();
String newFileName=UUID.randomUUID().toString();
newFileName=newFileName+fileName.substring(fileName.lastIndexOf("."),fileName.length());
String path=request.getRealPath("/");
path=path+"upload/";
File filePath=new File(path);
//如果不存在就进行创建
if(!filePath.exists()) {
filePath.mkdir();
}
//写入
cord.transferTo(new File(path+newFileName));
return "success";
}
3.多文件上传
多文件上传时,即使组件的名称和形参的名称一致,也需要增加@RequestParame
@ResponseBody
@PostMapping("/upload2")
//MultipartFile 可以作为请求参数 ,根据名称会将多媒体组件封装在该类型的参数中
//名字与前端的 file的name相同
public String testLoad2(@RequestBody(name="cords") MultipartFile[] cords ,User user,HttpServletRequest request,HttpServletResponse response) throws Exception {
for(MultipartFile cord:cords){
String fileName =cord.getOriginalFilename();
String newFileName=UUID.randomUUID().toString();
newFileName=newFileName+fileName.substring(fileName.lastIndexOf("."),fileName.length());
String path=request.getRealPath("/");
path=path+"upload/";
File filePath=new File(path);
//如果不存在就进行创建
if(!filePath.exists()) {
filePath.mkdir();
}
//写入
cord.transferTo(new File(path+newFileName));
}
return "success";
}
二、视图解析器
可以通过配置的形式手动的修改视图解析器,默认采用jstl的视图解析器,springboot可以通过配置使用thymealf
要求:jsp全部放在web-inf中
可以通过配置的形式手动的修改视图解析器,默认采用jstl的视图解析器,springboot可以通过配置使用thymealf
要求:jsp全部放在web-inf中
三、拦截器(拦截不了jsp页面)
拦截器(Interceptor),主要完成请求参数的解析、将页面表单参数赋值给值栈中响应的属性、执行功能检验、程序异常调试等工作
1 应用场景
拦截器(Interceptor),主要完成请求参数的解析、将页面表单参数赋值给值栈中响应的属性、执行功能检验、程序异常调试等工作
1.权限设置(filter)
2.性能监控(监控请求的执行时间和响应时间)
2 过滤器和拦截器的区别
- 过滤器是基于函数回调的,而拦截器基于java反射
- 过滤器可以过滤所有,拦截器只能拦截请求
- 过滤器在请求的声明周期中只能执行一次,而拦截器可以多次执行
- 过滤器依赖于servlet容器,而拦截器不依赖于servlet容器
- 过滤器无法获取请求值栈中的信息,拦截器可以获取(ModelAndView)
- 过滤器是基于函数回调的,而拦截器基于java反射
- 过滤器可以过滤所有,拦截器只能拦截请求
- 过滤器在请求的声明周期中只能执行一次,而拦截器可以多次执行
- 过滤器依赖于servlet容器,而拦截器不依赖于servlet容器
- 过滤器无法获取请求值栈中的信息,拦截器可以获取(ModelAndView)
其实不管是拦截器还是过滤器没什么大的区别,在条件允许的情况下,使用两者那个都可以
但是能使用拦截器的,不一定能使用过滤器(例如没有servlet容器的情况下,或者是计算响应时间等)
3步骤
3.1定义拦截器 实现HandlerInterceptor接口
package com.sofwin.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
//拦截器
public class UserInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("pre==========="+handler.getClass().getName());
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) {
System.out.println("postHandler。。。。。。。。"+modelAndView.getViewName());
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("afterComletion======");
}
}
3.2将拦截器交给spring管理
3.3 配置拦截器
返回指定子字符串(str)在此字符串(uri)中第一次出现处的索引。 如果此字符串中没有这样的字符出现,则返回 -1
// js是先判断是否有.
if(uri.indexOf("css")>-1||uri.indexOf("images")>-1||(uri.lastIndexOf(".")>-1)&&("js".equals(uri.substring(uri.lastIndexOf("."),uri.length())))) {
chain.doFilter(request, response);
}//登录页面 //验证码
else if(uri.indexOf("login.jsp")>-1) {
chain.doFilter(request, response);
}//登录请求
else if(uri.indexOf("LoginServlet")>-1) {
chain.doFilter(request, response);
}else if(user!=null) {
//登录过 进行放行
chain.doFilter(request, response);
}else {
//过滤请求
//响应登录页面 让用户进行登录 ---使用重定向 放在一直是别的界一直进行过滤
HttpServletResponse resp=(HttpServletResponse)response;
resp.sendRedirect(req.getContextPath()+"/login.jsp");
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}
package com.sofwin.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
//拦截器
public class UserInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("pre==========="+handler.getClass().getName());
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,ModelAndView modelAndView) {
System.out.println("postHandler。。。。。。。。"+modelAndView.getViewName());
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("afterComletion======");
}
}
3.2将拦截器交给spring管理
3.3 配置拦截器
返回指定子字符串(str)在此字符串(uri)中第一次出现处的索引。 如果此字符串中没有这样的字符出现,则返回 -1
// js是先判断是否有.
if(uri.indexOf("css")>-1||uri.indexOf("images")>-1||(uri.lastIndexOf(".")>-1)&&("js".equals(uri.substring(uri.lastIndexOf("."),uri.length())))) {
chain.doFilter(request, response);
}//登录页面 //验证码
else if(uri.indexOf("login.jsp")>-1) {
chain.doFilter(request, response);
}//登录请求
else if(uri.indexOf("LoginServlet")>-1) {
chain.doFilter(request, response);
}else if(user!=null) {
//登录过 进行放行
chain.doFilter(request, response);
}else {
//过滤请求
//响应登录页面 让用户进行登录 ---使用重定向 放在一直是别的界一直进行过滤
HttpServletResponse resp=(HttpServletResponse)response;
resp.sendRedirect(req.getContextPath()+"/login.jsp");
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}
返回指定子字符串(str)在此字符串(uri)中第一次出现处的索引。 如果此字符串中没有这样的字符出现,则返回 -1
// js是先判断是否有.
if(uri.indexOf("css")>-1||uri.indexOf("images")>-1||(uri.lastIndexOf(".")>-1)&&("js".equals(uri.substring(uri.lastIndexOf("."),uri.length())))) {
chain.doFilter(request, response);
}//登录页面 //验证码
else if(uri.indexOf("login.jsp")>-1) {
chain.doFilter(request, response);
}//登录请求
else if(uri.indexOf("LoginServlet")>-1) {
chain.doFilter(request, response);
}else if(user!=null) {
//登录过 进行放行
chain.doFilter(request, response);
}else {
//过滤请求
//响应登录页面 让用户进行登录 ---使用重定向 放在一直是别的界一直进行过滤
HttpServletResponse resp=(HttpServletResponse)response;
resp.sendRedirect(req.getContextPath()+"/login.jsp");
}
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}
7.不拦截静态资源(推荐使用)
如果前端控制器设置了静态资源进入,但是使用拦截器不设置,拦截器依旧会对静态资源进行拦截
因此我们设置如下进行静态资源的放行
8 应用场景的例子
1.权限设置(拦截器版本)
servlet 控制层
//访问 登录界面
@GetMapping("login")
public String testlogin() {
return "login";
}
//进行检查
@GetMapping("checklogin")
public String testlogin1(String userName,String password,HttpServletRequest request) {
if("zhangsan".equals(userName)&&"123".equals(password)) {
request.getSession().setAttribute("user", "user");
return "user/list";
}
return "login";
}
登录页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
登录成功页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
登录成功
配置文件
四、全局异常处理器
用来进行统一的异常处理===jsp中exception对象
当项目在运行过程中发生异常,会自动被定义的全局异常处理器接收,处理并响应对应的异常页面
注意:全局异常处理器只能处理服务器的异常。 客户端的异常处理不了
1.步骤
1.1 创建类 实现HandlerExceptionResolver接口
package com.sofwin.exception;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
@Component
//全局异常处理器 ---所有的异常全部抛出 由全局异常处理器来进行处理
public class ExceptionHandler implements HandlerExceptionResolver{
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) {
//因为有视图解析器 所以我们不用加jsp等
ModelAndView modelAndView =new ModelAndView("exception");
if(ex instanceof SofwinException) {
SofwinException sf=(SofwinException)ex;
modelAndView.addObject("msg",sf.getMsg());
modelAndView.addObject("cord",sf.getCord());
}
else {
modelAndView.addObject("msg","对不起,网络问题,请稍后访问");
modelAndView.addObject("cord","2222");
}
return modelAndView;
}
}
2.2 将类交给spring管理
package com.sofwin.exception;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
@Component
//全局异常处理器 ---所有的异常全部抛出 由全局异常处理器来进行处理
public class ExceptionHandler implements HandlerExceptionResolver{
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) {
//因为有视图解析器 所以我们不用加jsp等
ModelAndView modelAndView =new ModelAndView("exception");
if(ex instanceof SofwinException) {
SofwinException sf=(SofwinException)ex;
modelAndView.addObject("msg",sf.getMsg());
modelAndView.addObject("cord",sf.getCord());
}
else {
modelAndView.addObject("msg","对不起,网络问题,请稍后访问");
modelAndView.addObject("cord","2222");
}
return modelAndView;
}
}
2.2 将类交给spring管理
2.3 自定义异常
package com.sofwin.exception;
public class SofwinException extends Exception {
private String msg;
private String cord;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getCord() {
return cord;
}
public void setCord(String cord) {
this.cord = cord;
}
public SofwinException(String msg, String cord) {
this.msg = msg;
this.cord = cord;
}
public SofwinException() {
super();
}
}
2.4 方法中抛出异常
@ResponseBody
@GetMapping("ttt")
public String test66(Integer a, Integer b ) throws SofwinException {
if(b==0) {
throw new SofwinException("空指针", "111");
}
float res=a/b;
System.out.println("视图解析器");
return "www";
}
@ResponseBody
@GetMapping("ttt")
public String test66(Integer a, Integer b ) throws SofwinException {
if(b==0) {
throw new SofwinException("空指针", "111");
}
float res=a/b;
System.out.println("视图解析器");
return "www";
}
在可以预知的地方主动抛出异常
在不可预知的地方设置通用的提示



