• SpringBoot系列: 与Spring Rest服务交互数据


    不管是单体应用还是微服务应用, 现在都流行Restful风格,  下图是一个比较典型的使用rest的应用架构, 该应用不仅使用database数据源, 而且用到了一个Weather微服务, 另一方面, 该应用也是通过rest方式为web UI 或其他微服务应用提供服务. 

    =============================
    通过Postman 插件测试Rest接口
    =============================

    之前使用postman 插件调试rest接口总报 415 Unsupported Media Type错误, 原因是: HEADERS中必须设置Content-type为application/json, 后台才能顺利接收到参数. 见下图截图. 
    {
    "timestamp": "2018-09-07T06:49:57.620+0000",
    "status": 415,
    "error": "Unsupported Media Type",
    "message": "Content type 'text/plain;charset=UTF-8' not supported",
    "path": "/books"
    }

    =============================
    与 Rest 服务交互的几个环节
    =============================

    一. Spring 后台与其他Rest服务的数据交互
    Spring 提供了 RestTemplate 类, 方便和其他Rest服务交互数据


    二. 在web response中 返回 json 数据
    对于Restful的视图方法, 其返回类型可以是 ResponseEntity<T> 或者 ResponseEntity<List<T>>, Spring会自动将返回值转换为json格式. 如果要输出多个对象的复合体json, 可以在java中定义一个Wrapper类组合多个Pojo类, 然后返回这个Wrapper对象即可.

    三. 接收 web Request 中的 json 数据
    视图方法的 @RequestBody 注释参数可以是Map类型, 也可以是Pojo类型. 如果是Pojo类型, Spring就自动完成json->object的转换, 如果是map类型, Spring就自动完成kv映射. 如果json数据是多个object的某种组合, 我们可以在java中定义一个Wrapper类组合多个Pojo类, 专门接收 Request 中的json数据.

    =============================
    示例代码
    =============================

    Pojo代码:

    class Office {
        private String address;
    
        public String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    }
    
    class Car {
        private String brand;
    
        public String getBrand() {
            return brand;
        }
    
        public void setBrand(String brand) {
            this.brand = brand;
        }
    }
    
    /*
     * Boss 类是 Office 和 Office 类的组合
     */
    class Boss {
        private Car car;
        private Office office;
    
        public Car getCar() {
            return car;
        }
    
        public void setCar(Car car) {
            this.car = car;
        }
    
        public Office getOffice() {
            return office;
        }
    
        public void setOffice(Office office) {
            this.office = office;
        }
    }

    Controller和主函数代码:

    @SpringBootApplication
    @RestController
    public class Demo1Application {
    
        // 示例: 一个对象的json response
        // 测试url为 http://localhost:8080/oneOffice
        // 结果为 {"address":"address1"}
        @ResponseBody
        @RequestMapping(value = "/oneOffice", method = RequestMethod.GET)
        public ResponseEntity<Office> oneOffice() {
            Office office = new Office();
            office.setAddress("address1");
            return new ResponseEntity<Office>(office, HttpStatus.OK);
        }
    
        // 示例: 一个集合的json response
        // 测试url为 http://localhost:8080/offices
        // 结果为 [{"address":"address1"},{"address":"address2"}]
        @ResponseBody
        @RequestMapping(value = "/offices", method = RequestMethod.GET)
        public ResponseEntity<List<Office>> offices() {
            List<Office> offices = new ArrayList<Office>();
            Office office1 = new Office();
            office1.setAddress("address1");
            Office office2 = new Office();
            office2.setAddress("address2");
            offices.add(office1);
            offices.add(office2);
            return new ResponseEntity<List<Office>>(offices, HttpStatus.OK);
        }
    
        // 示例: 一个简单对象的 Post 示例
        // 测试url为 http://localhost:8080/offices
        // 提交的data为  { "address": "address1" }
        @RequestMapping(value = "/offices", method = RequestMethod.POST, consumes = "application/json")
        @ResponseBody
        public String createOffice(@RequestBody Office office) {
            if (office != null && office.getAddress() != null) {
                return "OK";
            } else {
                return "Empty";
            }
        }
    
        // 示例: 一个组合对象的 response 示例
        // 测试url为  http://localhost:8080/oneBoss
        // 结果为  {"car":null,"office":{"address":"address1"}}
        @RequestMapping(value = "/oneBoss", method = RequestMethod.GET)
        @ResponseBody
        public ResponseEntity<Boss> oneBoss() {
            Office office = new Office();
            office.setAddress("address1");
            Boss objectWrapper = new Boss();
            objectWrapper.setOffice(office);
            return new ResponseEntity<Boss>(objectWrapper, HttpStatus.OK);
        }
    
    
        // 示例: 一个组合对象的 Post 示例
        // 测试url为 http://localhost:8080/bosses
        // 提交的data为  {"car":null,"office":{"address":"address1"}}
        @RequestMapping(value = "/bosses", method = RequestMethod.POST, consumes = "application/json")
        @ResponseBody
        public String createBoss(@RequestBody Boss boss) {
            if (boss != null && boss.getOffice() != null
                    && boss.getOffice().getAddress() != null) {
                return "OK";
            } else {
                return "Empty";
            }
        }
    
    
        public static void main(String[] args) {
            SpringApplication.run(Demo1Application.class, args);
        }
    }

    =========================
    参考
    =========================
    https://www.leveluplunch.com/java/tutorials/014-post-json-to-spring-rest-webservice/
    https://javabeat.net/rest-api-best-practices/
    https://www.baeldung.com/building-a-restful-web-service-with-spring-and-java-based-configuration
    截图来自: https://github.com/hamvocke/testing-microservices-ebook/blob/master/testing-microservices.adoc

  • 相关阅读:
    在jQuery中Ajax的Post提交中文乱码的解决方案
    mysql 日期时间型的按日期分组
    mysql 逗号分隔的id转为逗号分隔的名称
    阿米在日本工作生活趣事(2)
    阿米在日本工作生活趣事(1)
    com.mysql.jdbc.exceptions.jdbc4.MySQLTransactionRollbackException: Lock wait timeout exceeded; try restarting transaction
    File exists.If no other git process is currently running,
    带小数点的String 转int java.lang.Double cannot be cast to java.lang.Integer
    Jboss解决只能通过localhost访问而不能使用IP访问项目的问题
    This method accesses the value of a Map entry, using a key that was retrieved from a keySet iterator. It is more efficient to use an iterator on the entrySet of the map, to avoid the Map.get(key) look
  • 原文地址:https://www.cnblogs.com/harrychinese/p/Springboot_SpringRest.html
Copyright © 2020-2023  润新知