用户详情请求
使用@PathVariable注解去绑定url中的参数
@RequestMapping(value="user/{id}",method = RequestMethod.GET)
public User getInfo(@PathVariable(required = false) String id) {
User user=new User();
user.setUsername("tom");
return user;
}
测试用例
@Test
public void whenGenInfoSuccess() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/user/1")
.contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.username").value("tom"));
}
需求:传来的必须是数字
@RequestMapping(value="user/{id:\\d+}",method = RequestMethod.GET)
public User getInfo(@PathVariable(required = false) String id) {
User user=new User();
user.setUsername("tom");
return user;
}
@Test
public void whenGenInfoFail() throws Exception {
mockMvc.perform(MockMvcRequestBuilders.get("/user/a")
.contentType(MediaType.APPLICATION_JSON_UTF8))
.andExpect(MockMvcResultMatchers.status().is4xxClientError());
}
需求:query接口不能将password字段返回给前端,getInfo接口要将password字段返回给前端
解析:使用@JsonView
@Data
public class User {
@JsonView(UserSimpleView.class)
private String username;
@JsonView(UserDetailView.class)
private String password;
public interface UserSimpleView{};
public interface UserDetailView extends UserSimpleView{};
}
@RestController
public class UserController {
@RequestMapping(value = "/user",method = RequestMethod.GET)
@JsonView(User.UserSimpleView.class)
public List<User> query(@RequestParam(required = false) String username,@PageableDefault(page = 1,size = 10,sort = "username,asc") Pageable pageable){
System.out.println(pageable.getPageSize()+"---"+pageable.getPageNumber()+"---"+pageable.getSort());
List<User> users=new ArrayList<User>(3);
users.add(new User());
users.add(new User());
users.add(new User());
return users;
}
@JsonView(User.UserDetailView.class)
@RequestMapping(value="user/{id:\\d+}",method = RequestMethod.GET)
public User getInfo(@PathVariable(required = false) String id) {
User user=new User();
user.setUsername("tom");
return user;
}
}
用户创建请求
@PostMapping
public User createUser(User user) {
System.out.println("user==>"+user);
user.setId("1");
return user;
}
@Test
public void whenCreateSuccess() throws Exception {
String content = "{\"username\":\"tom\",\"password\":null}";
String res = mockMvc
.perform(MockMvcRequestBuilders.post("/user").contentType(MediaType.APPLICATION_JSON_UTF8)
.content(content))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.id").value(1)).andReturn().getResponse()
.getContentAsString();
System.out.println(res);
}
发现controller类的参数User内并没有传过来的值。
需要加一个@RequestBody
@PostMapping
public User createUser(@RequestBody User user) {
System.out.println("user==>"+user);
user.setId("1");
return user;
}
之前并没有接触过@RequestBody注解,网上查询了一下该注解的作用https://blog.csdn.net/justry_deng/article/details/80972817
简单的说就是:参数放在请求体中,必须用@RequestBody注解接收。
需求:处理日期类型的参数
(视频上所说,由于现在前后端分离的情况,可能后台一个接口会被不同的渠道调用,app,网页端。这些渠道可能显示的格式不同,所以一般而言后端传给前端会是时间戳格式,然后再由前端选择显示的格式。但我们现在并不是= =,而是传格式化好了的时间,可以用@DateTimeFormat 和 @JsonFormat 注解,@DateTimeFormat 在RequestBody中不生效)
需求:校验参数的合法性,并处理校验的结果
解析:使用@vaild注解和BindingResult注解
@Data
@ToString
public class User {
@JsonView(UserSimpleView.class)
private String id;
@JsonView(UserSimpleView.class)
private String username;
@NotBlank(message = "密码不能为空")
@JsonView(UserDetailView.class)
private String password;
private Date birthDate;
public interface UserSimpleView {
};
public interface UserDetailView extends UserSimpleView {
};
}
@PostMapping
public User createUser(@Valid @RequestBody User user,BindingResult errors) {
if(errors.hasErrors()) {
errors.getAllErrors().stream().forEach(error-> System.out.println(error.getDefaultMessage()));
}
System.out.println("user==>"+user);
user.setId("1");
return user;
}
(这里我使用的参数校验和视频上的略有出入,看我的实现可以看常用功能文章系列的参数校验那一篇。)
用户修改请求
@Data
@ToString
public class User {
@JsonView(UserSimpleView.class)
private String id;
@JsonView(UserSimpleView.class)
private String username;
@NotBlank(message = "密码不能为空")
@JsonView(UserDetailView.class)
private String password;
@Past(message = "生日必须是过去的时间")
private Date birthDate;
public interface UserSimpleView {
};
public interface UserDetailView extends UserSimpleView {
};
}
@PutMapping(value="/{id:\\d+}")
public User updateUser(@Valid @RequestBody User user,BindingResult errors) {
if(errors.hasErrors()) {
errors.getAllErrors().stream().forEach(error-> System.out.println(error.getDefaultMessage()));
}
System.out.println("user==>"+user);
user.setId("1");
return user;
}
@Test
public void whenUpdateSuccess() throws Exception {
Date date=new Date(LocalDateTime.now().plusYears(1).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
String content = "{\"id\":\"1\",\"username\":\"tom\",\"password\":null,\"birthDate\":"+date.getTime()+"}";
String res = mockMvc
.perform(MockMvcRequestBuilders.put("/user/1").contentType(MediaType.APPLICATION_JSON_UTF8)
.content(content))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.id").value(1)).andReturn().getResponse()
.getContentAsString();
System.out.println(res);
}
需求:自定义校验注解
public class MyConstraintValidator implements ConstraintValidator<MyConstraint, Object> {
@Override
public void initialize(MyConstraint constraintAnnotation) {
System.out.println("MyConstraintValidator init");
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
System.out.println("value==》"+value);
// TODO 写具体的校验逻辑,true验证通过,false验证不过
return false;
}
}
@Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = MyConstraintValidator.class)
public @interface MyConstraint {
String message() default "";
Class<?>[] groups() default { };
Class<? extends Payload>[] payload() default { };
}
@MyConstraint(message = "自定义校验不过")
@JsonView(UserSimpleView.class)
private String username;
服务器异常处理
spring boot的默认异常处理机制是,浏览器返回错误页面,客户端返回json数据。
1、在src/main/resources下建立resources文件夹,然后再建error文件夹,再建立相应的错误页面。如404.hmtl,500.html
多线程提高接口性能
使用swagger生成文档
1、引入pom依赖
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger2 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.springfox/springfox-swagger-ui -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
2、使用@EnableSwagger2开启swagger
@SpringBootApplication
@EnableSwagger2
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
3、使用注解
@Api注解:说明这个controller是干什么的
@Api("用户服务")
public class UserController
@ApiOperation:说明这个方法是干什么的
@ApiOperation(value = "用户创建服务")
@PostMapping
public User createUser(@Valid @RequestBody User user,BindingResult errors)
@ApiModelProperty :参数是对象时,说明对象的属性
@ApiModelProperty("用户名")
@JsonView(UserSimpleView.class)
private String username;
@ApiModelProperty("用户密码")
@NotBlank(message = "密码不能为空")
@JsonView(UserDetailView.class)
private String password;
@ApiModelProperty("用户生日")
@Past(message = "生日必须是过去的时间")
private Date birthDate;
@ApiParam:参数是单独的一个时,说明。
public List<User> query(@ApiParam("用户名")@RequestParam(required = false) String username,@PageableDefault(page = 1,size = 10,sort = "username,asc") Pageable pageable){
参考链接://www.greatytc.com/p/a66cf3acd29a