版权声明:From Lay https://blog.csdn.net/Sadlay/article/details/84383150
REST(二)开发REST风格端点
篇幅有限,这里我们就不在赘述service和dao的设计和实现了,如果需要可以文章末尾查看源码。
我们先定义用户实体
实体
package com.lay.rest.entity;
import com.lay.rest.entity.enumeration.SexEnum;
/**
* @Description:
* @Author: lay
* @Date: Created in 13:11 2018/11/17
* @Modified By:IntelliJ IDEA
*/
public class User {
private Long id;
private String userName;
private SexEnum sex=null;
private String note;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public SexEnum getSex() {
return sex;
}
public void setSex(SexEnum sex) {
this.sex = sex;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
}
这里的性别是个枚举类,这里给出实现
package com.lay.rest.entity.enumeration;
/**
* @Description:
* @Author: lay
* @Date: Created in 13:29 2018/11/17
* @Modified By:IntelliJ IDEA
*/
public enum SexEnum {
MALE(1,"男"),FEMALE(2,"女");
private int id;
private String name;
SexEnum(int id,String name){
this.id=id;
this.name=name;
}
public static SexEnum getEnumById(int id){
for (SexEnum sex : SexEnum.values()) {
if(sex.getId()==id){
return sex;
}
}return null;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
然后是在页面展示的VO(View Object)对象
VO
package com.lay.rest.vo;
/**
* @Description:
* @Author: lay
* @Date: Created in 14:56 2018/11/17
* @Modified By:IntelliJ IDEA
*/
public class UserVo {
private Long id;
private String userName;
private int sexCode;
private String sexName;
private String note;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getSexCode() {
return sexCode;
}
public void setSexCode(int sexCode) {
this.sexCode = sexCode;
}
public String getSexName() {
return sexName;
}
public void setSexName(String sexName) {
this.sexName = sexName;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
}
Vo对实体的性别进行了转换,这样在前台页面可以更好的进行展示。
接下来我们需要编写一个控制器
控制器
package com.lay.rest.controller;
/**
* @Description:
* @Author: lay
* @Date: Created in 14:58 2018/11/17
* @Modified By:IntelliJ IDEA
*/
@Controller
public class UserController {
//用户服务接口
@Autowired
private UserService userService = null;
//映射视图
@GetMapping("/restful")
public String index() {
return "/restful";
}
//转换Vo变Entity
private User changeToEntity(UserVo userVo) {
User user = new User();
user.setId(userVo.getId());
user.setUserName(userVo.getUserName());
user.setSex(SexEnum.getEnumById(userVo.getSexCode()));
user.setNote(userVo.getNote());
return user;
}
//转换Entity变Vo
private UserVo changeToVo(User user) {
UserVo userVo = new UserVo();
userVo.setId(user.getId());
userVo.setUserName(user.getUserName());
userVo.setSexCode(user.getSex().getId());
userVo.setSexName(user.getSex().getName());
userVo.setNote(user.getNote());
return userVo;
}
//将Entity列表转为Vo列表
private List<UserVo> changeToVoes(List<User> userList) {
List<UserVo> volist = new ArrayList<>();
for (User user : userList) {
UserVo userVo = changeToVo(user);
volist.add(userVo);
}
return volist;
}
//将Vo列表转为Entity列表
private List<User> changeToEntities(List<UserVo> userVoList) {
List<User> userlist = new ArrayList<>();
for (UserVo userVo : userVoList) {
User user = changeToEntity(userVo);
userlist.add(user);
}
return userlist;
}
//结果Vo
public class ResultVo {
private Boolean success = null;
private String message = null;
public ResultVo() {
}
public ResultVo(Boolean success, String message) {
this.success = success;
this.message = message;
}
public Boolean getSuccess() {
return success;
}
public void setSuccess(Boolean success) {
this.success = success;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
}
控制器定义了实体和VO互相转换的方法和返回的处理结果集。
然后是用于测试的页面
前台页面
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta charset="UTF-8">
<title>获取请求头参数</title>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.0.js"></script>
<script type="text/javascript">
//测试JavaSript代码
</script>
</head>
<body>
<h1>测试Restful下的请求</h1>
</body>
</html>
接下来我们进行具体的REST开发
首先我们需要创建资源。
创建用户
控制器
//测试post请求, 新增用户
@PostMapping("/user")
@ResponseBody
public User insertUser(@RequestBody UserVo userVo) {
User user = this.changeToEntity(userVo);
return userService.inserUser(user);
}
测试JavaSript代码
//测试post请求 创建用户
function post() {
var params={
'userName':'user_name_new',
'sexCode':1,
'note':'note_new'
}
$.post({
url:'./user',
contentType:"application/json",
data:JSON.stringify(params),
success:function (result) {
if(result==null||result.id==null){
alert("插入失败");
return;
}
alert("插入成功");
}
});
}
获取用户
控制器
//测试get请求 获取用户
@GetMapping(value = "/user/{id}")
@ResponseBody
public UserVo getUser(@PathVariable("id") Long id) {
User user = userService.getUser(id);
return changeToVo(user);
}
页面
//测试get请求 获取用户
function get() {
$.get("./user/1",function (user,status) {
if(user==null){
alert("结果为空");
}else {
alert("用户信息为:"+JSON.stringify(user));
}
});
}
条件获取用户
控制器
//查询符合要求的用户
@GetMapping("/users/{userName}/{note}/{start}/{limit}")
@ResponseBody
public List<UserVo> findUsers(
@PathVariable("userName") String userName,
@PathVariable("note") String note,
@PathVariable("start") int start,
@PathVariable("limit") int limit
) {
List<User> userList = userService.findUsers(userName, note, start, limit);
return this.changeToVoes(userList);
}
页面
//查询符合要求的用户
@GetMapping("/users/{userName}/{note}/{start}/{limit}")
@ResponseBody
public List<UserVo> findUsers(
@PathVariable("userName") String userName,
@PathVariable("note") String note,
@PathVariable("start") int start,
@PathVariable("limit") int limit
) {
List<User> userList = userService.findUsers(userName, note, start, limit);
return this.changeToVoes(userList);
}
修改用户全部信息
控制器
//使用HTTP的put请求修改用户信息
@PutMapping("/user/{id}")
@ResponseBody
public User updateUser(@PathVariable("id") Long id, @RequestBody UserVo userVo) {
User user = this.changeToEntity(userVo);
user.setId(id);
userService.updateUser(user);
return user;
}
页面
// 测试修改用户的Put请求
//updateUser();
function updateUser() {
var params={
'userName':'user_name_1_new',
'sexCode':1,
'note':'note_new_1'
}
$.ajax({
url:'./user/1',
//此处告知使用put请求
type:'PUT',
contentType:'application/json',
data:JSON.stringify(params),
success:function (user,status) {
if(user==null){
alert("结果为空");
}else {
alert(JSON.stringify(user));
}
}
});
}
修改用户指定信息(姓名)
控制器
//使用PATCH请求修改用户名称
@PatchMapping("/user/{id}/{userName}")
@ResponseBody
public ResultVo changeUserName(@PathVariable("id") Long id, @PathVariable("userName") String userName) {
int result = userService.updateUserName(id, userName);
ResultVo resultVo = new ResultVo(result > 0, result > 0 ? "更新成功" : "更新用户【" + id + "】失败");
return resultVo;
}
页面
// 测试PATCH请求
//updateUserName()
function updateUserName() {
$.ajax({
url:'./user/1/user_name_patch',
type:'PATCH',
success:function (result, status) {
if(result==null){
alert("结果为空");
}else {
alert(result.success?"更新成功":"更新失败");
}
}
})
}
删除用户
控制器
//使用HTTP的DELETE请求
@DeleteMapping("/user/{id}")
@ResponseBody
public ResultVo deleteUser(@PathVariable("id") Long id) {
int result = userService.deleteUser(id);
ResultVo resultVo = new ResultVo(result > 0, result > 0 ? "更新成功" : "更新用户【" + id + "】失败");
return resultVo;
}
页面
//测试删除用户HTTP的DELETE请求
//deleteUser()
function deleteUser() {
$.ajax({
url:'./user/1',
type:'DELETE',
success:function (result) {
if(result==null){
alert("结果为空");
}else {
alert(result.success?"删除成功":"删除失败");
}
}
})
}
表单提交
前面的请求都是通过javascript来完成的。在一些表单的提交中,也许不需要在使用js,这是就需要使用别的方式提交。
控制器
// 修改用户名称表单
@PatchMapping("/user/name")
@ResponseBody
public ResultVo changeUserName2( Long id, String userName) {
int result = userService.updateUserName(id, userName);
ResultVo resultVo = new ResultVo(result > 0, result > 0 ? "更新成功" : "更新用户【" + id + "】失败");
return resultVo;
}
//映射视图
@GetMapping("/user/name")
public String changeUserName(){
return "change_user_name";
}
测试页面
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<meta charset="UTF-8">
<title>获取请求头参数</title>
<script type="text/javascript" src="https://code.jquery.com/jquery-3.2.0.js"></script>
<script type="text/javascript"></script>
</head>
<body>
<form id="form" action="./name" method="post">
<table>
<tr>
<td>用户编号</td>
<td><input id="id" name="id"/></td>
</tr>
<tr>
<td>用户名称</td>
<td><input id="userName" name="userName"/></td>
</tr>
<tr>
<td></td>
<td align="right"><input id="submit" name="submit" type="submit"/></td>
</tr>
</table>
<input type="hidden" name="_method" id="_method" value="PATCH">
</form>
</body>
</html>
这里需要注意两点,一是form定义是post请求;而是form中还存在一个命名为_method
的隐藏字段,并且定义其值为PATCH
,这样就能够定位到对应的服务器的方法了。
使用@RestController
因为现在前后端分离,所以使用JSON作为前后端交互已经十分普遍。如果每一个方法都加入@ResponseBody
才能将数据模型转换为Json,显然有些冗余。这里sprirng mvc还有一个@RestController
注解,通过它可以将控制器返回的对象转换为JSON数据集。
但是为了使正常的视图能够被成功渲染,原本通过字符串的方式就不能用了。这是可以参考下面的index()方法,使用ModelAndView
返回,这样就能够让Spring mvc通过视图名词找到对应的视图,并将数据模型进行渲染。代码如下
控制器
package com.lay.rest.controller;
/**
* @Description:
* @Author: lay
* @Date: Created in 23:32 2018/11/17
* @Modified By:IntelliJ IDEA
*/
@RestController
public class TestRestController {
//在restController下映射视图
@GetMapping("/restful2")
public ModelAndView index(){
ModelAndView mv=new ModelAndView("restful");
return mv;
}
}