项目管理与SSM框架 SpringMVC(五)

本文涉及的产品
.cn 域名,1个 12个月
简介: 项目管理与SSM框架 SpringMVC(五)

六、SpringMVC异常处理

6.1 单个控制器异常处理

在系统当中, Dao、Service、Controller层代码出现都可能抛出异常。如果哪里产生异常就在哪里处理,则会降低开发效率。所以一般情况下我们会让异常向上抛出,最终到达DispatcherServlet中,此时SpringMVC提供了异常处理器进行异常处理,这样可以提高开发效率。

1、处理异常的控制器

//异常处理方法,添加@ExceptionHandler注解表示该方法是处理异常的方法,属性为处理的异常类。
    //Exception:异常对象。Model:数据模型
    @ExceptionHandler(java.lang.NullPointerException.class)
    public String exceptionHandler(Exception exception,Model model){
        //模型中添加异常对象
        model.addAttribute("msg",exception);
        //跳转到异常页面
        return "error";
    }

2、前端异常页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>异常</title>
</head>
<body>
出错了!${requestScope.msg}
</body>
</html>


6.2 全局异常处理

在控制器中定义异常处理方法只能处理该控制器类的异常,要想处理所有控制器的异常,需要定义全局异常处理类。

package com.zj.controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
//全局异常处理器处理所有控制器的异常,需要添加@ControllerAdvice注解
@ControllerAdvice
public class GlobalExceptionHandler {
    //异常处理方法,添加@ExceptionHandler注解表示该方法是处理异常的方法,属性为处理的异常类。
    //Exception:异常对象。Model:数据模型
    @ExceptionHandler(java.lang.NullPointerException.class)
    public String exceptionHandler(Exception exception, Model model){
        //模型中添加异常对象
        model.addAttribute("msg",exception);
        //跳转到异常页面
        return "error";
    }
}

6.3 自定义异常

以上方式都是使用的SpringMVC自带的异常处理器进行异常处理,我们还可以自定义异常处理器处理异常:

package com.zj.controller;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
// 自定义异常处理器实现HandlerExceptionResolver接口,并放入Spring容器中
@Component
public class MyExceptionHandler implements HandlerExceptionResolver {
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        ModelAndView modelAndView = new ModelAndView();
        if (e instanceof NullPointerException) {
            modelAndView.setViewName("error");
        } else {
            modelAndView.setViewName("error2");
        }
        modelAndView.addObject("msg", e);
        return modelAndView;
    }
}

七、SpringMVC拦截器

7.1 拦截器简介

SpringMVC的拦截器(Interceptor)也是AOP思想的一种实现方式。它与Servlet的过滤器(Filter)功能类似,主要用于拦截用户的请求并做相应的处理,通常应用在权限验证、记录请求信息的日志、判断用户是否登录等功能上。

拦截器和过滤器的区别

  • 拦截器是SpringMVC组件,而过滤器是Servlet组件。
  • 拦截器不依赖Web容器,过滤器依赖Web容器。
  • 拦截器只能对控制器请求起作用(不拦截静态资源),而过滤器则可以对所有的请求起作用。
  • 拦截器可以直接获取IOC容器中的对象,而过滤器就不太方便获取。

7.2 拦截器使用

1、创建控制器方法

@RequestMapping("/m1")
    public String m1(){
        System.out.println("控制器方法");
        return "result";
    }

2、创建拦截器类,该类实现HandlerInterceptor接口,需要重写三个方法:

  • preHandle:请求到达Controller前执行的方法,返回值为true通过拦截器,返回值为false被拦截器拦截。
  • postHandle:跳转到JSP前执行的方法
  • afterCompletion:跳转到JSP后执行的方法
package com.zj.controller;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor implements HandlerInterceptor {
    // 请求到达Controller前执行,此时可以向request域添加数据。
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("请求到达Controller之前");
        // 如果return false则无法到达Controller
        return true;
    }
    // 跳转到JSP前执行,此时可以向Request域添加数据
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        request.setAttribute("name","张三");
        System.out.println("请求跳转到JSP前");
    }
    // 跳转到JSP后执行,此时已经不能向Request域添加数据
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("请求跳转到JSP后");
    }
}

3、在SpringMVC核心配置文件中配置拦截器

<!--拦截器-->
<mvc:interceptors>
    <mvc:interceptor>
        <!--配置拦截器的作用对象-->
        <mvc:mapping path="/**"/>
        <!--配置拦截器对象-->
       <bean class="com.zj.controller.MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

