SpringMVC-异常解析器&拦截器&跨域请求文件上传与下载
SpringMVC 07 -异常解析器&拦截器&跨域请求
1 异常解析器
1.1 异常解析器,统一处理
Controller中的抛出需要集中处理的异常。
定义一个“异常解析器” 集中捕获处理 所有异常
此种方案,在集中管理异常方面,更有优势!
定义统一异常处理类
- @param httpServletRequest request对象
- @param httpServletResponse response对象
- @param o 出现异常的Controller对象
- @param e 异常
@Component
public class MyHandlerExceptionResolver implements HandlerExceptionResolver {
/**
*
* @param httpServletRequest request对象
* @param httpServletResponse response对象
* @param o 出现异常的Controller对象
* @param e 异常
* @return
*/
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
Object o,
Exception e) {
//1、可以通过异常的类型,来做出不同处理
// if(e instanceof LongException){
// modelAndView.setViewName("error");
// }else if(e instanceof OrderException){
// modelAndView.setViewName("error");
// }else if(e instanceof PayException){
// modelAndView.setViewName("error");
// }
//2、前端分离项目。通过响应流进行进行响应
//httpServletResponse.getWriter().write(json)
ModelAndView modelAndView = new ModelAndView();
modelAndView.setViewName("error");
//打印异常信息
e.printStackTrace();
return modelAndView;
}
}
注意:如果在Controller中对异常进行了处理,则不会进入异常处理解析器中
2 拦截器
2.1 作用
作用:抽取handler中的冗余功能,类似于过滤器
2.2 定义拦截器
执行顺序: preHandle–postHandle–afterCompletion
public class LoginInterceptor implements HandlerInterceptor { //AOP
@Override
public boolean preHandle(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler) throws Exception {
System.out.println("进入到Handler之前执行【进行拦截操作】");
HttpSession session = request.getSession();
Object loginUser = session.getAttribute("loginUser");
if(loginUser == null){
response.sendRedirect(request.getContextPath()+"/pages/login.jsp");
return false;
}
return true; //是否放行 false表示不放行 true放行
}
@Override
public void postHandle(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("进入到Handler之后执行【进行后续操作】");
}
@Override
public void afterCompletion(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("当请求成功之后数据渲染完成执行【资源释放】");
}
}
2.3 配置拦截路径
SpringMVC拦截器配置
- 可以设置多个拦截器,顺序有关系,从前往后依次过滤
- 设置拦截的路径 (可以设置多个) /* 只能拦截/下的路径,不能拦截子路径 /**表示所有请求
<!-- SpringMVC拦截器配置(可以设置多个拦截器,顺序有关系,从前往后依次过滤)-->
<mvc:interceptors>
<mvc:interceptor>
<!-- 设置拦截的路径 (可以设置多个) /* 只能拦截/下的路径,不能拦截子路径 /**表示所有请求 -->
<mvc:mapping path="/**"/>
<!-- 排除拦截的路径 (可以设置多个) -->
<mvc:exclude-mapping path="/user/login"/>
<bean class="com.ying.controller.LoginInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
3 跨域请求
3.1 域
域:协议+IP+端口
http://localhost:8989
http://localhost:8080
http://www.baidu.com:80
3.2 Ajax跨域问题
Ajax发送请求时,不允许跨域,以防用户信息泄露。
当Ajax跨域请求时,响应会被浏览器拦截(同源策略),并报错。即浏览器默认不允许ajax跨域得到响应内容。
互相信任的域之间如果需要ajax访问,(比如前后端分离项目中,前端项目和后端项目之间),则需要额外的设置才可正常请求。
3.3 解决方案
3.3.1 CORS配置
- 允许其他域访问
- 在被访问方的Controller类或者方法上,添加注解
- origins:表示指定的来源(如果不写表示任何来源)
- maxAge :表示缓存的有效时间 (以秒为单位)
@CrossOrigin("http://127.0.0.1:8848") //允许此域发请求访问
public class TestController {
....
}
3.3.1 设置允许携带Cookie
- 携带对方cookie,使得session可用
- 在访问方,ajax中添加属性:withCredentials: true
$.ajax({
type: "POST",
url: "http://localhost:8989/web/sys/login",
...,
xhrFields: {
// 跨域携带cookie
withCredentials: true
}
});
注意:在Chrome浏览器上不允许跨域携带cookie,后续可以使用Nginx解决跨域问题