专栏首页郭少华Spring Security项目Spring MVC开发RESTful API(二)

Spring Security项目Spring MVC开发RESTful API(二)

查询请求

常用注解

  • @RestController 标明此Controller提供RestAPI
  • @RequestMapping 映射http请求url到java方法
  • @RequestParam 映射请求参数到java方法到参数
  • @PageableDefault 指定分页参数默认值

编写一个简单的UserController类

@RestController
@RequestMapping(value = "/user")
public class UserController {

    @RequestMapping(method = RequestMethod.GET)
    public List<User> query(@RequestParam(name = "username",required = true) String username, @PageableDefault(page = 1,size = 20,sort = "username",direction = Sort.Direction.DESC)Pageable pageable){

        System.out.println(pageable.getSort());
        List<User>users=new ArrayList<>();
        users.add(new User("aaa","111"));
        users.add(new User("bbb","222"));
        users.add(new User("ddd","333"));
        return  users;
    }
}

@PageableDefault SpingData分页参数 page当前页数默认0开始 sizi每页个数默认10 sort 排序

Srping boot 测试用例

在demo的pom.xml里面引入spirngboot的测试

    <!--spring测试框架-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
    </dependency>

测试/user接口

@RunWith(SpringRunner.class) //运行器
@SpringBootTest
public class UserControllerTest {

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

    @Before
    public void stup(){
        mockMvc= MockMvcBuilders.webAppContextSetup(wac).build();
    }
  //测试用例
    @Test
    public void whenQuerSuccess() throws Exception {
        String result=mockMvc.perform(MockMvcRequestBuilders.get("/user")
                //传过去的参数
                .param("username","admin")
                .contentType(MediaType.APPLICATION_JSON_UTF8))
                //判断请求的状态吗是否成功,200
                .andExpect(MockMvcResultMatchers.status().isOk())
                //判断返回的集合的长度是否是3
                .andExpect(MockMvcResultMatchers.jsonPath("$.length()").value(3))
                //打印信息
                .andDo(MockMvcResultHandlers.print())
                .andReturn().getResponse().getContentAsString();
        //打印返回结果
        System.out.println(result);
    }

jsonPath文档语法查询地址

用户详情请求

常用注解

  • @PathVariable 映射url片段到java方法参数
  • @JsonView 控制json输出内容

实体对象

@NoArgsConstructor
@AllArgsConstructor
public class User {

    public interface UserSimpleView{};
    public interface UserDetailView extends UserSimpleView{};

    private String username;
    private String password;

    @JsonView(UserSimpleView.class)
    public String getUsername() {
        return username;
    }


    public void setUsername(String username) {
        this.username = username;
    }

    @JsonView(UserDetailView.class)
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

Controller类

@RestController
@RequestMapping(value = "/user")
public class UserController {

    @RequestMapping(value = "/{id:\\d+}",method = RequestMethod.GET)
    // 正则表达式 :\\d+ 表示只能输入数字
    //用户名密码都显示
    @JsonView(User.UserDetailView.class)
    public User  userInfo(@PathVariable String id){
        User user=new User();
        user.setUsername("tom");
        return user;
    }
}

测试用例

@RunWith(SpringRunner.class) //运行器
@SpringBootTest
public class UserControllerTest {

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

    @Before
    public void stup(){
        mockMvc= MockMvcBuilders.webAppContextSetup(wac).build();
    }

    //用户详情用例
    @Test
    public void whenUserInfoSuccess() throws Exception {
        String result=mockMvc.perform(MockMvcRequestBuilders.get("/user/1")
                .contentType(MediaType.APPLICATION_JSON_UTF8))
                //判断请求的状态吗是否成功,200
                .andExpect(MockMvcResultMatchers.status().isOk())
                //判断返回到username是不是tom
                .andExpect(MockMvcResultMatchers.jsonPath("$.username").value("tom"))
                //打印信息
                .andDo(MockMvcResultHandlers.print())
                .andReturn().getResponse().getContentAsString();
        //打印返回结果
        System.out.println(result);
    }
}

用户处理创建请求

常用注解

  • @RequestBody 映射请求体到java方法到参数
  • @Valid注解和BindingResult验证请求参数合法性并处理校验结果

实体对象

@NoArgsConstructor
@AllArgsConstructor
public class User {

    public interface UserSimpleView{};
    public interface UserDetailView extends UserSimpleView{};
    private String id;
    private String username;

    //不允许password为null
    @NotBlank
    private String password;

    private Date birthday;

    @JsonView(UserSimpleView.class)
    public String getId() { return id; }

    public void setId(String id) { this.id = id; }

    @JsonView(UserSimpleView.class)
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }



    @JsonView(UserDetailView.class)
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @JsonView(UserSimpleView.class)
    public Date getBirthday() { return birthday; }

    public void setBirthday(Date birthday) { this.birthday = birthday; }
}

Controller类

    @RequestMapping(method = RequestMethod.POST)
    @JsonView(User.UserSimpleView.class)
    //@Valid启用校验password不允许为空
    public User createUser(@Valid @RequestBody User user, BindingResult errors){
        //如果校验有错误是true并打印错误信息
        if(errors.hasErrors()){
            errors.getAllErrors().stream().forEach(error -> System.out.println(error.getDefaultMessage()));
        }
        System.out.println(user.getUsername());
        System.out.println(user.getPassword());
        System.out.println(user.getBirthday());
        user.setId("1");
        return user;
    }

测试用例

@RunWith(SpringRunner.class) //运行器
@SpringBootTest
public class UserControllerTest {

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

    @Before
    public void stup(){
        mockMvc= MockMvcBuilders.webAppContextSetup(wac).build();
    }

    //用户创建用例
    @Test
    public void whenCreateSuccess() throws Exception {
        Date date=new Date();
        String content="{\"username\":\"tom\",\"password\":null,\"birthday\":"+date.getTime()+"}";
        String result=mockMvc.perform(MockMvcRequestBuilders.post("/user")
                .content(content)
                .contentType(MediaType.APPLICATION_JSON_UTF8))
                //判断请求的状态吗是否成功,200
                .andExpect(MockMvcResultMatchers.status().isOk())
                //判断返回到username是不是tom
                .andExpect(MockMvcResultMatchers.jsonPath("$.id").value("1"))
                .andReturn().getResponse().getContentAsString();
        //打印返回结果
        System.out.println(result);
    }
}

修改和删除请求

验证注解

注解

解释

@NotNull

值不能为空

@Null

值必须为空

@Pattern(regex=)

字符串必须匹配正则表达式

@Size(min=,max=)

集合的元素数量必须在min和max之间

@Email

字符串必须是Email地址

@Length(min=,max=)

检查字符串长度

@NotBlank

字符串必须有字符

@NotEmpty

字符串不为null,集合有元素

@Range(min=,max=)

数字必须大于等于min,小于等于max

@SafeHtml

字符串是安全的html

@URL

字符串是合法的URL

@AssertFalse

值必须是false

@AssertTrue

值必须是true

@DecimalMax(value=,inclusive)

值必须小于等于(inclusive=true)/小于(inclusive=false) value指定的值

@DecimalMin(value=,inclusive)

值必须大于等于(inclusive=true)/大于(inclusive=false) value指定的值

@Digits(integer=,fraction=)

integer指定整数部分最大长度,fraction小数部分最大长度

@Future

被注释的元素必须是一个将来的日期

@Past

被注释的元素必须是一个过去的日期

@Max(value=)

值必须小于等于value值

@Min(value=)

值必须大于等于value值

自定义注解修改请求

实体对象

@NoArgsConstructor
@AllArgsConstructor
public class User {

    public interface UserSimpleView{};
    public interface UserDetailView extends UserSimpleView{};
    private String id;
    
    //自定义注解
    @MyConstraint(message = "账号必须是tom")
    private String username;

    //不允许password为null
    @NotBlank(message = "密码不能为空")
    private String password;

    //加验证生日必须是过去的时间
    @Past(message = "生日必须是过去的时间")
    private Date birthday;

    @JsonView(UserSimpleView.class)
    public String getId() { return id; }

    public void setId(String id) { this.id = id; }

    @JsonView(UserSimpleView.class)
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }



    @JsonView(UserDetailView.class)
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @JsonView(UserSimpleView.class)
    public Date getBirthday() { return birthday; }

    public void setBirthday(Date birthday) { this.birthday = birthday; }
}

Controller类

    @RequestMapping(value = "/{id:\\d+}",method = RequestMethod.PUT)
    @JsonView(User.UserSimpleView.class)
    //@Valid启用校验password不允许为空
    public User updateUser(@Valid @RequestBody User user, BindingResult errors){
        //如果校验有错误是true并打印错误信息
        if(errors.hasErrors()){
            errors.getAllErrors().stream().forEach(error -> System.out.println(error.getDefaultMessage()));
        }
        System.out.println(user.getUsername());
        System.out.println(user.getPassword());
        System.out.println(user.getBirthday());
        user.setId("1");
        return user;
    }

测试用例

@RunWith(SpringRunner.class) //运行器
@SpringBootTest
public class UserControllerTest {

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

    @Before
    public void stup(){
        mockMvc= MockMvcBuilders.webAppContextSetup(wac).build();
    }