4、JSP页面

<html>
<body>
<h2>Hello, ${requestScope.name}</h2>
</body>
</html>


7.3 全局拦截器

全局拦截器可以拦截所有控制器处理的URL,作用等于/**,配置方式如下:

<!-- 配置拦截器 -->
<mvc:interceptors>  
  <!-- 全局拦截器 -->  
  <bean class="com.zj.interceptor.MyInterceptor">
  </bean>
</mvc:interceptors>

7.4 拦截器链与执行顺序

如果一个URL能够被多个拦截器所拦截,全局拦截器最先执行,其他拦截器根据配置文件中配置的从上到下执行,接下来我们再配置一个拦截器:

<!--拦截器-->
<mvc:interceptors>
    <!--拦截器1-->
    <mvc:interceptor>
        <!--配置拦截器的作用对象-->
        <mvc:mapping path="/**"/>
        <!--配置拦截器对象-->
        <bean class="com.zj.Interceptor.MyInterceptor"/>
    </mvc:interceptor>
    <!--拦截器2-->
    <mvc:interceptor>
        <!--配置拦截器的作用对象-->
        <mvc:mapping path="/**"/>
        <!--配置拦截器对象-->
        <bean class="com.zj.Interceptor.MyInterceptor2"/>
    </mvc:interceptor>
</mvc:interceptors>

结论:

  1. preHandle()顺序执行,postHandle()、afterComletion()逆序执行。
  2. 只要有一个preHandle()拦截,后面的preHandle(),postHandle()都不会执行。
  3. 只要相应的preHandle()放行,afterComletion()就会执行。

7.5 拦截器过滤敏感词案例

在系统中,我们需要将所有响应中的一些敏感词替换为***,此时可以使用拦截器达到要求:

1、写控制器方法

@RequestMapping("/m2")
public String m2(Model model){
  model.addAttribute("name","大笨蛋");
  return "index";
}

2、编写敏感词拦截器

package com.zj.Interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import java.util.Set;
// 敏感词拦截器
public class SensitiveWordInterceptor implements HandlerInterceptor {
  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws UnsupportedEncodingException {
    request.setCharacterEncoding("UTF-8");
    response.setContentType("text/plain;charset=UTF-8");
      return true;
   }
  @Override
  public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
    // 敏感词列表
    String[] sensitiveWords = {"坏人","暴力","笨蛋"};
    // 获取model中所有数据
    Map<String, Object> model = modelAndView.getModel();
    Set<Map.Entry<String, Object>> entries = model.entrySet();
    // 遍历model
    for (Map.Entry<String, Object> entry : entries) {
      String key = entry.getKey();
      String value = entry.getValue().toString();
      // 将model值和敏感词列表遍历比对
      for (String sensitiveWord : sensitiveWords) {
        // 如果model值包含敏感词,则替换
        if(value.contains(sensitiveWord)){
          String newStr = value.replaceAll(sensitiveWord, "**");
          model.put(key, newStr);
         }
       }
     }
   }
}

3、配置拦截器

<!-- 配置拦截器-->
<mvc:interceptors>
  <!-- 敏感词拦截器 -->
  <mvc:interceptor>
    <mvc:mapping path="/**"/>
    <bean class="com.zj.interceptor.SensitiveWordInterceptor"></bean>
  </mvc:interceptor>
</mvc:interceptors>

4、访问


八、SpringMVC跨域请求

8.1 同源策略

同源策略是浏览器的一个安全功能。同源,指的是两个URL的协议,域名,端口相同。浏览器出于安全方面的考虑,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。

哪些不受同源策略限制:

  1. 页面中的<a>跳转、表单提交不会受到同源策略限制的。
  2. 静态资源引入也不会受到同源策略限制。如嵌入到页面中的<script src=""><img src=""><link href="">等。

最容易收到同源策略影响的就是Ajax请求。

8.2 跨域请求

当请求URL的协议、域名、端口三者中任意一个与当前页面URL不同时即为跨域。浏览器执行JavaScript脚本时,会检查当前请求是否同源,如果不是同源资源,就不会被执行。

当前页面URL 被请求页面URL 是否跨域 原因
http://www.baidu.com/ http://www.baidu.com/index.html
http://www.baidu.com/ https://www.baidu.com/index.html 跨域 协议不同
http://www.baidu.com/ http://www.jd.com/ 跨域 主域名不同
http://www.baidu.com/ http://jd.jd.com/ 跨域 子域名不同
http://www.baidu.com:8080/ http://www.baidu.com:7001/ 跨域 端口号不同

8.3 控制器接收跨域请求

SpringMVC提供了注解@CrossOrigin解决跨域问题。用法如下:

@RequestMapping("/m3")
@ResponseBody
// 如果请求从http://localhost:8080发出,则允许跨域访问
@CrossOrigin("http://localhost:8080")
public String m3(){
  System.out.println("测试跨域请求");
  return "success";
}


相关文章
|
3月前
|
Java 数据库连接 Maven
手把手教你如何搭建SSM框架、图书商城系统案例
这篇文章是关于如何搭建SSM框架以及实现一个图书商城系统的详细教程,包括了项目的配置文件整合、依赖管理、项目结构和运行效果展示,并提供了GitHub源码链接。
手把手教你如何搭建SSM框架、图书商城系统案例
|
1月前
|
JSON 前端开发 Java
SSM:SpringMVC
本文介绍了SpringMVC的依赖配置、请求参数处理、注解开发、JSON处理、拦截器、文件上传下载以及相关注意事项。首先,需要在`pom.xml`中添加必要的依赖,包括Servlet、JSTL、Spring Web MVC等。接着,在`web.xml`中配置DispatcherServlet,并设置Spring MVC的相关配置,如组件扫描、默认Servlet处理器等。然后,通过`@RequestMapping`等注解处理请求参数,使用`@ResponseBody`返回JSON数据。此外,还介绍了如何创建和配置拦截器、文件上传下载的功能,并强调了JSP文件的放置位置,避免404错误。
|
1月前
|
前端开发 Java 应用服务中间件
【Spring】Spring MVC的项目准备和连接建立
【Spring】Spring MVC的项目准备和连接建立
53 2
|
2月前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
|
1月前
|
XML 前端开发 Java
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
本文阐述了Spring、Spring Boot和Spring MVC的关系与区别,指出Spring是一个轻量级、一站式、模块化的应用程序开发框架,Spring MVC是Spring的一个子框架,专注于Web应用和网络接口开发,而Spring Boot则是对Spring的封装,用于简化Spring应用的开发。
109 0
Spring,SpringBoot和SpringMVC的关系以及区别 —— 超准确,可当面试题!!!也可供零基础学习
|
2月前
|
XML 缓存 前端开发
springMVC02,restful风格,请求转发和重定向
文章介绍了RESTful风格的基本概念和特点,并展示了如何使用SpringMVC实现RESTful风格的请求处理。同时,文章还讨论了SpringMVC中的请求转发和重定向的实现方式,并通过具体代码示例进行了说明。
springMVC02,restful风格,请求转发和重定向
|
3月前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
|
3月前
|
XML JSON 数据库
SpringMVC入门到实战------七、RESTful的详细介绍和使用 具体代码案例分析(一)
这篇文章详细介绍了RESTful的概念、实现方式,以及如何在SpringMVC中使用HiddenHttpMethodFilter来处理PUT和DELETE请求,并通过具体代码案例分析了RESTful的使用。
SpringMVC入门到实战------七、RESTful的详细介绍和使用 具体代码案例分析(一)
|
3月前
|
Java 数据库连接 Maven
SSM框架整合图书管理项目
这篇文章是关于SSM框架整合到图书管理项目的详细教程,涵盖了从Maven项目构建、依赖导入、数据库连接、配置文件编写、实体类和接口实现到SpringMVC整合的完整步骤。
SSM框架整合图书管理项目
|
2月前
|
XML Java 数据库连接
如何搭建SSM框架、图书商城系统
这是一份详尽的《Spring + SpringMVC + Mybatis 整合指南》,作者耗时良久整理出约五万字的内容,现已经全部笔记公开。此文档详细地介绍了如何搭建与整合SSM框架,具体步骤包括创建Maven项目、添加web骨架、配置pom文件以及整合Spring、SpringMVC和Mybatis等。无论是对初学者还是有一定基础的开发者来说,都是很好的学习资源。此外,作者还提供了项目源码的GitHub链接,方便读者实践。虽然当前主流推荐学习SpringBoot,但了解SSM框架仍然是不可或缺的基础。
34 0