前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Boot 进阶之 Web 进阶笔记

Spring Boot 进阶之 Web 进阶笔记

作者头像
solocoder
发布2022-04-06 12:53:09
2030
发布2022-04-06 12:53:09
举报
文章被收录于专栏:大前端客栈

一、表单验证

改造 Girl 对象,给 age 字段加校验最小值为18,并给出错误提示。

代码语言:javascript
复制
@Entity
public class Girl {

@Id
@GeneratedValue
private Integer id;

private String cupSize;

@M<span class="hljs-keyword">in</span>(value = 18, message = <span class="hljs-string">"未成年少女禁止入内"</span>)
private Integer age;

public <span class="hljs-function"><span class="hljs-title">Girl</span></span>() {
}

//getter、setter 方法省略

}

相应的 Controller 方法,用 Girl 对象接收传递过来的参数,并加上 @Validated 注解。BindingResult 用来接收错误信息

代码语言:javascript
复制
@PostMapping(value = "/girl/add")
public Girl add(@Validated Girl girl, BindingResult bindingResult) {
    if(bindingResult.hasErrors()){
        System.out.println(bindingResult.getFieldError().getDefaultMessage());
        return null;
    }
    return repository.save(girl);
}

如果传递的 age 小于 18,则会报错。

注意:@NotNull 和 @NotEmpty 和@NotBlank 区别 @NotEmpty 用在集合类上面 @NotBlank 用在String上面 @NotNull 用在基本类型上

二、使用 AOP 处理请求

先在 pom.xml 文件中添加 AOP 依赖

代码语言:javascript
复制
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

新建 HttpAspect.java

代码语言:javascript
复制
package com.solo.test01.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
@Aspect
@Component
public class HttpAspect {
private static final Logger logger = LoggerFactory.getLogger(HttpAspect.class);

//指定切点
@Pointcut(<span class="hljs-string">"execution(public * com.solo.test01.controller.GirlController.*(..))"</span>)
public void <span class="hljs-function"><span class="hljs-title">log</span></span>() {

}

@Before(<span class="hljs-string">"log()"</span>)
public void <span class="hljs-keyword">do</span>Before(JoinPoint joinPoint) {
    logger.info(<span class="hljs-string">"doBefore-----"</span>);
    
    //获取 http 请求的内容
    ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    HttpServletRequest request = attributes.getRequest();
    //url
    logger.info(<span class="hljs-string">"url: {}"</span>, request.getRequestURL());
    //method
    logger.info(<span class="hljs-string">"method: {}"</span>, request.getMethod());
    // ip
    logger.info(<span class="hljs-string">"ip: {}"</span>, request.getRemoteAddr());
    //方法
    logger.info(<span class="hljs-string">"class_method: {}"</span>, joinPoint.getSignature().getDeclaringTypeName() + <span class="hljs-string">","</span> + joinPoint.getSignature().getName());
    //参数
    logger.info(<span class="hljs-string">"params: {}"</span>, joinPoint.getArgs());
}

@After(<span class="hljs-string">"log()"</span>)
public void <span class="hljs-function"><span class="hljs-title">doAfter</span></span>() {
    logger.info(<span class="hljs-string">"doAfter-----"</span>);
}

@AfterReturning(returning = <span class="hljs-string">"object"</span>, pointcut = <span class="hljs-string">"log()"</span>)
public void <span class="hljs-keyword">do</span>AfterReturning(Object object){
    logger.info(<span class="hljs-string">"response: {}"</span>, object.toString());
}

}

@Pointcut 指定切点,在 @Before 中获取 http 请求的内容,@AfterReturning 获取返回的内容。

三、指定统一返回格式

创建 Result 对象为统一返回数据格式

代码语言:javascript
复制
public class Result<T> {
    private Integer code;
    private String msg;
    private T data;
    
// get, <span class="hljs-built_in">set</span>方法省略

}

封装工具类 ResultUtils

代码语言:javascript
复制
/**
 * 返回结果的工具类封装
 */
public class ResultUtils {

    public static Result success(Object obj) {
        Result result = new Result();
        result.setCode(0);
        result.setMsg("成功");
        result.setData(obj);
        return result;
    }

    public static Result success() {
        return success(null);
    }

    public static Result error(Integer code, String msg) {
        Result result = new Result();
        result.setCode(code);
        result.setMsg(msg);
        return result;
    }
}

不同状态返回相同格式的结果

代码语言:javascript
复制
@PostMapping(value = "/girl/add")
public Result<Girl> add(@Validated Girl girl, BindingResult bindingResult) {
    if (bindingResult.hasErrors()) {
        return ResultUtils.error(1, bindingResult.getFieldError().getDefaultMessage());
    }
    return ResultUtils.success(repository.save(girl));
}

四、全局捕获异常处理

假如在 Service 中抛出了异常

代码语言:javascript
复制
@Component
public class GirlService {

@Autowired
GirlRepository repository;

public void getAge(Integer id){
    Girl girl = repository.findById(id).get();
    Integer age = girl.getAge();
    <span class="hljs-keyword">if</span>(age &lt;= 10){
        // 还在上小学吧
        throw new GirlException(ResultEnum.PRIMARY_SCHOOL);
    }<span class="hljs-keyword">else</span> <span class="hljs-keyword">if</span>(age &gt; 10 &amp;&amp; age &lt; 16){
        // 还在上中学吧
        throw new GirlException(ResultEnum.MIDDLE_SCHOOL);
    }
}

}

定义一个 ExceptionHandle 来全局捕获 GirlException 异常

代码语言:javascript
复制
@ControllerAdvice
public class ExceptionHandle {

    @ExceptionHandler(value = GirlException.class)
    @ResponseBody
    public Result handle(Exception e){
        if(e instanceof GirlException){
            GirlException girlException = (GirlException) e;
            return ResultUtils.error(girlException.getCode(), e.getMessage());
        }
        return ResultUtils.error(-1, "未知错误");
    }
}

这样当出现指定异常时就会被全局捕获到。

GirlException 是自定义异常,代码如下:

代码语言:javascript
复制
public class GirlException extends RuntimeException {

private Integer code;

public <span class="hljs-function"><span class="hljs-title">GirlException</span></span>() {
}

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

public Integer <span class="hljs-function"><span class="hljs-title">getCode</span></span>() {
    <span class="hljs-built_in">return</span> code;
}

public void <span class="hljs-built_in">set</span>Code(Integer code) {
    this.code = code;
}

}

要继承 RuntimeException ,不要继承 Exception ,否则事务不会回滚。

将所有错误码和错误信息都封装到枚举类里,便于统一管理。

代码语言:javascript
复制
public enum ResultEnum {
    UNKNOWN(-1, "未知错误"),
    SUCCESS(0, "成功"),
    PRIMARY_SCHOOL(100, "还是小学生吧"),
    MIDDLE_SCHOOL(101, "是中学生吧")
    ;

private Integer code;
private String msg;

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

public Integer <span class="hljs-function"><span class="hljs-title">getCode</span></span>() {
    <span class="hljs-built_in">return</span> code;
}

public String <span class="hljs-function"><span class="hljs-title">getMsg</span></span>() {
    <span class="hljs-built_in">return</span> msg;
}

}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018/08/13 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、表单验证
  • 二、使用 AOP 处理请求
  • 三、指定统一返回格式
  • 四、全局捕获异常处理
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档