SSM整合归纳

SSM开发基本规范

  • 表现层数据的封装
  • 异常处理类
  • 项目异常处理方案

image-20231002222806460

image-20231002223056307

 

idea中自动装配的时候对bean类型做检测系统会爆红但是我们只要修改就可以了

image-20231002225318515

image-20231002225342935

1. 表现层数据封装(统一返回结果)

前端已经疯了 格式不统一

  • 前端接收数据格式统一创建结果模型类,封装数据到data属性中

image-20231003001529211

public class Result {
    private Object data;
    private Integer code;
    private String msg;

    public Result() {
    }

    public Result(Integer code,Object data) {
        this.data = data;
        this.code = code;
    }

    public Result(Integer code, Object data, String msg) {
        this.data = data;
        this.code = code;
        this.msg = msg;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

前端接收数据格式统一创建结果模型类,封装数据到data属性中

约定好code

public class Code {
    public static final Integer SAVE_OK = 20011;
    public static final Integer DELETE_OK = 20021;
    public static final Integer UPDATE_OK = 20031;
    public static final Integer GET_OK = 20041;

    public static final Integer SAVE_ERR = 20010;
    public static final Integer DELETE_ERR = 20020;
    public static final Integer UPDATE_ERR = 20030;
    public static final Integer GET_ERR = 20040;

    public static final Integer SYSTEM_ERR = 50001;
    public static final Integer SYSTEM_TIMEOUT_ERR = 50002;
    public static final Integer SYSTEM_UNKNOW_ERR = 59999;

    public static final Integer BUSINESS_ERR = 60002;

}

image-20231003001802780

他妈的还是会有问题

查询的数据不存在 又要一起约定修改

就是数据不存在还要告诉用户一声,不能一句话不说

还要封装message

  • 设置统一数据返回结果类
    • 自己定义格式不固定 还可以提供构造方法

image-20231003002232653

image-20231003005821895

image-20231003005906575

设置code 异常代码(常量)

package com.itheima.controller;

//状态码  (常量)
public class Code {
    public static final Integer SAVE_OK = 20011;
    public static final Integer DELETE_OK = 20021;
    public static final Integer UPDATE_OK = 20031;
    public static final Integer GET_OK = 20041;

    public static final Integer SAVE_ERR = 20010;
    public static final Integer DELETE_ERR = 20020;
    public static final Integer UPDATE_ERR = 20030;
    public static final Integer GET_ERR = 20040;
}

result 表现层数据封装

package com.itheima.controller;

public class Result {
    //描述统一格式中的数据
    private Object data;   //必须是Object
    //描述统一格式中的编码,用于区分操作,可以简化配置0或1表示成功失败
    private Integer code;
    //描述统一格式中的消息,可选属性
    private String msg;
    //空参
    public Result() {
    }
    // code data  构造方法
    public Result(Integer code,Object data) {
        this.data = data;
        this.code = code;
    }
    // code data msg 构造方法
    public Result(Integer code, Object data, String msg) {
        this.data = data;
        this.code = code;
        this.msg = msg;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

AOP思想的运用:

image-20231008095851983

有这么多的异常我们该怎么处理?

解决方案:

全部抛到 表现层 来处理异常

所有的异常均抛出到表现层进行处理

集中的统一处理项目中出现的异常

之前存在的问题:

  1. 把异常均抛出到表现层处理:代码书写量大且意义不强
  2. 我们不可能每个异常处理都一样 所以我们要分类处理,但是还是会存在问题 不能用try catch写

解决方案:AOP

AOP的思想但是我们不用写AOP

image-20231008100217907


2. 异常处理器

按照他的格式来进行编写

image-20231003144929650


@RestControllerAdvice 声明做异常处理的

声明做异常处理的

为Rest风格开发的控制器类做增强

image-20231003145736831

@RestControllerAdvice用于标识当前类为REST风格对应的异常处理器
@ExceptionHandler用于设置当前处理器类对应的异常类型
//@RestControllerAdvice用于标识当前类为REST风格对应的异常处理器
@RestControllerAdvice
public class ProjectExceptionAdvice {
    //@ExceptionHandler用于设置当前处理器类对应的异常类型
    //1. 处理系统异常
    @ExceptionHandler(SystemException.class)
    public Result doSystemException(SystemException ex){
        //记录日志
        //发送消息给运维
        //发送邮件给开发人员,ex对象发送给开发人员
        return new Result(ex.getCode(),null,ex.getMessage());
    }
    //2. 处理业务异常
    @ExceptionHandler(BusinessException.class)
    public Result doBusinessException(BusinessException ex){
        return new Result(ex.getCode(),null,ex.getMessage());
    }

    //3. 除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常
    @ExceptionHandler(Exception.class)
    public Result doOtherException(Exception ex){
        //记录日志
        //发送消息给运维
        //发送邮件给开发人员,ex对象发送给开发人员
        return new Result(Code.SYSTEM_UNKNOW_ERR,null,"系统繁忙,请稍后再试!");
    }
}

@ExceptionHandler 声明处理异常的种类

专门用来拦截异常的 声明处理异常的种类

之前存在的问题:不规范的用户行为操作产生的异常

image-20231003145752139

( )定义用来处理哪一种类型的异常

@RestControllerAdvice
public class ProjectExceptionAdvice {
    @ExceptionHandler(SystemException.class)
    public Result doSystemException(SystemException ex){
        //记录日志
        //发送消息给运维
        //发送邮件给开发人员,ex对象发送给开发人员
        return new Result(ex.getCode(),null,ex.getMessage());
    }

    @ExceptionHandler(BusinessException.class)
    public Result doBusinessException(BusinessException ex){
        return new Result(ex.getCode(),null,ex.getMessage());
    }

    @ExceptionHandler(Exception.class)
    public Result doOtherException(Exception ex){
        //记录日志
        //发送消息给运维
        //发送邮件给开发人员,ex对象发送给开发人员
        return new Result(Code.SYSTEM_UNKNOW_ERR,null,"系统繁忙,请稍后再试!");
    }
}

3. 项目异常处理方案

  • 异常处理器
  • 自定义异常
  • 异常编码
  • 自定义消息

image-20231003150528895

  1. 业务异常
  2. 系统异常
  3. 其他异常

怎么做?

image-20231003150636339

项目异常处理

1)自定义项目系统级异常

image-20231008102449845

image-20231008102529964

image-20231003152724289

//先继承 运行时异常(他会把异常自动向上抛出)
public class SystemException extends RuntimeException{
    private Integer code;

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public SystemException(Integer code, String message) {
        super(message);
        this.code = code;
    }

    public SystemException(Integer code, String message, Throwable cause) {
        super(message, cause);
        this.code = code;
    }

}

2)自定义项目业务级异常

image-20231003152749010

public class BusinessException extends RuntimeException{
    private Integer code;

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public BusinessException(Integer code, String message) {
        super(message);
        this.code = code;
    }

    public BusinessException(Integer code, String message, Throwable cause) {
        super(message, cause);
        this.code = code;
    }

}

3)自定义异常编码

image-20231003152817274

4)模拟业务异常

