SpringBoot Web小进阶学习

一:Valid表单验证
作用:在参数(例如girl类)前添加注解 @Valid 表示对这个参数进行验证
而需要验证的条件则是写在参数中(girl中的年龄等属性),而验证结果则是由bindingResult对象返回:

实体类:

    @Min(value = 18,message = "此女生未成年")
    private Integer age;

更多限制属性注解:http://blog.java1234.com/blog/articles/336.html
(网上找的大佬总结)

Controller类:

    /**调用时直接可以传age和cupSize参数即可,valid验证实体类*/
    @PostMapping(value = "/girls")
    public girl insert(@Valid girl girl, BindingResult bindingResult){
        /**获取验证结果,如果有错误,输出错误*/
        if(bindingResult.hasErrors()){
        /**简单输出错误信息,可用枚举深入设置*/       System.out.println(bindingResult.getFieldError().getDefaultMessage());
            return null;
        }
        girl.setAge(girl.getAge());
        girl.setCupSize(girl.getCupSize());
        return girlJPA.save(girl);
    }

二:AOP处理请求
这里写图片描述

AOP这种程序设计思想不是只局限于Java,.net,c#等都有
而AOP的思想,在我看来就是,面向切面编程,意思就是将程序的公共逻辑代码提取出来构成一个切面

(tip:http请求发送到Controller中,由spirng容器注入的bean实例化的时候,因为程序启动之时,这些被注入的bean(类 )已经实例化了,所以不会执行我们Controller类里的构造方法)

/**maven导包*/
<dependency>
    <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

例如有一个场景,在Controller类中每个mapping业务需求都需要采集访问接口的ip地址、端口等信息,与其在每个mapping中写一样的逻辑代码,倒不如把这些逻辑看作一个公共部分,每个mapping都会走,直接单独提取出来(这里也可强调了代码的复用性和不冗余性),这时候AOP就起到了关键性的作用

具体操作:
1:定义一个单独的AOP类,类前添加注解 @Aspect和 @Component

2:因为逻辑有请求前的逻辑代码也有请求后的,所以有多个方法,也就是有多个注解(例如 @Before和 @After)
但是Before和After里我们如果都需要获取到前后的ip等信息作为对比呢,这时候直接的想法是两个方法都通过RequestContextHolder.getRequestAttributes().getRequest()获取到的httpServletRequest来得到,明显的,代码又重复了,本着有重复代码就优化的原则(这个原则蛮重要),我们可以在这里这么做
定义一个方法

//代表GirlController这个控制器里的方法都会被拦截并且在这里做出处理
    @Pointcut("execution(public * com.Controller.*(..))")
    //括号里表示Controller类里的所有方法(任何参数)都进行拦截
    public void log(){ [1] }
@Before("log()")

然后在注解里添加log()方法,@Pointcut就是切点注解了
而在[1]中也就可以做一些事了

三:统一异常处理

在公司实习的过程中,不难发现,后端大佬,都是在接口返回参数中,有一个统一的标准,例如这样:

{
    "success": true,
    "resultMessage": "",
    "resultCode": "0000",
    "result": []
}

json格式
这样的好处在于,当因为前后端分离时,前端人员拿到你这个接口,立马能清楚的知道返回信息而直接撸他的代码

所以这种统一的异常处理,讲真,现在不学,到了工作岗位,迟早要学,而且事半功倍,何乐而不为呢

所以这里也制定了下异常处理统一格式

{
“code”: 0,
“msg”: “”,
“data”: null
}

既然这样指定了格式,如果一个个参数的new然后传,未免显得很Low,肯定得创建一个Result类进行规范,而data方面因为参数类型千奇百怪,所以泛型肯定是要有的

public class Result<T> {

    /** 错误码.  */
    private int code;

    /** 提示信息.  */
    private String msg;

    /** 具体信息.  */
    private T data;

    //get和set方法略

这里提一个问题,如果让你判断一个女孩的年龄(写在service层),如果小于10岁上小学,大于10小于16上初中,这两个条件因为太小了直接pass然后直接返回信息,大于16岁有加钱等操作,这样该怎么做呢
如果单纯返回给Controller1、2、3这样的然后再在Controller方法中进行if判断,未免显得繁琐,所以这里我们需要统一异常判断

不过Exception在抛异常的时候只能返回message,所以如果要加入错误码code,需要写自己的Exception
(这里注意继承的是RuntimeException,因为如果继承Exception,spring框架只对RuntimeException抛出的异常进行回滚)

public class GirlException extends RuntimeException {

    private int code;

    public GirlException(ResultEnum resultEnum) {
        super(resultEnum.getMsg());
        this.code = resultEnum.getCode();
    }

    public int getCode() {
        return code;
    }

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

而抛出的异常中,错误码目前是我们自己定义的,比如
错误码code(例如100) ———对应—— 你可能还在上小学吧
这样到后期,等涉及的错误异常越来越多,非常不利于管理和记录,所以枚举是必不可少的

    public enum ResultEnum {
        UNKNOWN_ERROR(-1,"未知错误"),
        SUCCESS(100,"成功"),
        PRIMARY_SCHOOL(101,"你可能还在上小学吧"),
        MIDDLE_SCHOOL(102,"初中生吧"),
        PROPERTY_ERROR(103,"自定义")
        ;

        private int code;

    private String msg;

    ResultEnum(int code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }
}

调用时直接ResultEnum.PRIMARY_SCHOOL表示括号里的内容,而ResultEnum.PROPERTY_ERROR.getCode()表示具体的code

四:单元测试

Idea 单元测试可以直接右键方法选择Go To –> Test –> 创建一个Test
然后编写单元测试 右键Run
不过进行单元测试的类上要添加注解 @RunWith(SpringRunner.class) 和 @SpringBootTest

特殊的对api(Controller类)进行测试时,
使用三个注解 @RunWith(SpringRunner.class)
@SpringBootTest @AutoConfigureMockMvc

@Autowired

    private MockMvc mvc;

    @Test
    public void getGirls() throws Exception {
        mvc.perform(MockMvcRequestBuilders.get("/girls"))
                .andExpect(MockMvcResultMatchers.status().isOk());
        //判断以get方式对girls这个路径返回的status进行测试
    }   
发布了12 篇原创文章 · 获赞 1 · 访问量 3649
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览