什么是REST风格:

Representational State Transfer :表现层状态转换,实际上是一种风格。标准,约定

首先需要有资源才能表现, 所以第一个名词是“ 资源”。有了资源也要根
据需要以合适的形式表现资源,这就是第二个名词一一表现层。最后是资源可以被新增、修改、删
除等,也就是第三个名词“状态转换”。

资源: 它可以是系统权限用户、角色和菜单等,也可以是一些媒体类型, 如文本、图片、歌曲,总之它就是一个具体存在的
对象。可以用一个URI ( Unifonn Resource Identifier ,统一资源定位符)指向它, 每个资源对应一个特定的U阳。
要获取这个资源, 访问它的U阳即可,而在REST 中每一个资源都会对应一个独一无二的U阻。在阻ST 中, URI 也可以称
为端点(End Point ) 。
表现层: 有了资源还需要确定如何表现这个资源。例如, 一个用户可以使用JSON 、XML 或者其他的形式表现出来,又如
可能返回的是一幅图片。在现今的互联网开发中, JSON 数据集己经是一种最常用的表现形式

REST风格当中,每一个资源都只是对应一个网址,而一个资源网址应该是一个名词,不存在动词。

URI (Unifonn Resource Identifier)统一资源定位符

REST风格其实就是一种约定问题,不同的http请求对应的不同的资源操作,

@GetMapping

/**
* RestController,作用是使返回的结果能够以json数据集的方法进行返回
* 转换为JSTL或者json
* 11默认将方法或者类标注为application/json;charset=UTF-8
* 22方法执行结束后,spring会遍历注册号的HttpMessageConverter接口
* 的实现类。
* 33注册好的MappingJackson2HttpMessageConverter就会放回true,
* 启动转换器将结果转换为JSON数据集
*/
@RestController
@RequestMapping("annotation")
public class RedisUserController {
@Autowired
private UserService userService =null; /**
* http的get请求,获取资源
* @param id
* @return
*/
@GetMapping("/{id}")
public User getUser(@PathVariable("id") Long id){
System.out.println(System.currentTimeMillis());
User user = userService.getUser(id);
System.out.println(System.currentTimeMillis());
return user;
}

请求:

@PostMapping

   /**
* http的post请求,创建资源
* @param userName
* @param note
* @return
*/
@PostMapping()
public User insertUser(
@RequestParam ("userName") String userName,
@RequestParam ("note") String note
){
User user = new User();
user.setUserName(userName);
user.setNote(note);
userService.insertUser(user);
return user;
}

请求结果;

@DeleteMapping

 /**
* http的Delete请求,删除服务器资源
* @param id
* @return
*/
@DeleteMapping("{id}")
public int delUser(@PathVariable("id") Long id){
return userService.deleteUser(id);
}

从数据库中删除了id为44员工

@PutMapping

@PatchMapping

  /**
* http Put请求,提交所有的资源属性以修改资源,
* http patch请求,提交资源的部分修改属性,
* 其实他们两个都差不多,只不过是约定的问题而已
* @param id
* @param userName
* @return
*/
@PatchMapping("/user/{id}")
public User updUser(
@PathVariable("id") Long id,
@RequestParam("userName") String userName
){
return userService.updateUser(id,userName);
}

修改之前的:

处理HTTP请求状态码,异常和响应头

通过实体类去实现;

/**
* 当发生资源找不到或者处理逻辑发生异常时,需要考虑返回给客户端的http状态码和错误消息
* spring提供实体封装类ResponseEntity:有效的封装错误消息和状态码
* 和注解@ResponseStatus:配置指定的响应码给客户端
*/
@RestController
public class HttpStatusController {
@Autowired
UserService userService; /**
* 11新建一个请求头对象,
* 22向请求头通过add方法进行加入k-v
* 33需要建立一个响应实体类,将需要放回的信息,请求头对象,响应http状态码
* 备注:这里使用 HttpStatus.CREATED ,指定状态码为201,标识资源创建成功
* @param userName
* @param note
* @return
*/
@PostMapping("/http/status")
public ResponseEntity<Integer> insertUser(
@RequestParam("userName") String userName,
@RequestParam ("note") String note
){
User user = new User();
user.setUserName(userName);
user.setNote(note);
Integer re = userService.insertUser(user);
// 设置http响应头
HttpHeaders httpHeaders = new HttpHeaders();//新建请求头
String success = (re == 0 ) ? "false" : "true";//如果结果为0,就是false
httpHeaders.add("success",success); return new ResponseEntity<Integer>(re,httpHeaders, HttpStatus.CREATED);
}

使用注解:

