zoukankan      html  css  js  c++  java
  • 第二章:RESTful API

    学习内容

      使用Spring MVC编写Restful API

      使用Spring MVC处理其他web应用常见的需求和场景

        如何处理静态资源和异常,如何使用Spring MVC的拦截器,文件的上传下载,如何进行请求的异步开发

      RESTful API开发常用辅助框架

        Swagger-生成服务文档,WireMock-伪造服务

    RESTful API介绍

      特点:

      1.用URL描述资源

      2.使用HTTP方法描述行为,使用HTTP状态码来表示不同结果

        增删改查对应POST、DELETE、PUT、GET,使用状态码来表示结果而不是用报文里面的内容。

      3.使用json交互数据

      4.RESTful只是一种风格,并不是强制标准

    编写第一个RESTful API

      使用注解声明RESTful API

        常用注解

          @RestController 标明此Controller提供RESTful API

          @RequestMapping及其变体 映射http请求url到java方法

          @RequestParam 映射请求参数到java方法的参数

          @PageableDefault 指定分页参数的默认值

      在RESTful API中传递参数

        @RequestParam

          required,name,defaultValue,required表示参数是否必须,name表示HTTP请求参数名,defaultValue表示未传参数时使用的默认值。

    @RequestMapping(value = "/user", method = RequestMethod.GET)
    public List<User> query(@RequestParam(required = true, name = "username", defaultValue = "Tom") String username) {
        System.out.println(username);
        List<User> users = new ArrayList<User>();
        users.add(new User());
        users.add(new User());
        users.add(new User());
        return users;
    }

          如果传递参数太多,Spring MVC可以自动将参数组装到对象中,可以声明一个类UserQueryCondition有多个属性。

    public class UserQueryCondition {
        
        private String username;
        private int age;
        private int ageTo;
        
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public int getAgeTo() {
            return ageTo;
        }
        public void setAgeTo(int ageTo) {
            this.ageTo = ageTo;
        }
    
    }
    @RequestMapping(value = "/user", method = RequestMethod.GET)
    public List<User> query(UserQueryCondition condition) {
        System.out.println(ReflectionToStringBuilder.toString(condition, ToStringStyle.MULTI_LINE_STYLE));
        List<User> users = new ArrayList<User>();
        users.add(new User());
        users.add(new User());
        users.add(new User());
        return users;
    }
    @Test
    public void whenQuerySuccess() throws Exception {
        mockMvc.perform(get("/user")
                .param("username", "jojo")
                .param("age", "10")
                .param("ageTo", "20")
                .contentType(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.length()").value(3));
    }

         @PageableDefault

          page,size,sort,表示默认查第几页,一页数据条数,排序

    @RequestMapping(value = "/user", method = RequestMethod.GET)
    public List<User> query(UserQueryCondition condition, @PageableDefault(page = 1, size = 10, sort = "username,asc") Pageable pageable) {
        System.out.println(ReflectionToStringBuilder.toString(condition, ToStringStyle.MULTI_LINE_STYLE));
        System.out.println(ReflectionToStringBuilder.toString(pageable, ToStringStyle.MULTI_LINE_STYLE));
        List<User> users = new ArrayList<User>();
        users.add(new User(1));
        users.add(new User(2));
        users.add(new User(3));return users;
    }
    @Test
    public void whenQuerySuccess() throws Exception {
        mockMvc.perform(get("/user")
                .param("username", "jojo")
                .param("age", "10")
                .param("ageTo", "20")
                .param("size", "5")
                .param("page", "2")
                .param("sort", "age,desc")
                .contentType(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(status().isOk());
    }

    编写用户详情服务

      @PathVariable 映射url片段到java方法的参数

        name,required,name要和url片段相同,required表示是否必须

    @RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
    public User getInfo(@PathVariable(name = "id") String userid) {
        User user = new User();
        user.setId(userid);
        user.setUsername("Tom");
        return user;
    }
    @Test
    public void whenGetInfoSuccess() throws Exception {
        String result = mockMvc.perform(get("/user/1")
                .contentType(MediaType.APPLICATION_JSON_UTF8))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$.username").value("Tom"))
        .andReturn().getResponse().getContentAsString();
        System.out.println(result);
    }  

      在url片段的声明中使用正则表达式

    @RequestMapping(value = "/user/{id:\d+}", method = RequestMethod.GET)
    public User getInfo(@PathVariable(name = "id") String userid) {
        User user = new User();
        user.setId(userid);
        user.setUsername("Tom");
        return user;
    }
    @Test
    public void whenGetInfoFail() throws Exception {
        mockMvc.perform(get("/user/a")
                .contentType(MediaType.APPLICATION_JSON_UTF8))
                .andExpect(status().is4xxClientError());
    }

      @JsonView控制json输出内容

        假设query不想返回用户密码,getInfo时返回给前台用户密码,即在返回相同对象时控制返回哪些字段。

        使用步骤:

          1.使用接口声明多个视图 2.在值对象的get方法上指定视图 3.在Controller方法上指定视图

    public class User {
        
        public interface UserSimpleView {}; //视图1
        public interface UserDetailView extends UserSimpleView {}; //视图2,因继承视图1,所以使用视图2也会显示视图1的属性
        
        private String id;
        private String username;
        private int age;
        private String password;
        
        @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(UserSimpleView.class)
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        @JsonView(UserDetailView.class)
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }
    
    }
    @RequestMapping(value = "/user", method = RequestMethod.GET)
    @JsonView(User.UserSimpleView.class)
    public List<User> query(UserQueryCondition condition, @PageableDefault(page = 1, size = 10, sort = "username,asc") Pageable pageable) {
        System.out.println(ReflectionToStringBuilder.toString(condition, ToStringStyle.MULTI_LINE_STYLE));
        System.out.println(ReflectionToStringBuilder.toString(pageable, ToStringStyle.MULTI_LINE_STYLE));
        List<User> users = new ArrayList<User>();
        users.add(new User());
        users.add(new User());
        users.add(new User());
        return users;
    }
    
    @RequestMapping(value = "/user/{id:\d+}", method = RequestMethod.GET)
    @JsonView(User.UserDetailView.class)
    public User getInfo(@PathVariable(name = "id") String userid) {
        User user = new User();
        user.setId(userid);
        user.setUsername("Tom");
        return user;
    }

       代码重构

        1.将url相同部分提到类上声明

        2.使用RequestMapping的变体GetMapping

    @RestController
    @RequestMapping("/user")
    public class UserController {
        
        @GetMapping()
        @JsonView(User.UserSimpleView.class)
        public List<User> query(UserQueryCondition condition, @PageableDefault(page = 1, size = 10, sort = "username,asc") Pageable pageable) {
            System.out.println(ReflectionToStringBuilder.toString(condition, ToStringStyle.MULTI_LINE_STYLE));
            System.out.println(ReflectionToStringBuilder.toString(pageable, ToStringStyle.MULTI_LINE_STYLE));
            List<User> users = new ArrayList<User>();
            users.add(new User());
            users.add(new User());
            users.add(new User());
            return users;
        }
        
        @GetMapping("/{id:\d+}")
        @JsonView(User.UserDetailView.class)
        public User getInfo(@PathVariable(name = "id") String userid) {
            User user = new User();
            user.setId(userid);
            user.setUsername("Tom");
            return user;
        }
    
    }

      

  • 相关阅读:
    Jquery才可以使用 this 指定当前DOM
    微擎使用腾讯地图拾取坐标
    使用 MUI 自制 弹出层
    mui 底部导航栏
    PHP 向数组头部插入数据
    a 标签添加 onclick 事件
    # & 等特殊字符会导致传参失败
    HTML 颜色输入框修改事件的触发,以及获取修改后的颜色
    C++ malloc()函数的注意点及使用示例
    C++ malloc函数
  • 原文地址:https://www.cnblogs.com/wtrover/p/9522363.html
Copyright © 2011-2022 走看看