前言
rest风格严格意义上说不是一种标准,而是一种风格,在如今互联网界,这个风格被广泛用于微服务系统之间的交互。

REST简单介绍

REST(Representional State Transfer)直译为表现层状态转换。针对REST和RESTful的介绍,觉得这篇博客写的不错,可以参看一下REST,RESTful介绍.

其实总结起来也就几句话,rest设计规范为通过url表示接口名,HTTP请求方式来区分请求类型。同时前端根据HTTP状态响应码做相应的处理。

HTTP的动作
HTTP存在创建,修改,访问,删除。这几种操作。

rest风格的url一般不会出现动词,区分动作的任务已经交给了HTTP协议了。

关于rest风格有一些建议:

1、一般不应该在URI中存在动词

2、不要在URI中加入版本号

3、建议参数超过5个,通过JSON请求传递参数

之前在总结spring mvc的时候简单总结过@RequestMapping让URL映射到对应的控制器,不过为了更好的支持REST风格的开发,spring之后还提供了@GetMapping,@PostMapping,@PutMapping,@PatchMapping,@DeleteMapping

通过@RequestMapping、@GetMapping等注解可以定位到指定的控制器方法上,通过注解@PathVariable就能够将URI地址参数获取,通过@ResponseBody可以将请求体为json的数据转换为负责的java对象。下面开始进行实例说明,这里只举例POS和GET请求对应的rest请求。

REST请求实例
1、对应的bean对象

public class User {
private Long id;
private String userName;
private SexEnum sex = null;
private String note;

//这里省略getter和setter方法

}
2、对应的UserVO

public class UserVo {
private Long id;
private String userName;
private int sexCode;
private String sexName;
private String note;

//省略getter和setter方法
}
3、对应的controller

package com.learn.chapter11.controller;

import com.learn.chapter11.domain.User;
import com.learn.chapter11.enumeration.SexEnum;
import com.learn.chapter11.service.UserService;
import com.learn.chapter11.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

/**
* autor:liman
* mobilNo:15528212893
* mail:657271181@qq.com
* comment:
*/
@Controller
public class UserController {

@Autowired
private UserService userService;

@GetMapping("/index")
public String index() {
System.out.println("test index");
return "restful";
}

@PostMapping("/user")
@ResponseBody
public User insertUser(@RequestBody UserVo userVo) {
User user = this.changeToPo(userVo);
System.out.println(user.toString());
return user;
}

@GetMapping(value = "/user/{id}")
@ResponseBody
public UserVo getUser(@PathVariable("id") Long id) {
User user = new User();
user.setNote("just test");
user.setId(id);
user.setUserName("liman");
user.setSex(SexEnum.MALE);
return changeToVo(user);
}

@GetMapping(value = "/users/{userName}/{note}/{start}/{limit}")
@ResponseBody
public List<UserVo> findUsers(
@PathVariable("userName"www.thd178.com) String userName,
@PathVariable("note"www.gcyL157.com) String note,
@PathVariable("start"www.mhylpt.com/) int start,
@PathVariable("limit") int limit) {
System.out.println(userName+":"+note+":"+start+":"+limit);
List<User> userList = userService.findUsers(userName, note, start, limit);
return this.changeToVoes(userList);
}

@PutMapping("/user/{id}")
@ResponseBody
public User updateUser(@PathVariable("id") Long id,@RequestBody UserVo userVo){
User user = this.changeToPo(userVo);
user.setId(1L);
userService.updateUser(user);
return user;
}

//将VO对象转换的po
private User changeToPo(UserVo userVo) {
User user = new User();
user.setSex(SexEnum.getSexEnum(userVo.getSexCode()));
user.setUserName(userVo.getUserName());
user.setId(userVo.getId());
user.setNote(userVo.getNote());
return user;
}

// 转换PO变为VO
private UserVo changeToVo(User user) {
UserVo userVo = new UserVo(www.michenggw.com);
userVo.setId(user.getId(www.dasheng178.com));
userVo.setUserName(user.getUserName());
userVo.setSexCode(user.getSex(www.ysyl157.com ).getCode());
userVo.setSexName(user.getSex(www.meiwanyule.cn).getName());
userVo.setNote(user.getNote());
return userVo;
}

// 将PO列表转换为VO列表
private List<UserVo> changeToVoes(List<User> poList) {
List<UserVo> voList = new ArrayList<>();
for (User user : poList) {
UserVo userVo = changeToVo(user);
voList.add(userVo);
}
return voList;
}
}
由于需要拼接json数据进行测试,这里不用postman进行测试,为了直观,还是采用老套的jsp操作即可。