  /**
* 通过注解@ResponseStatus去指定
* 当方法正常返回的时候,http状态码为201
* @param userName
* @param note
* @return
*/
@PostMapping("/http/status/an")
@ResponseStatus(HttpStatus.CREATED)
public Integer insertUseran(
@RequestParam("userName") String userName,
@RequestParam ("note") String note
){
User user = new User();
user.setUserName(userName);
user.setNote(note);
Integer re = userService.insertUser(user); return re;
}
}

异常处理;

定义一个运行时的异常:

//场景:运行的时候,查询id用户,找不到数据或出现异常,这时候不能以正常返回去处理。
/**
* 11自定义异常类:找不到用户的时候抛出异常
* 异常抛出后,可以在控制器通知@ControllerAdvice里面进行处理
* @ControllerAdvice:定义控制器通知
* @ExceptionHandler:指定异常发生的处理方法
*继承的异常RuntimeException是指:运行时的异常,和我们普通的
* Exception:受检查的异常,这种异常是强制我们catch或throw的异常。
* 你遇到这种异常必须进行catch或throw,如果不处理,编译器会报错。
*
*/
public class NotFoundException extends RuntimeException{
public static final long serialVersionUID = 1L; private Long code;//异常编码
private String customMsg;//异常自定义消息 public NotFoundException() {
} public NotFoundException(Long code, String customMsg) {
super();
this.code = code;
this.customMsg = customMsg;
} public Long getCode() {
return code;
} public void setCode(Long code) {
this.code = code;
} public String getCustomMsg() {
return customMsg;
} public void setCustomMsg(String customMsg) {
this.customMsg = customMsg;
}
}

定义一个控制器通知:

/**
* 2自定义一个控制器通知
* 在@ControllerAdvice中指定拦截包路径,限定被拦截的注解为@Controller/@RestController
* 在@ExceptionHandler注解方法上,通过value属性,指定异常类型进行拦截
* 在@ResponseBody定义响应的信息已json的格式表达
* 在@ResponseStatus定义服务器内部错误500代码
*/
@ControllerAdvice(
basePackages = {"com.quan.annotationredis.controller.*"},
annotations = {Controller.class, RestController.class}
)
public class UserControllerAdvice {
@ExceptionHandler(value = NotFoundException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)//定义服务器错误代码
@ResponseBody
public Map<String,Object> exception(HttpServletRequest request,
NotFoundException ex){
Map<String,Object> msgMap = new HashMap<>();
msgMap.put("code",ex.getCode());
msgMap.put("message",ex.getCustomMsg());
return msgMap;
}
}

测试controller:

@Controller
public class ExceptionController { @Autowired
UserService userService; /**
* 一旦方法出现异常,就会别控制器通知所拦截,最后经@ExceptionHandler定义
* 的方法进行处理。
* @param id
* @return
*/
@GetMapping("/exception/{id}")
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public User getUser(@PathVariable("id") Long id){
System.out.println(System.currentTimeMillis());
User user = userService.getUser(id);
if (user == null){
throw new NotFoundException(1L,"找不到用户"+id+"的信息");
}
System.out.println(System.currentTimeMillis());
return user;
}
}

使用RestTemplate请求后端;

底层是通过类HttpURLConnection实现的。

    /**
* restTemplate.getForObject方法中:
* 第一个参数URL:标明请求服务器什么资源,{id}代表参数
* 第二个参数:表示将请求返回User类的结果,实际上服务器只会给回我们json格式数据
* 是因为restTemplate内部将其转化给java对象。
* 第三个参数:就是URL对应的参数。
* @return
*/
private static User getUser() {
int id = 1;
RestTemplate restTemplate = new RestTemplate();
User user = restTemplate.getForObject(
"http://localhost:8012/annotation/{id}",
User.class, id
);
System.out.println(user.getUserName());
return user;
}
}

输出的日志结果:

