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, userGender等10个字段。可你的编辑功能因为需求,在某个特别的页面里只能修改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);

}

spring-in-action-day05-REST的更多相关文章

  1. 1、Spring In Action 4th笔记(1)

    Spring In Action 4th笔记(1) 2016-12-28 1.Spring是一个框架,致力于减轻JEE的开发,它有4个特点: 1.1 基于POJO(Plain Ordinary Jav ...

  2. spring in action 4th --- quick start

    读spring in action. 环境搭建 quick-start依赖注入 面向切面 1.环境搭建 jdk1.8 gradle 2.12 Intelij idea 2016.2.1 1.1创建一个 ...

  3. ssh整合随笔(注解方式,Spring 管理action)

    Web.xml<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi=" ...

  4. Spring in action记录

    最近一段时间重新学习了一遍SPRING,现在对这些笔记整理一下,一来算是对之前的学习有一个交代,二来当是重新学习一次,三来可以留下备份 这次学习中以SPRING IN ACTION 4这学习资料,整书 ...

  5. Spring in Action 4th 学习笔记 之 AOP

    前提:本文中的AOP仅限于Spring AOP. 先说说为什么需要AOP 最简单的一个例子就是日志记录,如果想记录一些方法的执行情况,最笨的办法就是修改每一个需要记录的方法.但这,真的很笨... 好的 ...

  6. 学习spring in action 第一天

    这段时间,开始学习java吧,因为C sharp 学习了java的大量语法格式,所以,留意下,就不会错了,java 有的c sharp也有,而且之前我也学习过java的桌面开发,但是一下子上来就要自己 ...

  7. spring in action学习笔记十五:配置DispatcherServlet和ContextLoaderListener的几种方式。

    在spring in action中论述了:DispatcherServlet和ContextLoaderListener的关系,简言之就是DispatcherServlet是用于加载web层的组件的 ...

  8. spring in action 学习笔记十四:用纯注解的方式实现spring mvc

    在讲用纯注解的方式实现springmvc之前先介绍一个类:AbstractAnnotationDispatcherServletInitializer.这个类的作用是:任何一个类继承AbstractA ...

  9. spring in action 学习十一:property placeholder Xml方式实现避免注入外部属性硬代码化

    这里用到了placeholder特有的一个语言或者将表达形式:${},spring in action 描述如下: In spring wiring ,placeholder values are p ...

  10. spring in action学习笔记一:DI(Dependency Injection)依赖注入之CI(Constructor Injection)构造器注入

    一:这里先说一下DI(Dependency Injection)依赖注入有种表现形式:一种是CI(Constructor Injection)构造方法注入,另一种是SI(Set Injection) ...

随机推荐

  1. ANSYS安装教程

    ANSYS 16.0 WIN10 64位安装步骤:1.使用"百度网盘客户端"下载ANSYS 16.0软件安装包到电脑磁盘里全英文名称文件夹内,安装前先断开网络,然后找到ANSYS. ...

  2. 【云原生 · Kubernetes】Taint和Toleration(污点和容忍)

    个人名片: 因为云计算成为了监控工程师‍ 个人博客:念舒_C.ying CSDN主页️:念舒_C.ying Taint和Toleration(污点和容忍) 概念 添加多个tainit(污点) 使用例子 ...

  3. PGL图学习之图神经网络ERNIESage、UniMP进阶模型[系列八]

    PGL图学习之图神经网络ERNIESage.UniMP进阶模型[系列八] 原项目链接:fork一下即可:https://aistudio.baidu.com/aistudio/projectdetai ...

  4. ES系列二之常见问题解决

    上篇ES系列一之java端API操作结束后本以为就相安无事了,但生产的问题是层出不穷的:下面我就再记录下近几周遇到的问题以及解决方案: 一 更新ES信息报错 报错信息如下: Use Elasticse ...

  5. ArcEngine 释放对象

    释放对象 例如IFeatureCursor,IFeatureClass等 ESRI.ArcGIS.ADF.ComReleaser.ReleaseCOMObject(myFeatureCursor); ...

  6. day18 批量查询与模糊查询 & 聚合函数与内置函数 & distinct关键字 & 分页查询limit & 排序order

    day18 两个表student和user student id s_name s_age s_sex user id u_name u_age u_sex 批量插入 insert into stud ...

  7. 【ASP.NET Core】MVC控制器的各种自定义:特性化的路由规则

    MVC的路由规则配置方式比较多,咱们用得最多的是两种: A.全局规则.就是我们熟悉的"{controller}/{action}". app.MapControllerRoute( ...

  8. GitOps实践之kubernetes安装argocd

    1. 什么是argocd 1.Argo CD是Kubernetes的一个声明性GitOps持续交付工具. 2.应用程序定义.配置和环境应该是声明性的和版本控制的.应用程序部署和生命周期管理应自动化.可 ...

  9. C语言条件语句中调用函数并赋值时的一个小坑

    在C语言中,如果在条件语句中赋值,一定要注意符号优先级的问题,比较符号是比赋值符号先执行的.如果同时还调用函数,并将返回值赋给变量,更容易产生错误. 看下面的代码: int increase(int ...

  10. 玩转 Go 生态|Hertz WebSocket 扩展简析

    WebSocket 是一种可以在单个 TCP 连接上进行全双工通信,位于 OSI 模型的应用层.WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据.在 W ...