image-20231003152948852

image-20231008103114793

5)拦截并处理异常

image-20231003153028808

用构造方法把code data 传过去的值 会被异常处理类去接收

image-20231008103416268

//@RestControllerAdvice用于标识当前类为REST风格对应的异常处理器
@RestControllerAdvice
public class ProjectExceptionAdvice {
    //@ExceptionHandler用于设置当前处理器类对应的异常类型
    //1. 处理系统异常
    @ExceptionHandler(SystemException.class)
    public Result doSystemException(SystemException ex){
        //记录日志
        //发送消息给运维
        //发送邮件给开发人员,ex对象发送给开发人员
        return new Result(ex.getCode(),null,ex.getMessage());
    }
    //2. 处理业务异常
    @ExceptionHandler(BusinessException.class)
    public Result doBusinessException(BusinessException ex){
        return new Result(ex.getCode(),null,ex.getMessage());
    }

    //3. 除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常
    @ExceptionHandler(Exception.class)
    public Result doOtherException(Exception ex){
        //记录日志
        //发送消息给运维
        //发送邮件给开发人员,ex对象发送给开发人员
        return new Result(Code.SYSTEM_UNKNOW_ERR,null,"系统繁忙,请稍后再试!");
    }
}

6)异常处理效果对比

image-20231003153150128

4. 全局异常处理器(瑞吉)

@ControllerAdvice

package com.itheima.reggie.common;

import lombok.extern.java.Log;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.sql.SQLIntegrityConstraintViolationException;

/**
 * 全局异常处理
 */
@ControllerAdvice(annotations = {RestController.class, ControllerAdvice.class})
@ResponseBody//方法返回的是JSON数据最终  封装成JSON数据并且返回
@Slf4j
public class GlobalExceptionHandler {
    /**
     * 异常处理方法 处理的是关于这个的异常SQLIntegrityConstraintViolationException
     * @return
     */
    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)
    public R<String> exceptionHandler(SQLIntegrityConstraintViolationException ex) {
        log.error(ex.getMessage());

        if (ex.getMessage().contains("Duplicate entry")){
            String[] split = ex.getMessage().split(" ");
            String msg = split[2]+"已存在";
            return R.error(msg);

        }
        return R.error("未知错误");
    }

    /**
     * 自定义异常处理
     * @param ex
     * @return
     */
    //TODO 在全局异常处理器中去处理自己的异常
    @ExceptionHandler(CustomException.class)
    public R<String> exceptionHandler(CustomException ex) {
        log.error(ex.getMessage());

        return R.error(ex.getMessage());
    }

}

