SMM整合

 目录

1.表现层数据封装

总结

2.项目异常

项目异常分类 

 总结

3.放行静态资源

针对添加和删除等操作的细节描写.....

 4.拦截器

配置拦截器

拦截器链

 总结:除了拦截器的SSM项目,搭建具体流程。


 

 spring整合mybatis,使用Junit对service层做测试

1.表现层数据封装

前端拿到的数据

 等一下,我们就说假如啊?假如,我们增删改,后端不就是只给一个true或者false吗?但是查询是给一个封装好的json你对象,前端按照你的格式,去遍历数据,是不是格式种类多?所以,统一封装一个格式,对象,属性名data,

等一下,拿到code编码,根据编码号,判断返回错误或者失败,当然这是为了查询准备的,增删改bool值,完全没必要,但还是要封装到一起。meg错误信息,是为了查询返回的,表示查询失败。但还是要封装到一起的。

就是返回前端的数据,要统一一个格式。

包结构

 只是建议这样写

Result.java

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;
    }
}

我们是不是需要什么编码?来表明成功还是失败?

Code.java

编码随意,最好5为,结尾0表示失败,1表示成功。

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;

    public static final Integer EXCEPTION_ERR = 11111; 

}

总结

我们要将数据封装成一个具有data(数据),code(成功、错误编码),message(特殊消息),的一个对象(属性可扩展多个)的对象,返回给前端。

自定义一个Code类,封装错误成功编码。

2.项目异常

 异常处理器,如果后端服务器出现上述异常,我们要让他跟那些正常代码返回给前端的数据格式一致,所以也要设置一个异常处理器,来处理。

ProjectExceptionAdvice.java

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

项目异常分类 

 假如说,用户访问不同的网址,导致匹配不到正确的路径,然后产生异常,

区分异常种类,一般也就这两个常用的,业务异常(BusinessException),系统异常(SystemException),将我们捕获的异常,转换成我们自己定义的异常,抛出被SPringMvc捕获。

 下面

BusinessException.java

//自定义异常处理器,用于封装异常信息,对异常进行分类
public class BusinessException extends RuntimeException{

    private Integer code;

    public Integer getCode() {
        return code;
    }

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



    public BusinessException(String message) {
        super(message);
    }

    public BusinessException(Integer code,Throwable cause,String message) {
        super(message, cause); // 我们不是继承异常,Throwable,是Exception的父
        this.code = code;
    }

    public BusinessException( Integer code,String message) {
        super(message); // message,就是异常抛出的消息
        this.code = code;
    }


}

模拟异常抛出:

 将捕获java的异常转换成自定义异常,我觉得以后这个话,有可能也封装成一条常量吧,毕竟以后异常处理器是为了保证返回给前端的数据格式统一,就算出异常也是如此格式。但是自定义异常。感觉无所谓。

  try{
            int i = 1/0;
        }catch (Exception e){
           
            throw new SystemException(Code.SYSTEM_TIMEOUT_ERR,"服务器访问超时,请重试!",e);
        }

ProjectExceptionAdvice.java

//@RestControllerAdvice 用于标识当前类为REST风格对应的异常处理器
//@ControllerAdvice 用于表示当前类为异常处理器
@RestControllerAdvice
public class ProjectExceptionAdvice {
    //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.捕获其他异常
    @ExceptionHandler(Exception.class)
    public Result doOtherException(Exception ex){
        //记录日志
        //发送消息给运维
        //发送邮件给开发人员,ex对象发送给开发人员
        return new Result(Code.SYSTEM_UNKNOW_ERR,null,"系统繁忙,请稍后再试!");
    }
}


 

 总结

AOP小结:

说一下,我们不是学aop,不是有个环绕通知吗?他能能够拿到并原对象,并调用他。

我们可以用环绕通知,给所有方法,绑定。捕获异常,并封装成自定义异常抛出。

异常处理器作用:为了保证服务器出异常时,向前端返回的数据统一数据格式。

1.自定义异常 2.系统抛出异常 3.异常处理器捕获异常()        

3.放行静态资源

// 这个配置类,支持spring的扩展功能,当然也可以把他放在springConfig里,这样
@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/");
    }
}

针对添加和删除等操作的细节描写.....

