Spring Boot入门2

参考:Spring Boot进阶之Web进阶

示例代码:https://git.oschina.net/liaoshixiong/girl

 

1、使用@Valid表单验证

2、使用AOP处理请求

3、异常处理

4、测试代码:单元测试。

表单验证

1、代码使用GIT下载命令

// 下载代码
git clone git@git.oschina.net:liaoshixiong/girl.git

// 切换到标签所在的代码
git checkout -b web-2 web-2

// 切换到标签所在的代码
git checkout -b web-1 web-1

2、添加一个记录,可以使用实体类来获取所有的参数

GirlController.java

    /**
     * 添加一个女生
     * @return
     */
    @PostMapping(value = "/girls")
    public Girl girlAdd(Girl girl){
       return this.girRepository.save(girl);
    }

3、表单验证:age<18,不能添加。

在实体类中写注解。Girl.java

    @Min(value=18,message = "未成年少女禁止")
    private  Integer age;

在controller中写对应的验证注解。GirlController.java

    /**
     * 添加一个女生
     * @return
     */
    @PostMapping(value = "/girls")
    public Girl girlAdd(@Valid  Girl girl, BindingResult bindingResult){
        if(bindingResult.hasErrors()){
            System.out.println(bindingResult.getFieldError().getDefaultMessage());
            return null;
        }

       return this.girRepository.save(girl);
    }

使用AOP处理请求

AOP:

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程。

OOP:面向对象程序设计(Object Oriented Programming)

统一处理请求日志。

1、添加依赖到pom.xml

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>

2、编写代码:Before(...)拦截所有GirlContoller下的方法,在之前都执行log().

After(...)拦截所有GirlContoller下的方法,在之后都执行log().

@Aspect
@Component
public class HttpAspect {

    @Before("execution(public  * com.imooc.girl.controller.GirlController.*(..))")
    public void log(){
        System.out.println("exec GirlController.* before");
    }

    @After("execution(public  * com.imooc.girl.controller.GirlController.*(..))")
    public void logAfter(){
        System.out.println("exec GirlController.* after");
    }
}

3、提取注解@Before与@After的切点使用@Pointcut。

@Aspect
@Component
public class HttpAspect {
    @Pointcut("execution(public  * com.imooc.girl.controller.GirlController.*(..))")
    public void log(){

    }

    @Before("log()")
    public void doBefore(){
        System.out.println("exec GirlController.* before");
    }

    @After("log()")
    public void doAfter(){
        System.out.println("exec GirlController.* after");
    }
}

4、使用Spring自带的org.slf4j.Logger代替System.out.println打印日志。

@Aspect
@Component
public class HttpAspect {
    private final static Logger logger = LoggerFactory.getLogger(HttpAspect.class);

    @Pointcut("execution(public  * com.imooc.girl.controller.GirlController.*(..))")
    public void log(){

    }

    @Before("log()")
    public void doBefore(){
        logger.info("exec GirlController.* before");
    }

    @After("log()")
    public void doAfter(){
        logger.info("exec GirlController.* after");
    }
}

2018-09-06 11:05:21.345  INFO 8752 --- [nio-8182-exec-1] com.imooc.girl.aspect.HttpAspect         : exec GirlController.* before
Hibernate: select girl0_.id as id1_0_0_, girl0_.age as age2_0_0_, girl0_.cup_size as cup_size3_0_0_ from girl girl0_ where girl0_.id=?
2018-09-06 11:05:21.439  INFO 8752 --- [nio-8182-exec-1] com.imooc.girl.aspect.HttpAspect         : exec GirlController.* after

5、获取请求的相关信息。

    @Before("log()")
    public void doBefore(JoinPoint joinPoint){
        ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        //1 URL
        logger.info("url={}",request.getRequestURL());
        //2 method
        logger.info("method={}",request.getMethod());
        //3 ip
        logger.info("ip={}",request.getRemoteAddr());
        //4 类方法
        logger.info("class_method={}",joinPoint.getSignature().getDeclaringTypeName()+"."+joinPoint.getSignature().getName());
        //5 参数
        logger.info("args={}",joinPoint.getArgs());
    }

2018-09-06 11:16:54.471  INFO 6908 --- [nio-8182-exec-1] com.imooc.girl.aspect.HttpAspect         : url=http://127.0.0.1:8182/girl/girls/5
2018-09-06 11:16:54.472  INFO 6908 --- [nio-8182-exec-1] com.imooc.girl.aspect.HttpAspect         : method=GET
2018-09-06 11:16:54.472  INFO 6908 --- [nio-8182-exec-1] com.imooc.girl.aspect.HttpAspect         : ip=127.0.0.1
2018-09-06 11:16:54.476  INFO 6908 --- [nio-8182-exec-1] com.imooc.girl.aspect.HttpAspect         : class_method=com.imooc.girl.controller.GirlController.girlFindOne
2018-09-06 11:16:54.476  INFO 6908 --- [nio-8182-exec-1] com.imooc.girl.aspect.HttpAspect         : args=5
Hibernate: select girl0_.id as id1_0_0_, girl0_.age as age2_0_0_, girl0_.cup_size as cup_size3_0_0_ from girl girl0_ where girl0_.id=?
2018-09-06 11:16:54.566  INFO 6908 --- [nio-8182-exec-1] com.imooc.girl.aspect.HttpAspect         : exec GirlController.* after