<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>测试restful请求</title>
<script type="text/javascript"
src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script type="text/javascript">

function post() {
var params = {
'id':'1',
'userName': 'user_name_new',
'sexCode': 1,
'note': "note_new"
}
$.post({
url: "./user",
// 此处需要告知传递参数类型为JSON,不能缺少
contentType: "application/json",
// 将JSON转化为字符串传递
data: JSON.stringify(params),
// 成功后的方法
success: function (result) {
if (result == null || result.id == null) {
alert("插入失败");
return;
}
alert("插入成功");
}
});
}

post();

function get() {
$.get("./user/1", function (user, status) {
if (user == null) {
alert("结果为空")
} else {
alert("用户信息为" + JSON.stringify(user));
}
});
}

get();

function findUsers() {
$.get("./users/u/n/0/5", function (user, status) {
if (user == null) {
alert("结果为空")
} else {
alert("用户信息为:" + JSON.stringify(user));
}
});
}

findUsers();

</script>
</head>
<body>
<h1>测试RESTful下的请求</h1>
</body>
</html>
其实使用的部分没有总结太多,只是针对@PathVariable注解的使用进行了总结,这个注解就是在url中获取参数。同时:使用@RestController注解可以将控制器返回的对象转换为json数据集。

结果的渲染
@RestController注解会自动将控制器方法返回的值自动转换成json数据,这个其实在Spring mvc的深入理解中做了介绍,但是没有很好的条理性。

其实spring mvc的数据转换是通过HTTPMessageConverter接口的实现类完成,在Spring MVC中,IOC容器会自动注册两个HttPMessageConverter接口的实现类,他们分别为StringHTTPMessageConverter和MappingJackson2HttPMessageConverter。spring mvc在执行控制器的方法之后会去遍历注册的HttpMessageConverter接口的实现类,使用canWrite方法去判断是否拦截控制器的返回。对于HttpMessageConverter机制没有处理的数据模型,按spring mvc的流程,会流转到视图解析器(ViewResolver)

处理HTTP状态码、异常和响应头
当资源发生找不到的异常时,需要返回客户端指定的状态码,spring mvc其实已经提供了实体封装类ResponseEntity和注解@ResponseStatus。ResponseEntity可以有效的封装错误信息和状态码,通过@ResponseStatus可以配置指定的响应码给客户端。

@ResponseStatus和@ResponseBody注解一样,都是标记在方法上

@PostMapping("/successHeader2")
//直接在注解上加入返回成功的状态码
@ResponseStatus(HttpStatus.CREATED)
public UserVo insertUserSuccess(@RequestBody UserVo userVo){
User user = this.changeToPo(userVo);
userService.insertUser(user);
UserVo result = this.changeToVo(user);
return result;
}
RestTemplate请求
To be Continued......

最新文章

  1. MVC Core 网站开发(Ninesky) 2、栏目
  2. [LeetCode] Design Hit Counter 设计点击计数器
  3. 如何对Azure磁盘性能进行测试
  4. Java中如何克隆集合——ArrayList和HashSet深拷贝
  5. intelij idea 2016.2注册码
  6. 【转载】UEditor前端配置项说明
  7. [ruby on rails] 跟我学之(5)显示所有数据
  8. 网站开发常用jQuery插件总结(13)定位插件scrollto
  9. C#编译器对于dynamic对象到底做了什么
  10. Linux 查看文件内容的命令
  11. [Regular Expressions] Find Repeated Patterns
  12. JS它DOM
  13. Sea.Js使用入门
  14. 01Design and Analysis Algorithm Using Python-程振波
  15. MT【299】对数型数列不等式
  16. HACK入别人的游戏制作做MOD的几种技巧
  17. zabbix 3.2.5 agent端(源码包)安装部署 (二)
  18. linux下如何删除十字符libudev.so病毒文件
  19. SoapUI 测试接口演示
  20. pom报错解决方法大全

热门文章

  1. netty之粘包分包的处理
  2. nio之netty3的应用
  3. JavaWeb项目生成PDF文件添加水印图片并导出
  4. Qt-QML-Repeater-导航条
  5. RabbitMQ基础教程之Spring&amp;JavaConfig使用篇
  6. .NET中发送邮件的实现
  7. [JSON].toString()
  8. linux c语言 fork() 和 exec 函数的简介和用法
  9. 十分钟掌握pandas(pandas官方文档翻译)
  10. 家用甲醛pm2.5温湿度传感器实验