14:10:42.839 [main] DEBUG org.springframework.web.client.RestTemplate - HTTP GET http://localhost:8012/annotation/1
14:10:42.904 [main] DEBUG org.springframework.web.client.RestTemplate - Accept=[application/json, application/*+json]
14:10:42.921 [main] DEBUG org.springframework.web.client.RestTemplate - Response 200 OK
14:10:42.924 [main] DEBUG org.springframework.web.client.RestTemplate - Reading to [com.quan.annotationredis.entity.User]
gangganghao

多个参数的时候:

@RestController
@RequestMapping("annotation")
public class RedisUserController {
@Autowired
private UserService userService =null; @PostMapping("/{userName}/{note}")
public User insertUser(
@PathVariable ("userName") String userName,
@PathVariable ("note") String note
){
User user = new User();
user.setUserName(userName);
user.setNote(note);
userService.insertUser(user);
return user;
}

将参数用一个Map对象封装起来,Map的键名称和URI中所定义的参数时保持一致的。这样子就能将参数统一封装到Map中了

    /**
*因为我们的Controller层返回的是User类型,所以我们这里也放回User,并使用ResponseEntity<User>接受
* postForEntity ,通过post请求返回一个实体类,需要url,请求类型,返回类型,参数列表
* responseEntity.getBody();通过类的方法从返回体里面拿到返回体的内容。(contorller里面是返回user)
* @return
*/
public static User insertUser(){
RestTemplate restTemplate = new RestTemplate();
String userName = "huolalala";
String note = "huolalanote";
String url = "http://localhost:8012/annotation/{userName}/{note}"; Map<String,Object> params = new HashMap<>();
params.put("userName",userName);
params.put("note",note); ResponseEntity<User> responseEntity = restTemplate.postForEntity(url,User.class,User.class,params);
User user = responseEntity.getBody();
System.out.println(user);
return user;
}

运行日志;

14:55:47.888 [main] DEBUG org.springframework.web.client.RestTemplate - HTTP POST http://localhost:8012/annotation/huolalala/huolalanote
14:55:47.948 [main] DEBUG org.springframework.web.client.RestTemplate - Accept=[application/json, application/*+json]
14:55:47.966 [main] DEBUG org.springframework.web.client.RestTemplate - Writing [class com.quan.annotationredis.entity.User] with org.springframework.http.converter.json.MappingJackson2HttpMessageConverter
14:55:47.987 [main] DEBUG org.springframework.web.client.RestTemplate - Response 200 OK
14:55:47.990 [main] DEBUG org.springframework.web.client.RestTemplate - Reading to [com.quan.annotationredis.entity.User]
User{id=49, userName='huolalala', note='huolalanote'}

请求体获取参数:

  /**
* 11先定义请求头HttpHeaders,设置请求体为JSON格式
* 22将请求体实体user和请求头绑定到请求实体对象HttpEntiry
* 33restTemplate.postForObject将请求对象传递过去,
* @return
*/
public static User insertUser1(){
User user = new User();
user.setNote("RRRR");
user.setUserName("QQQQ"); HttpHeaders httpheaders = new HttpHeaders();
httpheaders.setContentType(MediaType.APPLICATION_JSON_UTF8); HttpEntity<User> httpEntity = new HttpEntity<>(user,httpheaders); RestTemplate restTemplate = new RestTemplate();
restTemplate.postForObject("http://localhost:8012/annotation",httpEntity,User.class); return user; }

删除:

    /**
*
*/
public static void delUser(){
Long id = 48L;
RestTemplate restTemplate = new RestTemplate();
String url = "http://localhost:8012/annotation/{id}";
restTemplate.delete(url,id);//这个方法没有返回值
}

运行日志:

17:09:06.618 [main] DEBUG org.springframework.web.client.RestTemplate - HTTP DELETE http://localhost:8012/annotation/48
17:09:06.639 [main] DEBUG org.springframework.web.client.RestTemplate - Response 200 OK

spring-boot-learning-REST风格网站的更多相关文章

  1. 使用Spring boot开发RestFul 风格项目PUT/DELETE方法不起作用

    在使用Spring boot 开发restful 风格的项目,put.delete方法不起作用,解决办法. 实体类Student @Data public class Student { privat ...

  2. Spring Boot构建 RESTful 风格应用

    Spring Boot构建 RESTful 风格应用 1.Spring Boot构建 RESTful 风格应用 1.1 实战 1.1.1 创建工程 1.1.2 构建实体类 1.1.4 查询定制 1.1 ...

  3. Spring Boot2 系列教程(三十一)Spring Boot 构建 RESTful 风格应用

    RESTful ,到现在相信已经没人不知道这个东西了吧!关于 RESTful 的概念,我这里就不做过多介绍了,传统的 Struts 对 RESTful 支持不够友好 ,但是 SpringMVC 对于 ...

  4. Vue + Spring Boot从零开始搭建个人网站(一) 之 项目前端Vue.js环境搭建

    前言: 最近在考虑搭建个人网站,想了想决定采用前后端分离模式 前端使用Vue,负责接收数据 后端使用Spring Boot,负责提供前端需要的API 就这样开启了我边学习边实践之旅 Vue环境搭建步骤 ...

  5. spring boot(3)-Rest风格接口

    Rest接口 虽然现在还有很多人在用jsp,但是其实这种动态页面早已过时,现在前端流行的是静态HTML+ rest接口(json格式).当然,如果是单台服务器,用动态还是静态页面可能没什么很大区别,但 ...

  6. Spring Boot 2.0 设置网站默认首页

    Spring Boot设置默认首页,方法实验OK如下 附上Application启动代码 /** * @ClassName Application * @Description Spring-Boot ...

  7. Spring Boot (2) Restful风格接口

    Rest接口 动态页面jsp早已过时,现在流行的是vuejs.angularjs.react等前端框架 调用 rest接口(json格式),如果是单台服务器,用动态还是静态页面可能没什么大区别,如果服 ...

  8. Spring boot——构建rest风格

    前言rest风格严格意义上说不是一种标准,而是一种风格,在如今互联网界,这个风格被广泛用于微服务系统之间的交互. REST简单介绍 REST(Representional State Transfer ...

  9. Spring Boot 之restful风格

    步骤一:restful风格是什么? 我们知道在做web开发的过程中,method常用的值是get和post.可事实上,method值还可以是put和delete等等其他值. 既然method值如此丰富 ...

  10. 一:Spring Boot、Spring Cloud

    上次写了一篇文章叫Spring Cloud在国内中小型公司能用起来吗?介绍了Spring Cloud是否能在中小公司使用起来,这篇文章是它的姊妹篇.其实我们在这条路上已经走了一年多,从16年初到现在. ...

随机推荐

  1. HTTP攻击与防范-跨网站脚本攻击

    实验目的 1.了解XSS -跨网站脚本攻击带来的危险性. 2.掌握XSS -跨网站脚本攻击的原理与方法 3.掌握防范攻击的方法 实验原理 跨网站脚本攻击之所以会发生,是因为网站的Web应用程序对用户的 ...

  2. [题解]UVA10986 Sending email

    链接:http://vjudge.net/problem/viewProblem.action?id=24941 描述:n个点,m条边的无向图,寻找从S到T的最短路. 思路:基础的单源点最短路 用Di ...

  3. 企业如何建立一体化数据分析平台?还是得说说那几家BI工具

    近年来,BI工具和报表工具犹如一股春风,吹遍了大江南北,成为了众多企业的发展利器,受到了企业决策者的拥戴.同时,在企业信息化需求日益旺盛的市场里也孕育了不少BI工具与报表工具厂商.商业智能的应用在国外 ...

  4. python+pytest接口自动化(1)-接口测试基础

    接口定义 一般我们所说的接口即API,那什么又是API呢,百度给的定义如下: API(Application Programming Interface,应用程序接口)是一些预先定义的接口(如函数.H ...

  5. 【C#】String| StringBuilder 字符

    原文链接:https://www.cnblogs.com/huameitang/p/10528646.html 字符串是用于表示文本的字符的有序集合. String对象是对象的有序集合 System. ...

  6. 由浅入深--第一个MyBatis程序

    话不多说,马上开始我们的第一个Mybatis程序: 第一个程序,当然要参考MyBatis的官网文档来搞,地址如下:https://mybatis.org/mybatis-3/zh/getting-st ...

  7. 如何修改oracle数据库用户密码过期策略

    转至:https://www.cnblogs.com/zhangshuaihui/p/11451590.html 1.   查询数据库用户何时过期 登陆数据库PL/SQL工具,输入以下sql语句: s ...

  8. HTML学习如何布局

    <!DOCTYPE html><html><head> <meta charset="utf-8"> <title>菜鸟 ...

  9. SpringCloudStream(RabbitMQ&Kafka)&Spring-Kafka配置使用

    目录 是什么 解决问题 使用方式 创建生产者项目 pom yml 生产消息方法 接口 实现 创建消费者项目 pom yml 接收消息方法 重复消费 消费者yml 持久化 消费者负载个性配置(预拉取) ...

  10. react 也就这么回事 05 —— 组件 & Props

    什么是组件:用来实现局部功能的可复用代码片段 比如很多界面会用到"分页"功能,因此可以将它封装成独立的组件 这样用到分页的界面只需引入该组件而不必重新写代码 1 定义组件 在 Re ...