提交表单?

我们点击提交之后,按照之前?特殊消息?状态码?成功?失败?将特殊消息拿过来?

编辑表单?

我们点击编辑之后,是不是要有这个数据,反显到表单里,那是不要根据id查询数据

然后,将数据填充到表单里。然后,编辑数据,将新的数据提交给后端。

 4.拦截器

跟过滤器,差不多只不过只是针对SpringMvc能镜像映射的路径来说,看来学到的SpringMvc中,mvc扩展功能,也就拦截器有点用,毕竟是针对动态逻辑的。

ProjectInterceptor.java

配置拦截器

1.定义拦截器

@Component
//定义拦截器类,实现HandlerInterceptor接口
//注意当前类必须受Spring容器控制
public class ProjectInterceptor implements HandlerInterceptor {
    @Override
    // 原始操作被拦截之前,执行的代码
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return true;
        // if return false,代表终止你原始操作。,也就是真真整的拦截你原始操作的执行。
    }

    @Override
    // 原始操作被拦截后执行的代码
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("postman......");
       
    }

    @Override
    //拦截之后执行的代码
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("执行方法后调用的内容......");
       
    }
}

2.配置拦截器被拦截那个路径,你这个配置类,被其他扫描上,也相当于连接在一起了,@CompentScan扫描之后,一个能和配置类和其他配置类能连接在一起,另外像是被@Service等标签,表上的不就是相当于new Bean()操作,?但前提是交给spring来管理也就是被springConfig配置文件扫描上。

SpringMvcSupport.java

@Configuration
// webMvc的扩展功能,
public class SpringMvcSupport extends WebMvcConfigurationSupport {
    @Autowired
    private ProjectInterceptor projectInterceptor;

    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        // 这个以后前后端分离就没用了...........
        // 拦截静态资源
        registry.addResourceHandler("/pages/**").addResourceLocations("/pages/");
    }

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(projectInterceptor).addPathPatterns("/books", "/books/*");
    }
}

 这tm就是个代理,在controller中实际又加上一个代理对象,可以参考aop的环绕通知来理解。

  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String contentType = request.getHeader("Content-Type");
        HandlerMethod hm = (HandlerMethod)handler;
        Method method = hm.getMethod();

        // 怎么理解封装这个概念,有些时候,按照参数输出类,也不一定是它本身的类,看他真正的类型,getClass(),毕竟每个对象有JVM给我们创建,但是真实数据类型你不知道。任何一个良好简装的程序私有属性,都是对应的get ,set方法。
        // Spring的半壁江山,IOC, = spring帮你new bean() ; AOP,通过spring 帮我们创建代理对象,来调用对应的方法。
        // springMvc,
        System.out.println("preHandle...222");
        return false;
    }

拦截器链

 

 其实拦截器链,我为什么想的是vip呢?

 总结:除了拦截器的SSM项目,搭建具体流程。

1.先变成Web项目,导入pom.xml坐标,(就算记住,考虑版本不匹配问题,建议写个博客,把基本框架需要坐标放进去)

2.建一个包架构,再建spring核心配置类,jdbc核心配置类,mybatis核心配置类,SpringMvc核心配置类,servlet核心配置类(tomcat,加载你这些关键配置文件),

3.一般就是做test测试之类的,做业务层的。(提示,可能出现的错误)

PS :发现了一个问题,我数据库设置表列的格式,跟前端要存入的数据,不满足我数据库的格式。他md,抛异常?

解决方法1:我通过aop,对前端的数据进行过滤格式化,保证正确性,其实挺傻逼的,前端也能过滤,只不过双重保险。

Cause: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'sex' at row 1

// 你想存入的数据太长了。

4.就是对controller层进行完善了,一般我们创建controller层,因为要保证向前端传输的数据格式是一致的,建一个Rusult类,将data,code,message...属性封装进去,建一个Code类,封装成功错误编码,ExceptionAdvice 异常捕获通知类,@RestControllerAdvice ,ProInterceptor 拦截器类

怎么说呢?异常通知类,就是捕获向上抛的异常的,我们可以在其他层捕获(绑定一个aop),按照异常类型划分,抛出不同的我们自定义异常,然后被异常处理器捕获。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

本郡主是喵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值