spring-boot-learning-REST风格网站
什么是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风格网站的更多相关文章
- 使用Spring boot开发RestFul 风格项目PUT/DELETE方法不起作用
在使用Spring boot 开发restful 风格的项目,put.delete方法不起作用,解决办法. 实体类Student @Data public class Student { privat ...
- Spring Boot构建 RESTful 风格应用
Spring Boot构建 RESTful 风格应用 1.Spring Boot构建 RESTful 风格应用 1.1 实战 1.1.1 创建工程 1.1.2 构建实体类 1.1.4 查询定制 1.1 ...
- Spring Boot2 系列教程(三十一)Spring Boot 构建 RESTful 风格应用
RESTful ,到现在相信已经没人不知道这个东西了吧!关于 RESTful 的概念,我这里就不做过多介绍了,传统的 Struts 对 RESTful 支持不够友好 ,但是 SpringMVC 对于 ...
- Vue + Spring Boot从零开始搭建个人网站(一) 之 项目前端Vue.js环境搭建
前言: 最近在考虑搭建个人网站,想了想决定采用前后端分离模式 前端使用Vue,负责接收数据 后端使用Spring Boot,负责提供前端需要的API 就这样开启了我边学习边实践之旅 Vue环境搭建步骤 ...
- spring boot(3)-Rest风格接口
Rest接口 虽然现在还有很多人在用jsp,但是其实这种动态页面早已过时,现在前端流行的是静态HTML+ rest接口(json格式).当然,如果是单台服务器,用动态还是静态页面可能没什么很大区别,但 ...
- Spring Boot 2.0 设置网站默认首页
Spring Boot设置默认首页,方法实验OK如下 附上Application启动代码 /** * @ClassName Application * @Description Spring-Boot ...
- Spring Boot (2) Restful风格接口
Rest接口 动态页面jsp早已过时,现在流行的是vuejs.angularjs.react等前端框架 调用 rest接口(json格式),如果是单台服务器,用动态还是静态页面可能没什么大区别,如果服 ...
- Spring boot——构建rest风格
前言rest风格严格意义上说不是一种标准,而是一种风格,在如今互联网界,这个风格被广泛用于微服务系统之间的交互. REST简单介绍 REST(Representional State Transfer ...
- Spring Boot 之restful风格
步骤一:restful风格是什么? 我们知道在做web开发的过程中,method常用的值是get和post.可事实上,method值还可以是put和delete等等其他值. 既然method值如此丰富 ...
- 一:Spring Boot、Spring Cloud
上次写了一篇文章叫Spring Cloud在国内中小型公司能用起来吗?介绍了Spring Cloud是否能在中小公司使用起来,这篇文章是它的姊妹篇.其实我们在这条路上已经走了一年多,从16年初到现在. ...
随机推荐
- 记一次payload绕过电脑管家免杀
一.msf命令提示符下generate命令生成1.首先可以使用show payloads命令查看所有的payload,然后使用use命令选中其中一个. 2.使用generate -h查看命令帮助 ge ...
- [题解]第十一届北航程序设计竞赛预赛——L.偶回文串
题目描述 长度为偶数的回文串被称为偶回文串.如果一个字符串重新排序之后能够成为一个偶回文串,则称为可回文的. 给一个字符串,求可回文的子串个数.字符串只含小写字母,单个字符串长度不超过10^5,所有数 ...
- Nexus6-刷LineageOS系统(Windows10处理环境下)
0.观前注意 本方法不一定保证正确,我只是通过了此方法进入了手机,但是仍然有少部分apk无法安装(比如v2rayNG),但是正常的浏览器和qq是能够正常运行的. 1.刷机准备 一台Nexus6手机(能 ...
- oj教程--学习顺序
1.数组 2.排序 3.递归 4.栈 5.队列 6.链表 7.二叉树 8.大数或高精度 9.枚举 10.搜索 11.字符串问题 12.贪心 13.最短路径 14.动态规划
- MySQL 学习-进阶
MySQL高级学习 一.MySQL 事务 1.1.事务的概念 一条或多条 SQL 语句组成一个执行单元,其特点是这个单元要么同时成功要么同时失败,单元中的每条 SQL 语句都相互依赖,形成一个整体,如 ...
- Qt:QThread
0.说明 QThread提供了一种与平台无关的线程管理方法. 一个QThread对象管理一个线程.QThread通过run()方法启动线程.默认情况下,run()方法通过exec()启动一个事件循环, ...
- shell日常积累
Linux shell脚本中shift的用法说明 https://blog.csdn.net/zhu_xun/article/details/24796235
- Java中的单利模式
单利模式 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 这种模式涉及到一个单一的类,该类负责创 ...
- MySQL性能优化之索引设计
作者:IT王小二 博客:https://itwxe.com 上一篇给小伙伴们讲了关于SQL查询性能优化的相关技巧,一个好的查询SQL离不开合理的索引设计.这篇小二就来唠一唠怎么合理的设计一个索引来优化 ...
- 论文翻译:2020_DCCRN: Deep Complex Convolution Recurrent Network for Phase-Aware Speech Enhancement
论文地址:DCCRN:用于相位感知语音增强的深度复杂卷积循环网络 论文代码:https://paperswithcode.com/paper/dccrn-deep-complex-convolutio ...