    //用户修改用例
    @Test
    public void whenUpdateSuccess() throws Exception {
        //当前时间加一年
        Date date = new Date(LocalDateTime.now().plusYears(1).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
        String content = "{\"id\":\"1\",\"username\":\"44\",\"password\":null,\"birthday\":" + date.getTime() + "}";
        String result = mockMvc.perform(MockMvcRequestBuilders.put("/user/1")
                .content(content)
                .contentType(MediaType.APPLICATION_JSON_UTF8))
                //判断请求的状态吗是否成功,200
                .andExpect(MockMvcResultMatchers.status().isOk())
                //判断返回到username是不是tom
                .andExpect(MockMvcResultMatchers.jsonPath("$.id").value("1"))
                .andReturn().getResponse().getContentAsString();
        //打印返回结果
        System.out.println(result);
    }

自定义注解

image.png

MyConstraint类

import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

//作用在字段跟方法上面
@Target({ElementType.FIELD,ElementType.METHOD})
//运行时注解
@Retention(RetentionPolicy.RUNTIME)
//需要校验注解的类
@Constraint(validatedBy = MyConstraintValidator.class)
public @interface MyConstraint {
    String message() default "{org.hibernate.validator.constraints.NotBlank.message}";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

MyConstraintValidator类

import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;

//范型1.验证的注解 2.验证的数据类型
public class MyConstraintValidator implements ConstraintValidator<MyConstraint,Object> {

    @Override
    public void initialize(MyConstraint myConstraint) {
        //校验器初始化的规则
    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext constraintValidatorContext) {
        //校验username如果是tom验证通过
        if (value.equals("tom")){
            return true;
        }else{
            return false;
        }

    }
}

删除请求

Controller类

    @RequestMapping(value = "/{id:\\d+}",method = RequestMethod.DELETE)
    //@Valid启用校验password不允许为空
    public void deleteUser(@PathVariable String id){
        System.out.println(id);
    }

测试用例

@RunWith(SpringRunner.class) //运行器
@SpringBootTest
public class UserControllerTest {

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

    @Before
    public void stup(){
        mockMvc= MockMvcBuilders.webAppContextSetup(wac).build();
    }

    //用户删除用例
    @Test
    public void whenDeleteSuccess() throws Exception {
        mockMvc.perform(MockMvcRequestBuilders.delete("/user/1")
                .contentType(MediaType.APPLICATION_JSON_UTF8))
                //判断请求的状态吗是否成功,200
                .andExpect(MockMvcResultMatchers.status().isOk());

    }

服务异常处理

把BindingResult errors去掉

    @RequestMapping(method = RequestMethod.POST)
    @JsonView(User.UserSimpleView.class)
    //@Valid启用校验password不允许为空
    public User createUser(@Valid @RequestBody User user){
        //如果校验有错误是true并打印错误信息
//        if(errors.hasErrors()){
//            errors.getAllErrors().stream().forEach(error -> System.out.println(error.getDefaultMessage()));
//        }
        System.out.println(user.getUsername());
        System.out.println(user.getPassword());
        System.out.println(user.getBirthday());
        user.setId("1");
        return user;
    }

查看返回的异常信息

image.png

处理状态码错误

创建文件结构如下404错误将跳转对应页面

image.png

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Spring Security项目第三方登陆(四)

    楠楠
  • Spring boot之JSON(二)

    楠楠
  • (Vue全家桶)Vue-router

    如果你在使用vue-cli中已经选择安装了vue-router,那这里不需要重复安装了。

    楠楠
  • 一文了解Java反射和应用

    静态编译:在编译的时候进确定类型,如果绑定对象成功,new 是静态加载类,就编译通过。

    Java技术江湖
  • Spring 中如何控制对象的初始化时间(延迟加载,强制先行加载)

    当标注了@Lazy 注解时候,不会看到 init user… 的输出。只有当首次使用 User 类的时候,才会被初始化。

    水货程序员
  • 第50节:Java当中的泛型

    这就存在一个问题,如果集合存储元素时,而且存储对象有很多,而且对象类型不相同,就很容易导致隐患。

    达达前端
  • Strategy Pattern(策略模式)- note

    可以在不破坏使用行为的类的情况下更改行为,并且这些类可以通过更改所使用的特定实现在行为之间进行切换,而无需进行任何重大的代码更改。

    Felix_wang
  • Java面试手册:反射

    Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于 Reflection API 取得任何类的内部信息,并能直接操作任意对象的内...

    南风
  • Java中的transient关键字

    用户1205080
  • Java实现Http的Post、Get、代理访问请求

    Java实现Http的访问请求。包含基本的Get访问、Post访问。Post包含使用代理模式访问

    似水的流年

扫码关注云+社区

领取腾讯云代金券