这里是设置了自定义异常处理

在项目中自定义一个全局异常处理器,在异常处理器上加上注解 @ControllerAdvice,可以通过属性annotations指定拦截哪一类的Controller方法。 并在异常处理器的方法上加上注解 @ExceptionHandler 来指定拦截的是那一类型的异常。

image-20231009224248409

WebMvcConfigurationSupport

@Configuration                      //
public class SpringMvcSupport extends WebMvcConfigurationSupport {
   /* @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
        registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
    }*/

    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
        registry.addResourceHandler("/css/**").addResourceLocations("/css/");
        registry.addResourceHandler("/js/**").addResourceLocations("/js/");
        registry.addResourceHandler("/plugins/**").addResourceLocations("/plugins/");
    }
}

image-20231003153528711

image-20231003153612000

前端

image-20231003154027016


SSM整合标准开发(了解)

image-20231003154854153

5. 拦截器(Interceptor)

  • 概念:是一种动态拦截的方法机制,在SpringMVC中动态拦截控制器方法的执行 拦截方法的调用
  • 作用:
    • 在指定的方法调用前后执行预先设定的代码(功能)
    • 阻止原始方法的执行

简单的说:

拦截器只能对SpringMVC的访问进行增强

可以在控制器之前 或者之后执行

image-20231029181213516


image-20231003155539854


拦截器与过滤器区别

  • 归属不同:Filter属于Servlet技术,Interceptor属于SpringMVC的激素和
  • 拦截内容不同:拦截器Interceptor仅针对SpringMVC的访问进行增强,Filter对所有访问进行增强

制作拦截器

  • 制作拦截器的功能类
  • 配置拦截器的执行位置

创建一个interceptor包书写类 一般设置在controller中

实现HandlerInterceptor接口 然后覆盖三个方法 alt+insert override Methods

类:ProjectInterceptor

HandlerInterceptor

先去实现HandlerInterceptor接口

image-20231029182159335

再去重写这三个方法

image-20231029182251392

@Component: 因为拦截器是为SpringMVC服务的,SpringMVC的环境需要加载到它 受SpringMVC的管理

@Component
//定义拦截器类,实现HandlerInterceptor接口
//注意当前类必须受Spring容器控制
public class ProjectInterceptor implements HandlerInterceptor {
    @Override
    //原始方法调用前执行的内容
    //返回值类型可以拦截控制的执行,true放行,false终止
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String contentType = request.getHeader("Content-Type");
        HandlerMethod hm = (HandlerMethod)handler;
        System.out.println("preHandle...111"+contentType);
        return true;
    }

    @Override
    //原始方法调用后执行的内容
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle...111");
    }

    @Override
    //原始方法调用完成后执行的内容
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("afterCompletion...111");
    }
}

WebMvcConfigurationSupport 过滤访问资源

在继承WebMvcConfigurationSupport的类中 注入拦截器

addResourceHandlers

**addResourceHandlers (拦截器对象) 这里需要@Autowired注入拦截器 过滤访问的静态资源 **

如果return false;表示终止原始操作的运行

@Configuration //配置成为一个bean
public class SpringMvcSupport extends WebMvcConfigurationSupport {
    @Autowired
    //注入拦截器  projectInterceptor
    private ProjectInterceptor projectInterceptor;

    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
    }

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        //配置拦截器  访问books的时候拦截
        registry.addInterceptor(projectInterceptor).addPathPatterns("/books","/books/*");
    }
}

步骤:

  1. 声明bena实现HandlerInterceptor接口
  2. 定义配置类,继承WebMvcConifgurationSupport实现addInterceptor方法(扫描加载配置)
  3. **添加具体的拦截器并设定拦截器的访问路径,路径可以通过可变参数设置多个 ** 设置哪个具体的拦截器 拦截什么请求
  4. 使用标准接口WebMvcConfigurer简化开发

1.声明bena实现HandlerInterceptor接口

image-20231003161852516

2.定义配置类,继承WebMvcConifgurationSupport实现addInterceptor方法(扫描加载配置)

image-20231003161834940

3.添加拦截器并设定拦截器的访问路径,路径可以通过可变参数设置多个

image-20231003162011850

**4.使用标准接口WebMvcConfigurer简化开发 **

image-20231003162053724


拦截器执行流程

image-20231003162139960


拦截器参数

前置处理

image-20231003162205940

后置处理

image-20231003162215416


拦截器链

image-20231003162307538

总结:

image-20231003162329671

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值