美文网首页IT@程序员猿媛想法Java架构技术进阶
请君入坑:RESTFul设计风格(二)

请君入坑:RESTFul设计风格(二)

作者: 程就人生 | 来源:发表于2019-05-06 23:33 被阅读4次

    往期回顾:

    请君入坑:RESTFul设计风格(一)

                                                                          ① 

    简单使用,并不能解决实际开发中的问题,今天还得继续深入一下,被迫式深入。在上篇文章中,可以用@RestController代替@Controller+@ResponseBody,每个方法上面少写了不少@ResponseBody注解。

    昨天的示例代码中,每个方法的注解还是用@RequestMapping....,这样写是不是太low了呢?

    图-1

    这种写法是针对Spring4.3以前版本的,Spring4.3以后的版本可以直接用对应的@PostMapping、@GetMapping、@PutMapping、@DeleteMapping代替,后面的method都省掉了,替换之后的代码看起来是不是有简洁了许多呢。

    图-2

    在使用@RestController注解后,如果还是使用老式开发,也就是前后端不是分离的,在返回到具体的页面时,就不能用字符串指定具体的页面,用字符串指定,只会原样输出,这时可以使用ModelAndView来捆绑到指定视图。

                                                                                   ② 

    昨天还提到一个问题,如果不用第三方模拟器,比如不使用API POST,是否还能够对POST、PUT、DELETE这三个方法进行测试呢,当然可以。REST设计风格中提供了REST Templete,使用REST Templete可对REST风格的URI发起请求。

    /**

     * RESTFul风格代码示范

     * @author程就人生

     *

     */

    @RequestMapping("/user")

    @RestController

    publicclass UserController {

        /**

         * 新增(CREATE)

         * @param user

         * @return

         */

        @PostMapping(value="/save")

        public String save(User user) {

        System.out.println("数据库持久层操作 save方法");

        returnuser.getUserMobile();

        }

        /**

         * 修改(UPDATE)

         * @param userUid

         * @param user

         * @return

         */

        @PutMapping(value="/{userUid}")

        public String update(@PathVariable String userUid,@RequestBody User user) {

        System.out.println("数据库持久层操作修改方法");

        returnuserUid;

        }

        /**

         * 删除数据(DELETE)

         * @param userUid

         * @return

         */

        @DeleteMapping(value="/{userUid}")

        public String delete(@PathVariable String userUid) {

        System.out.println("数据库持久层操作删除方法");

            returnuserUid;

        }

        /**

         * 查询单条数据(VISIT)

         * @param userUid

         * @return

         */

        @GetMapping(value="/{userUid}")

        public String info(@PathVariable String userUid) {

        System.out.println("数据库查询操作查询方法");     

        returnuserUid;

        }  

    }

    上面这段代码,对返回值进行了修改,返回值统一为String类型,下面是测试代码:

    importorg.junit.Test;

    importorg.junit.runner.RunWith;

    importorg.springframework.boot.test.context.SpringBootTest;

    importorg.springframework.http.HttpEntity;

    importorg.springframework.http.HttpHeaders;

    importorg.springframework.http.MediaType;

    importorg.springframework.test.context.junit4.SpringRunner;

    importorg.springframework.web.client.RestTemplate;

    importcom.example.demo.bean.User;

    /**

     * 测试类

     * @author程就人生

     *

     */

    @RunWith(SpringRunner.class)

    @SpringBootTest

    publicclass TestRest {

        @Test

        publicvoid contextLoads() {

            //实例化

            RestTemplate restTemplate = new RestTemplate();  

            //GET方法测试

            String url = "http://localhost:8701/user/{userUid}";    

            String userUid = "123456";    

            //String.class是返回值类型,返回值类型一定要和被请求方法返回值类型一致,特别注意!!!!

            restTemplate.getForEntity(url, String.class, userUid);

            //POST方法测试

            url = "http://localhost:8701/user/save";

            User user = new User();

            user.setUserMobile("55555555");

            //将请求的实体和header头设置一下

            HttpHeaders headers = new HttpHeaders();

            //设置请求内容为json类型

            headers.setContentType(MediaType.APPLICATION_JSON_UTF8);

            HttpEntity<User> httpEtity = new HttpEntity<>(user, headers);       

            restTemplate.postForEntity(url, httpEtity, String.class);

            //PUT方法测试

            url = "http://localhost:8701/user/{userUid}";

            user = new User();

            user.setUserMobile("6666666666");

            user.setCloudfishCode("ccccccc");

            headers = new HttpHeaders();

            //设置请求内容为json类型

            headers.setContentType(MediaType.APPLICATION_JSON_UTF8);

            httpEtity = new HttpEntity<User>(user,headers);

            //实体类接收不到参数时,需要给接收实体增加@RequestBody注解,特别注意!!!

            restTemplate.put(url, httpEtity, userUid);

            restTemplate.delete("http://localhost:8701/user/{userUid}", userUid);

        }

    }

    在用REST Template测试的过程中,PUT方法出现的问题较多,以下是注意事项:

    1.Headers头必须设置

    2.实体对接接收不到参数时,需要加@RequestBody注解

    3.在SpringBoot集成时,PUT方法是接收不到参数的,只能增加配置文件,配置文件如下,两种配置文件,加其中的一种即可:

    第一种配置:

    importorg.springframework.stereotype.Component;

    importorg.springframework.web.filter.HttpPutFormContentFilter;

    /**

     * 或者使用:@Component,其实原理都是一样,就是开启:HttpPutFormContentFilter

     * @author 87620

     *

     */

    @Component

    publicclass PutFilter extendsHttpPutFormContentFilter{

    }

    第二种配置:

    importorg.springframework.context.annotation.Bean;

    importorg.springframework.context.annotation.Configuration;

    importorg.springframework.web.filter.HttpPutFormContentFilter;

    importorg.springframework.web.servlet.config.annotation.EnableWebMvc;

    importorg.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

    /**

     * 使用@bean注解

     * @author 87620

     *

     */

    @Configuration

    @EnableWebMvc

    publicclass WebMvcConfig extendsWebMvcConfigurerAdapter{

      // 就是这个

      @Bean

      publicHttpPutFormContentFilterhttpPutFormContentFilter() {

          returnnewHttpPutFormContentFilter();

      }

    }

    为了保险起见,又用了API POST对PUT方法测试,这个工具是不能加@RequestBody的,加了之后会报415错误,如下图所示:

    图-3

    在实际的表单请求环境中,还没试过是什么情况,还需要进一步踩坑,实在不行的话,还是把@PutMapping注解换回原来的@RequestMapping吧,省掉还要配置其他的文件,新加的配置文件都被标注过期了,这个看起来也不太好。

    说到命名规则,上文中的新增操作user后面是个save,save本身是动词,就不符合RESTFul规范,这个还需要改一改。(知错就改才是个好孩子,哈哈)

    时间匆忙,RESTTemplate测试方法也写的很狼狈,RESTFul风格中对于REST方法的返回值也做了进一步的封装,明天继续。

    相关文章

      网友评论

        本文标题:请君入坑:RESTFul设计风格(二)

        本文链接:https://www.haomeiwen.com/subject/veajoqtx.html