什么是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. 记一次payload绕过电脑管家免杀

    一.msf命令提示符下generate命令生成1.首先可以使用show payloads命令查看所有的payload,然后使用use命令选中其中一个. 2.使用generate -h查看命令帮助 ge ...

  2. [题解]第十一届北航程序设计竞赛预赛——L.偶回文串

    题目描述 长度为偶数的回文串被称为偶回文串.如果一个字符串重新排序之后能够成为一个偶回文串,则称为可回文的. 给一个字符串,求可回文的子串个数.字符串只含小写字母,单个字符串长度不超过10^5,所有数 ...

  3. Nexus6-刷LineageOS系统(Windows10处理环境下)

    0.观前注意 本方法不一定保证正确,我只是通过了此方法进入了手机,但是仍然有少部分apk无法安装(比如v2rayNG),但是正常的浏览器和qq是能够正常运行的. 1.刷机准备 一台Nexus6手机(能 ...

  4. oj教程--学习顺序

    1.数组 2.排序 3.递归 4.栈 5.队列 6.链表 7.二叉树 8.大数或高精度 9.枚举 10.搜索 11.字符串问题 12.贪心 13.最短路径 14.动态规划

  5. MySQL 学习-进阶

    MySQL高级学习 一.MySQL 事务 1.1.事务的概念 一条或多条 SQL 语句组成一个执行单元,其特点是这个单元要么同时成功要么同时失败,单元中的每条 SQL 语句都相互依赖,形成一个整体,如 ...

  6. Qt:QThread

    0.说明 QThread提供了一种与平台无关的线程管理方法. 一个QThread对象管理一个线程.QThread通过run()方法启动线程.默认情况下,run()方法通过exec()启动一个事件循环, ...

  7. shell日常积累

    Linux shell脚本中shift的用法说明 https://blog.csdn.net/zhu_xun/article/details/24796235

  8. Java中的单利模式

    单利模式 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 这种模式涉及到一个单一的类,该类负责创 ...

  9. MySQL性能优化之索引设计

    作者:IT王小二 博客:https://itwxe.com 上一篇给小伙伴们讲了关于SQL查询性能优化的相关技巧,一个好的查询SQL离不开合理的索引设计.这篇小二就来唠一唠怎么合理的设计一个索引来优化 ...

  10. 论文翻译:2020_DCCRN: Deep Complex Convolution Recurrent Network for Phase-Aware Speech Enhancement

    论文地址:DCCRN:用于相位感知语音增强的深度复杂卷积循环网络 论文代码:https://paperswithcode.com/paper/dccrn-deep-complex-convolutio ...