6、获取返回值相关信息

    @AfterReturning(returning = "object",pointcut = "log()")
    public void doAfterReturning(Object object){
        logger.info("response={}",object);
    }

Hibernate: select girl0_.id as id1_0_0_, girl0_.age as age2_0_0_, girl0_.cup_size as cup_size3_0_0_ from girl girl0_ where girl0_.id=?
2018-09-06 11:21:46.138  INFO 8408 --- [nio-8182-exec-1] com.imooc.girl.aspect.HttpAspect         : exec GirlController.* after
2018-09-06 11:21:46.139  INFO 8408 --- [nio-8182-exec-1] com.imooc.girl.aspect.HttpAspect         : response=Optional[Girl{id=5, cupSize='B', age=19}]

统一异常处理

1、统一返回对象的实体类。

public class Result<T> {
    /* 错误码 */
    private Integer code;
    /*提示信息*/
    private String msg;
    /* 返回的具体内容*/
    private T data;

    public Result() {
    }

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

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
    @Override
    public String toString() {
        return "Result{" +
                "code=" + code +
                ", msg='" + msg + '\'' +
                ", data=" + data +
                '}';
    }
}

2、修改Controller中的返回结果。

   /**
     * 添加一个女生
     * @return
     */
    @PostMapping(value = "/girls")
    public Result<Girl> girlAdd(@Valid  Girl girl, BindingResult bindingResult){
        Result<Girl> result = new Result<>();

        if(bindingResult.hasErrors()){
            result.setCode(1);
            result.setMsg(bindingResult.getFieldError().getDefaultMessage());
             return result;

        }
        Girl insertData = this.girRepository.save(girl);
        result.setCode(0);
        result.setMsg("成功");
        result.setData(insertData);
       return result;
    }

3、写一个工具类,提取result的创建。

public class ResultUtil {

    public static Result success(Object object){
        Result result = new Result();
        result.setCode(0);
        result.setMsg("成功");
        result.setData(object);
        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;
    }

}

4、获取某女生的年龄并判断

<10,返回“应该在上小学”

10<age<16,返回“可能在上初中”

编写GirlController.java

    @GetMapping(value = "girls/getAge/{id}")
    public void getAge(@PathVariable("id")Integer id) throws Exception {
        this.girlService.getAge(id);
    }

编写GirlService.java

    public void getAge(Integer id) throws Exception {
        Optional<Girl> girl = this.girRepository.findById(id);
        Integer age = girl.get().getAge();
        if(age<10){
            throw  new GirlException(100,"你还在上小学吧");
        }else  if(age>10&&age<16){
            throw  new GirlException(101,"你可能在上初中");
        }

    }

编写GirlException.java,可以传Code。

public class GirlException extends RuntimeException {
    private Integer code;

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

    public Integer getCode() {
        return code;
    }

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

编写拦截Exception的ExceptionHandle.java

@ControllerAdvice
public class ExceptionHandle {

    private final  static Logger logger = LoggerFactory.getLogger(ExceptionHandle.class);

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public Result handle(Exception e){
        if(e instanceof GirlException){
            GirlException girlException = (GirlException)e;
            return ResultUtil.error(girlException.getCode(), girlException.getMessage());
        }
        logger.error("[系统异常]{}",e);
        return ResultUtil.error(-1,"未知错误:"+e.getMessage());
    }
}

5、使用枚举,管理异常代码

public enum ResultEnum {
    UNKNOW_ERROR(-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 getCode() {
        return code;
    }

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

    public String getMsg() {
        return msg;
    }

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

修改对应的GirlException构造器及抛异常代码。

GirlService.java

    public void getAge(Integer id) throws Exception {
        Optional<Girl> girl = this.girRepository.findById(id);
        Integer age = girl.get().getAge();
        if(age<10){
            throw  new GirlException(ResultEnum.PRIMARY_SCHOOL);
        }else  if(age>10&&age<16){
            throw  new GirlException(ResultEnum.MIDDLE_SCHOOL);
        }

    }

单元测试

测试Service

 

测试API

测试Service

1、在test中编写代码,选中方法名,右击并选中进行测试。

@RunWith(SpringRunner.class)
@SpringBootTest
public class GirlServiceTest {

    @Autowired
    private GirlService girlService;

    @Test
    public void findOneTest(){
        Girl girl = girlService.findOne(4);
        Assert.assertEquals(new Integer(14),girl.getAge());

    }
}

2、利用Idea,创建测试的java代码

3、对controller进行测试

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class GirlControllerTest {

    @Autowired
    private MockMvc mvc;

    @Test
    public void girlList() throws Exception {
        mvc.perform(MockMvcRequestBuilders.get("/girls"))
                .andExpect(MockMvcResultMatchers.status().isOk())
        .andExpect(MockMvcResultMatchers.content().string("llllll"));
    }

}

 

5、maven打包:mvn clean package

maven打包跳过单元测试:mvn clean package -Dmaven.test.skip=true;

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值