Spring Boot 进阶
表单验证例子
@Min(value = 18,message = "未成年禁止入内")
private Integer age;
//添加一个女生
@PostMapping("/girls")
public MyGirl addGirl(@Valid MyGirl myGirl, BindingResult bindingResult) {
if (bindingResult.hasErrors()){
System.out.println(bindingResult.getFieldError().getDefaultMessage());
return null;
}
MyGirl save = girlRepository.save(myGirl);
return save;
}
使用AOP和日志记录
aop思想举例子:
面向过程:如果天气下雨我打伞
面向对象:天气—>下雨 ; 我—>打伞
面向切面:
切面 = 切点+增强。 切点用来定位连接点
天气—>下雨
切点 :人—>打伞
增强:从包里拿出雨伞 (称这种增强为前置增强 )
切面:所有人的实现类在打伞前都给执行从包里拿出雨伞(横切逻辑,面向对象 编程思想的补充)
效果:我–>(从包里拿出雨伞)打伞;你–>(从包里拿出雨伞)打伞
package com.example.girl.aspect;
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;
@Component
@Aspect
public class HttpAspect {
private final static Logger logger = LoggerFactory.getLogger(HttpAspect.class);
@Pointcut("execution(* com.example.girl.GirlController.*(..))")
public void log(){
}
@Before("log()")
public void beforeLog(){
logger.info("before!!!!!!!!!!!!!!!!");
}
@After("log()")
public void afterLog(){
logger.info("after!!!!!!!!!!!!!!!!");
}
}
统一异常处理
我们可以利用异常和aop思想为我们实现状态码更加方便
- 用户访问controller
- 通过在service中抛出异常
- 然后通过ExceptionHandler 拦截异常,对异常进行处理(状态码,信息等。。)
- 最终返回给用户信息
@ControllerAdvice
public class ExceptionHandler {
@org.springframework.web.bind.annotation.ExceptionHandler(Exception.class)
@ResponseBody
public Result c(Exception e){
if(e instanceof MyException){
MyException myException = (MyException)e;
String message = e.getMessage();
Result result = new Result();
result.setMessage(message);
result.setCode(myException.getCode());
return result;
}else {
Result result=new Result();
result.setCode(-1);
result.setMessage("未知错误");
return result;
}
}
}
ResponseEntity的使用
@RestController("item")
public class ItemController {
@Autowired
private ItemService itemService;
@PostMapping
public ResponseEntity<Item> addItem(Item item){
if(item.getPrice()==null){
throw new RuntimeException("价格不能为空");
}else {
Item item1 = itemService.addOneItem(item);
return ResponseEntity.status(HttpStatus.ACCEPTED).body(item1);
}
}
}
单元测试
对controller的测试
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class ControllerTest {
@Autowired
private MockMvc mvc;
@Test
public void testC()throws Exception{
mvc.perform(MockMvcRequestBuilders.get("/girls"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.content().string("abc"));
}
}
对service进行测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class MyGirlServiceTest {
@Autowired
private MyGirlService myGirlService;
@Test
public void getGirlList() {
List<MyGirl> girlList = myGirlService.getGirlList();
}
}
使用带有注解的测试
@RunWith(SpringRunner.class)
@SpringBootTest
@Slf4j
public class TestLogback {
//方法1
// private final Logger logger = LoggerFactory.getLogger(TestLogback.class);
@Test
public void testInfo(){
// 方法1 logger.info("");
// 方法2: 使用@Slf4j注解
log.info("an----->");
}
}
执行全部测试
1.打开terminal
2.进入项目所在目录
3.mvn clean package
跳过测试?
mvn clean package -Dmaven.test.skip=true