zoukankan      html  css  js  c++  java
  • spring-in-action-day05-REST

    1.创建RESTFUL端点

      (1)创建get端点

      (2)创建post端点

      (3)创建put/patch端点

      (4)创建delete端点

    2.启用超媒体

    3.消费REST端点

      3.1使用RestTemplate消费端点

        (1)消费get端点

        (2)消费put端点

        (3)消费delete端点

        (4)消费post端点

          (5)   Resttemplate设置连接超时

      3.2使用Traverson导航超媒体REST API

    1.创建RESTFUL端点

      (1)创建get端点

    package tacos.web;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Optional;
    
    import org.springframework.http.HttpStatus;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.CrossOrigin;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import tacos.User;
    
    @org.springframework.web.bind.annotation.RestController 
    //@RestController 1.表示是controller组件 2.告诉spring所有的返回数据都会被写入响应体中-类似@responsebody的作用 @RequestMapping(value="/design",produces="application/json")
    //@RequestMapping 1.指定路径 2.指定返回的格式-这里可以是一个数组,包含多种格式produces={"application/json,text/xml}" @CrossOrigin(origins="*") //允许所有跨域请求 public class RestController { @GetMapping(value="recent/{id}",produces="application/json")
          //@GetMapping 1.指定get请求 2.指定路径 3.指定请求Accept必须有application/json public ResponseEntity<List<User>> recentTacos(@PathVariable("id") Integer id) { //获取数据li List<User> li = new ArrayList<User>(); if(li != null && li.size() > 0){ return new ResponseEntity<>(li,HttpStatus.OK) ;
                  //返回 ResponseEntity对象,可以自己定义状态码,在结果为空的情况下,返回null或者空集合不合适,就可以这样返回NOT_FOUND的状态码 }else{ return new ResponseEntity<>(li,HttpStatus.NOT_FOUND) ; } } //这个控制器智慧处理 /design/recent/{id}的get请求 {id}是参数占位符     //请求访问http://localhost:8080/design/recent/1 }

       (2)创建post端点

        

      @PostMapping(value="recent",consumes="application/json")     
        //@PostMapping 1.指定post请求 2.指定路径 3指定请求Content-Type属性是application/json @ResponseStatus(HttpStatus.CREATED)
        //@ResponseStatus当成功时,返回的状态码是201CREATED而不是200,这样描述的更清楚,表示请求不但成功,而且创建了一个资源 public User recentTacos(@RequestBody User user) { //@RequestBody 将请求的参数绑定到User对象 //保存数据 return user; } //值得注意的@ResponseStatus(HttpStatus.CREATED),更符合rest标准

      (3)创建put/patch端点

        1)为什么会有put和patch两种更新呢?

          PATCH方法是新引入的,是对PUT方法的补充,用来对已知资源进行局部更新

          假设我们有一个UserInfo,里面有userId userName userGender10个字段。可你的编辑功能因为需求,在某个特别的页面里只能修改userName,这时候的更新怎么做?

          人们通常(为徒省事)把一个包含了修改后userName的完整userInfo对象传给后端,做完整更新。但仔细想想,这种做法感觉有点二,而且真心浪费带宽

          于是patch诞生,只传一个userName到指定资源去,表示该请求是一个局部更新,后端仅更新接收到的字段。

          而put虽然也是更新资源,但要求前端提供的一定是一个完整的资源对象,理论上说,如果你用了put,但却没有提供完整的UserInfo,那么缺了的那些字段应该被清空

          也就是说put是对一个对象的所有属性进行更新,没有传来的属性用null替代。

          最后再补充一句,restful只是标准,标准的意思是如果在大家都依此行事的话,沟通成本会很低,开发效率就高。但并非强制(也没人强制得了)。

          所以你说在你的程序里把方法名从put改成patch没有任何影响,那是自然,因为你的后端程序并没有按照标准对两个方法做不同处理,那也不影响程序的运行

        2)PUT端点

        

      @PutMapping(value="recent",consumes="application/json")    
        //
    @PutMapping 1.指定put请求 2.指定路径 3指定请求Content-Type属性是application/json public User putrecentTacos(@RequestBody User user) { //@RequestBody 将请求的参数绑定到User对象 //更新数据 return user; }

     

        3)PATCH端点

          

      @PatchMapping(value="recent",consumes="application/json")    
        //@PatchMapping 1.指定patch请求 2.指定路径 3指定请求Content-Type属性是application/json public User patchrecentTacos(@RequestBody User user) { //@RequestBody 将请求的参数绑定到User对象 //局部更新数据 if(user.getList() != null){ //更新list } if(user.getUsername() != null){ //更新username } if(user.getPassword() != null){ //更新password } return user; } //可以看到PUT直接把user整体进行更新,而PATCH只对接收到的属性进行局部更新

        (4)创建delete端点

        

       @DeleteMapping(value="recent/{id}")    //@DeleteMapping 1.指定delete请求 2.指定路径3.指定参数占位符
        @ResponseStatus(HttpStatus.NO_CONTENT) //由于删除后没有资源返回所有我们返回状态码HttpStatus.NO_CONTENT 204清 晰的表示资源已不存在,而不是返回200仅表示成功
        public void patchrecentTacos(@PathVariable("id") Integer id) { //@PathVariable将参数占位符绑定到方法参数上
            //根据id删除
    }

    2.启用超媒体(不详细说明)

      hateoas

    3.消费REST端点

      (1)使用RestTemplate消费rest端点

        1)消费get端点

        被消费的端点  

    private RestTemplate temp = new RestTemplate(); //为了简便这里是直接创建-也可以注入获取对象

    @RequestMapping(value="orgdetail/{orgid}") @ResponseBody public Organization findOrgDetail(@PathVariable("orgid") Integer orgid,HttpServletResponse resp) { //获取数据li System.out.println("id=" + orgid); return new Organization(1,"机构" + orgid); }

        消费方法1-仅获取返回值

    @GetMapping(value="mygetrest") 
         public void mygetrest() {
            System.out.println("haha");
            Integer id = 1;
            //temp.getMessageConverters().add(new MyHttpMessageConverter());
            Organization forObject = temp.getForObject("http://localhost:8080/design/orgdetail/{orgid}",Organization.class,id );
        //参数1:路径,参数2,返回值类型,参数3:请求参数
            System.out.println("jieguo:" + forObject.toString());
            //jieguo:Organization [orgid=1, orgname=机构1]
        }

        消费方法2-获取返回值和其它信息

        @GetMapping(value="mygetrest2") 
         public void mygetrest2() {
            Integer id = 1;
              //temp.getMessageConverters().add(new MyHttpMessageConverter());
            ResponseEntity<Organization> entity = temp.getForEntity("http://localhost:8080/design/orgdetail/{orgid}",Organization.class,id );
          //参数1:路径,参数2,返回值类型,参数3:请求参数
            System.out.println("body:" + entity.getBody());
          //body:Organization [orgid=1, orgname=机构1]
            System.out.println("date:" + entity.getHeaders().getDate());
          //date:1600856875000
            System.out.println("header:" + entity.getHeaders());
          //header:{Content-Type=[application/json;charset=UTF-8], Transfer-Encoding=[chunked], Date=[Wed, 23 Sep 2020 10:27:55 GMT]}
    
        }

         2)消费put端点

          被消费的端点

      @PutMapping(value="recent",consumes="application/json")    //@PutMapping 1.指定put请求 2.指定路径 3指定请求Content-Type属性是application/json
        public void putrecentTacos(@RequestBody User user) { //@RequestBody 将请求的参数绑定到User对象
            //整体更新数据
            user.setUsername("gxin");
            System.out.println(user.getUsername());
        }

          消费

    @GetMapping(value="Myrecent")    
        public void Myrecent() { 
    
            
            User u = new User();
            u.setId(1L);
            u.setUsername("keyi");
            System.out.println("调用put方法");
            temp.put("http://localhost:8080/design/recent", u);
            
        }
        
    //temp.put没有返回值

        3)消费delete端点

          被消费的端点

       @DeleteMapping(value="/{id}")    //@DeleteMapping 1.指定delete请求 2.指定路径3.指定参数占位符
        @ResponseStatus(HttpStatus.NO_CONTENT) //由于删除后没有资源返回所有我们返回状态码HttpStatus.NO_CONTENT 204清 晰的表示资源已不存在,而不是返回200仅表示成功
        public void patchrecentTacos(@PathVariable("id") Integer id) { //@PathVariable将参数占位符绑定到方法参数上
            //根据id删除
            System.out.println(id);
        }

          消费

    @GetMapping(value="Mydelete")    
        public void Mydelete() { 
            System.out.println("调用delete方法");
            temp.delete("http://localhost:8080/design/{id}", 11); 
    //参数1:路径 参数2:请求的参数
            
        }
    //temp.delete没有返回值

        4)消费post端点

          被消费的端点

    @PostMapping(value="recent",consumes="application/json")    //@PostMapping 1.指定post请求 2.指定路径 3指定请求Content-Type属性是application/json
        @ResponseStatus(HttpStatus.CREATED) //@ResponseStatus当成功时,返回的状态码是201CREATED而不是200,这样描述的更清楚,表示请求不但成功,而且创建了一个资源
        public User recentTacos(@RequestBody User user) { //@RequestBody 将请求的参数绑定到User对象
            //保存数据
            return user;
            
        }

          消费方法1

          

    @GetMapping(value="MyPost")    
        public void MyPost() {     
            User u = new User();
            u.setId(1L);
            u.setUsername("keyi");
            System.out.println("调用put方法");
            User postForObject = temp.postForObject("http://localhost:8080/design/recent", u,User.class); 
            //参数1:路径  ,参数2:post请求参数 ,参数3:返回值class
            System.out.println(postForObject.getUsername());
            
        }

          消费方法2

    @GetMapping(value="MyPost2")    
        public void MyPost2() { 
            //整体更新数据
            
            User u = new User();
            u.setId(1L);
            u.setUsername("keyi");
            System.out.println("调用put方法");
            ResponseEntity<User> postForEntity = temp.postForEntity("http://localhost:8080/design/recent", u,User.class); 
            //参数1:路径  ,参数2:post请求参数 ,参数3:返回值class
            System.out.println(postForEntity.getBody().getUsername());
            
        }

        5)设置连接超时

         方法一:配置类,之后直接注入获取RestTemplate实例 

    @Configuration 
    public class AppConfig{
    @Bean
    public RestTemplate customRestTemplate(){
    HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
    httpRequestFactory.setConnectionRequestTimeout(3000);
    httpRequestFactory.setConnectTimeout(3000);
    httpRequestFactory.setReadTimeout(3000);
    
    return new RestTemplate(httpRequestFactory);
    }
    }

          方法2:配置属性+配置类

        

    属性配置
    custom.rest.connection.connection-request-timeout=3000
    custom.rest.connection.connect-timeout=3000
    custom.rest.connection.read-timeout=3000
    
    配置类
    @Configuration
    public class AppConfig{
    @Bean
    @ConfigurationProperties(prefix = "custom.rest.connection")
    public HttpComponentsClientHttpRequestFactory customHttpRequestFactory() {
        return new HttpComponentsClientHttpRequestFactory();
    }
    
    @Bean
    public RestTemplate customRestTemplate(){
        return new RestTemplate(customHttpRequestFactory());
    }
    }

     <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
            </dependency>

     (2)使用Traverson导航超媒体REST API

      知道有这个东西就好,不做说明了

    @RequestMapping(value="orgdetail/{orgid}")
    
    @ResponseBody
    
     public Organization findOrgDetail(@PathVariable("orgid") Integer orgid,HttpServletResponse resp) {
    
    //获取数据li
    
    System.out.println("id=" + orgid);
    
    return new Organization(1,"机构" + orgid);
    
    }
  • 相关阅读:
    应用程序域的用法
    WCF 暴露元数据的配置
    无svc文件发布WCF服务到IIS上
    C#输出毫秒
    [一点一滴学英语]20051017
    从其他平台转向Windows,MS提供了很多便利;那反过来呢?
    Ward Cunningham加入Eclipse?
    [导入][链接]Linux常用命令/快捷键
    [导入][号外]Oracle to buy JBoss, Zend and Sleepycat?
    [导入][链接]Google开始向Linux移植其Windows应用程序?
  • 原文地址:https://www.cnblogs.com/jthr/p/13728890.html
Copyright © 2011-2022 走看看