目录
3. 使用Spring MVC的控制器创建RESTful端点
三. 使用原生 javascript 和 jquery js库消费REST API
一、使用spring提供REST API
1. 项目准备
- 创建springboot项目
- 引入spring web、spring data-jpa等起步依赖
- 配置web端口、数据库连接
2. 生成数据库用户表实体
package readinglist.entity;
import javax.persistence.*;
import java.util.Date;
@Entity
@Table(name = "ATBL_USER_LV", schema = "PRODUCTION", catalog = "")
public class AtblUserLv {
private long id;
private String password;
private String username;
private Date addtime;
@SequenceGenerator(name = "generator", sequenceName = "SEQ_A_TBL", allocationSize = 1)
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "generator")
@Column(name = "ID", unique = true, nullable = false, scale = 0)
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
@Basic
@Column(name = "PASSWORD")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Basic
@Column(name = "USERNAME")
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Basic
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "ADDTIME")
public Date getAddtime() {
return addtime;
}
public void setAddtime(Date addtime) {
this.addtime = addtime;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
AtblUserLv that = (AtblUserLv) o;
if (id != that.id) return false;
if (password != null ? !password.equals(that.password) : that.password != null) return false;
if (username != null ? !username.equals(that.username) : that.username != null) return false;
if (addtime != null ? !addtime.equals(that.addtime) : that.addtime != null) return false;
return true;
}
@Override
public int hashCode() {
int result = (int) (id ^ (id >>> 32));
result = 31 * result + (password != null ? password.hashCode() : 0);
result = 31 * result + (username != null ? username.hashCode() : 0);
result = 31 * result + (addtime != null ? addtime.hashCode() : 0);
return result;
}
}
3. 使用Spring MVC的控制器创建RESTful端点
创建RESTful控制器需要使用@RestController注解,此注解会告诉Spring,控制器中的所有处理器方法的返回值都要直接写入响应体中,而不是将值放到模型中并传递给一个视图以便于进行渲染。
package readinglist.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import readinglist.entity.AtblUserLv;
import readinglist.repository.UserRepository;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Optional;
/**
* Rest端点定义类
* 2022年5月6日11:41:44
*/
@RestController //注解为REST控制器类
@CrossOrigin(origins = "*") //允许跨域请求
@RequestMapping(path = "/jsondata")
public class JsonRestController {
@Autowired //自动装备DB数据层类
private UserRepository userRepository;
@GetMapping("/getjData")
public String getjData(){
String jsonStr = "{\"id\": 2, \"title\": \"json title标题\", \"concf\": {\"width\": 34,\"height\": 35}, \"arrlist\": [\"JAVA\", \"JavaScript\", \"PHP\"]}";
//String jsonStr = "{\"id\": 2, \"title\": \"json title标题\", \"arrlist\": [\"JAVA\", \"JavaScript\", \"PHP\"]}";
//String jsonStr="{\"aaname\": \"兮动人\",\"aaid\":22,\"sex\": \"男\",\"xueli\": \"本科\"}";
return jsonStr;
}
/**
* 获得用户列表
* @return
*/
@GetMapping("/getuserlist")
public List<AtblUserLv> getusers(){
System.out.println("进入getuserlist请求...");
PageRequest page=PageRequest.of(0,2, Sort.by("addtime").descending());
return userRepository.findAll(page).getContent();
}
/**
* 根据ID查询用户信息
* {id}这个表示占位符,传入一个id值:http://localhost:8080/jsondata/getuser/1
* @PathVariable("id")这个注解中的id接收{id}的值,赋值给Long id参数
* @param id
* @return
*/
@GetMapping("/getuser/{id}")
public AtblUserLv userById(@PathVariable("id") Long id){
System.out.println("id===="+id);
Optional<AtblUserLv> optUser=userRepository.findById(id);
if(optUser.isPresent()){
return optUser.get();
}
return null;
}
/**
* 根据ID查询用户信息,使用ResponseEntity对象
* 如果查到用户,则返回ResponseEntity<AtblUserLv>对象,且HTTP状态为0K
* 如果查不到用户,则ResponseEntity放入null,且HTTP状态返回NOT_FOUND(404)
* @param id
* @return
*/
@GetMapping("/findUser/{id}")
public ResponseEntity<AtblUserLv> userByIdEntity(@PathVariable("id") Long id){
System.out.println("userByIdEntity--id:"+id);
Optional<AtblUserLv> optUser=userRepository.findById(id);
if(optUser.isPresent()){
return new ResponseEntity<>(optUser.get(), HttpStatus.OK);
}
return new ResponseEntity<>(null, HttpStatus.NOT_FOUND);
}
/**
* 添加新用户到数据库
* @param atbluserlv
* @param request
* @return
*/
@PostMapping(path = "/addpostusr")
@ResponseStatus(HttpStatus.CREATED)
public AtblUserLv postAddUser(@RequestBody AtblUserLv atbluserlv,HttpServletRequest request) {
System.out.println("进入方法:postAddUser---request.getMethod():"+request.getMethod());
System.out.println("request.getQueryString():"+request.getQueryString());
System.out.println("request.getRequestURI():"+request.getRequestURI());
System.out.println("===---------"+atbluserlv.getUsername()+atbluserlv.getPassword());
atbluserlv.setAddtime(new Date());
return userRepository.save(atbluserlv);
}
}
二、Spring 消费REST服务 API
1. 项目准备
- 创建消费端springboot项目
- 引入spring web等起步依赖
2. 创建消费端用户领域类
package com.sbootwo.resttemplate.entity;
import java.util.Date;
public class AtblUserLv {
private long id;
private String password;
private String username;
private Date addtime;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getAddtime() {
return addtime;
}
public void setAddtime(Date addtime) {
this.addtime = addtime;
}
}
3. 使用RestTemplate消费REST API
Spring 应用可以采用多种方式来消费 REST API,包括以下几种方式。
- RestTemplate:Spring 核心框架提供的简单、同步 REST 客户端。
- Traverson:Spring HATEOAS 提供的支持超链接、同步的 REST 客户端,其灵感来源于同名的 JavaScript 库。
- WebClient:Spring 5 所引用的反应式、异步 REST 客户端。
本节主要讲解使用 RestTemplate 消费 REST 端点,创建 Rest 端点 API 消费类
package com.sbootwo.resttemplate;
import com.sbootwo.resttemplate.entity.AtblUserLv;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
/**
* Rest端点API消费类
* 2022年5月6日11:40:37
*/
public class RestConsume {
/**
* 用户RestTemplate消费REST端点。
* 实例化一个RestTemplate对象调用方法 也可以 声明成一个bean注入需要的地方
*/
RestTemplate rest=new RestTemplate();
/**
* 消费服务端REST端点,获取单个用户信息
* @param id 传递给getForObject方法中的id,并填充到URL中的{id}占位符
* @return
*/
public AtblUserLv getIdUserOne(String id){
return rest.getForObject("http://localhost:8080/jsondata/getuser/{id}",AtblUserLv.class,id);
}
/**
* 消费服务端REST端点,获取单个用户信息
* URI对象通过String规范定义的
* @param uid 参数传入Map中,Map中的健id填充到URI中的{id}占位符,且Map中的健名称和id}占位符取名一致
* @return
*/
public AtblUserLv getIdUserTwo(String uid){
Map<String,String> mapurl=new HashMap<>();
mapurl.put("id",uid);
URI url= UriComponentsBuilder.fromHttpUrl("http://localhost:8080/jsondata/getuser/{id}").build(mapurl);
return rest.getForObject(url,AtblUserLv.class);
}
/**
* 消费服务端REST端点,获取单个用户信息
* getForEntity()方法和getForObject()方法不同的是,getForEntity()返回的并不是代表响应载荷的领域对象,
* 而是一个包裹领域对象的ResponseEntity对象。ResponseEntity对象能够访问很多的响应细节,比如响应头信息
* @param uid 传递给getForEntity方法中的uid,并填充到URL中的{id}占位符
* @return
*/
public AtblUserLv getIdUserThree(String uid){
ResponseEntity<AtblUserLv> responseEntity= rest.getForEntity("http://localhost:8080/jsondata/getuser/{id}",AtblUserLv.class,uid);
System.out.println("获得响应头信息:"+responseEntity.getHeaders().getDate());
return responseEntity.getBody();
}
/**
* 消费服务端REST端点,添加一个新用户信息
* @param atblUserLv 将atblUserLv领域类绑定到AtblUserLv.class上
* @return
*/
public AtblUserLv addAtblUserLvOne(AtblUserLv atblUserLv){
return rest.postForObject("http://localhost:8080/jsondata/addpostusr",atblUserLv,AtblUserLv.class);
}
/**
* 费服务端REST端点,添加一个新用户信息
* postForEntity()方法可以同时获得需要的地址和响应载体
* @param atblUserLv 将atblUserLv领域类绑定到AtblUserLv.class上
* @return
*/
public AtblUserLv addAtblUserLvTwo(AtblUserLv atblUserLv){
ResponseEntity<AtblUserLv> responseEntity=rest.postForEntity("http://localhost:8080/jsondata/addpostusr",atblUserLv,AtblUserLv.class);
System.out.println("获得响应头信息:"+responseEntity.getHeaders().getDate()+"--"+responseEntity.getHeaders().getLocation());
return responseEntity.getBody();
}
public static void main(String[] args) {
RestConsume restConsume=new RestConsume();
//-------------GET资源获取信用户信息-------------
AtblUserLv tuserone=restConsume.getIdUserOne("8");
System.out.println("----"+tuserone.getId()+"||"+tuserone.getUsername()+"||"+tuserone.getPassword()+"||"+tuserone.getAddtime());
AtblUserLv tusertwo=restConsume.getIdUserTwo("7");
System.out.println("=========="+tusertwo.getId()+"||"+tusertwo.getUsername()+"||"+tusertwo.getPassword()+"||"+tusertwo.getAddtime());
AtblUserLv tuserThree=restConsume.getIdUserThree("9");
System.out.println("====---===---"+tuserThree.getId()+"||"+tuserThree.getUsername()+"||"+tuserThree.getPassword()+"||"+tuserThree.getAddtime());
//-------------POST资源添加新用户-------------
AtblUserLv userObj=new AtblUserLv();
userObj.setUsername("nuser4");
userObj.setPassword("new123");
AtblUserLv newUserOne=restConsume.addAtblUserLvOne(userObj);
System.out.println("打印出新增用户的ID值:"+newUserOne.getId());
AtblUserLv userObj2=new AtblUserLv();
userObj2.setUsername("nuser5");
userObj2.setPassword("new123");
AtblUserLv newUserTwo=restConsume.addAtblUserLvTwo(userObj2);
System.out.println("打印出新增用户的ID值:"+newUserTwo.getId());
}
}
三. 使用原生 javascript 和 jquery js库消费REST API
1. 使用原生 js 消费REST API
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script type="text/javascript">
//使用原生javaScript请求服务端获取数据,查询数据库用户信息。2022年5月6日11:51:57
// 在这里使用 javaScript 语言发起 Ajax 请求,访问服务器 AjaxServlet 中 javaScriptAjax
function ajaxRequest() {
// 1 、我们首先要创建 XMLHttpRequest
var xmlhttprequest = new XMLHttpRequest();
// 2 、调用 open 方法设置请求参数
xmlhttprequest.open("GET","http://localhost:8080/jsondata/getjData",true)
// 4 、在 send 方法前绑定 onreadystatechange 事件,处理请求完成后的操作。
xmlhttprequest.onreadystatechange = function(){
if (xmlhttprequest.readyState == 4 && xmlhttprequest.status == 200) {
console.log("-----"+xmlhttprequest.responseText.length);
var jsonObj = JSON.parse(xmlhttprequest.responseText);
//var objeval = eval("("+xmlhttprequest.responseText+")");
console.log(jsonObj);
var htmlStr = "";
htmlStr+="<table border=\"1\" width=\"50%\" cellSpacing=\"0\" cellPadding=\"0\">";
htmlStr+="<tr>";
htmlStr+="<td>ID</td>";
htmlStr+="<td>标题</td>";
htmlStr+="<td>宽</td>";
htmlStr+="<td>高</td>";
htmlStr+="<td>列表</td>";
htmlStr+="</tr>";
htmlStr+="<tr>";
htmlStr+="<td>"+jsonObj.id +"</td>";
htmlStr+="<td>"+jsonObj.title+"</td>";
htmlStr+="<td>"+jsonObj.concf.width+"</td>";
htmlStr+="<td>"+jsonObj.concf.height+"</td>";
htmlStr+="<td>"+jsonObj.arrlist+"</td>";
htmlStr+="</tr>";
htmlStr+="</table>";
document.getElementById("div01").innerHTML=htmlStr;
// 把响应的数据显示在页面上
// document.getElementById("div01").innerHTML = " 编号:" + jsonObj.id + " , 姓名:" + jsonObj.name;
}
}
// 3 、调用 send 方法发送请求
xmlhttprequest.send();
}
//从数据库获取用户列表数据
function ajaxReqbtnTwo() {
// 1 、我们首先要创建 XMLHttpRequest
var xmlhttprequest = new XMLHttpRequest();
// 2 、调用 open 方法设置请求参数
xmlhttprequest.open("GET","http://localhost:8080/jsondata/getuserlist",true) //获得用户列表
// 4 、在 send 方法前绑定 onreadystatechange 事件,处理请求完成后的操作。
xmlhttprequest.onreadystatechange = function(){
console.log("status:"+xmlhttprequest.status+xmlhttprequest.responseText);
if (xmlhttprequest.readyState == 4 && xmlhttprequest.status == 200) {
var jsonObj = JSON.parse(xmlhttprequest.responseText.toString());
//var objeval = eval("("+xmlhttprequest.responseText+")");
//var arrayobj=xmlhttprequest.responseText;
console.log("-----"+jsonObj.length);
console.log(jsonObj);
var htmlStr = "";
htmlStr+="<table border=\"1\" width=\"50%\" cellSpacing=\"0\" cellPadding=\"0\">";
htmlStr+="<tr>";
htmlStr+="<td>ID</td>";
htmlStr+="<td>用户名</td>";
htmlStr+="<td>密码</td>";
htmlStr+="<td>添加时间</td>";
htmlStr+="</tr>";
for(var i = 0;i < jsonObj.length;i++) {
console.log(jsonObj[i]);
var userobj=jsonObj[i];
htmlStr+="<tr>";
htmlStr+="<td>"+userobj.id +"</td>";
htmlStr+="<td>"+userobj.username+"</td>";
htmlStr+="<td>"+userobj.password+"</td>";
htmlStr+="<td>"+formatTime(userobj.addtime)+"</td>";
htmlStr+="</tr>";
}
htmlStr+="</table>";
document.getElementById("div01").innerHTML=htmlStr;
// 把响应的数据显示在页面上
// document.getElementById("div01").innerHTML = " 编号:" + jsonObj.id + " , 姓名:" + jsonObj.name;
}
}
// 3 、调用 send 方法发送请求
xmlhttprequest.send();
}
//从数据库获取单个用户数据
function ajaxReqbtnThree() {
// 1 、我们首先要创建 XMLHttpRequest
var xmlhttprequest = new XMLHttpRequest();
// 2 、调用 open 方法设置请求参数
xmlhttprequest.open("GET","http://localhost:8080/jsondata/getuser/3",true) //根据ID查询
//xmlhttprequest.open("GET","http://localhost:8080/jsondata/findUser/8",true) //根据ID查询,返回ResponseEntity<AtblUserLv>对象
// 4 、在 send 方法前绑定 onreadystatechange 事件,处理请求完成后的操作。
xmlhttprequest.onreadystatechange = function(){
console.log("status:"+xmlhttprequest.status+xmlhttprequest.responseText);
if (xmlhttprequest.readyState == 4 && xmlhttprequest.status == 200) {
var jsonObj = JSON.parse(xmlhttprequest.responseText.toString());
//var objeval = eval("("+xmlhttprequest.responseText+")");
//var arrayobj=xmlhttprequest.responseText;
console.log(jsonObj);
var htmlStr = "";
htmlStr+="<table border=\"1\" width=\"50%\" cellSpacing=\"0\" cellPadding=\"0\">";
htmlStr+="<tr>";
htmlStr+="<td>ID</td>";
htmlStr+="<td>用户名</td>";
htmlStr+="<td>密码</td>";
htmlStr+="<td>添加时间</td>";
htmlStr+="</tr>";
htmlStr+="<tr>";
htmlStr+="<td>"+jsonObj.id +"</td>";
htmlStr+="<td>"+jsonObj.username+"</td>";
htmlStr+="<td>"+jsonObj.password+"</td>";
htmlStr+="<td>"+formatTime(jsonObj.addtime)+"</td>";
htmlStr+="</tr>";
htmlStr+="</table>";
document.getElementById("div01").innerHTML=htmlStr;
// 把响应的数据显示在页面上
// document.getElementById("div01").innerHTML = " 编号:" + jsonObj.id + " , 姓名:" + jsonObj.name;
}else{
document.getElementById("div01").innerHTML=xmlhttprequest.readyState+"------"+xmlhttprequest.status;
}
}
// 3 、调用 send 方法发送请求
xmlhttprequest.send();
}
//格式化时间
function formatTime(time) {
let date = new Date(time).toJSON()
return new Date(+new Date(date) + 8 * 3600 * 1000)
.toISOString()
.replace(/T/g, ' ')
.replace(/\.[\d]{3}Z/, '')
}
</script>
</head>
<body>
<button id="btnone" onclick="ajaxRequest()">查询数据one</button>
<button id="bentwo" onclick="ajaxReqbtnTwo()">查询用户列表</button>
<button id="benthree" onclick="ajaxReqbtnThree()">根据ID查询单个用户</button>
<hr>
<div id="div01">
</div>
</body>
</html>
2. 使用jquery js库消费REST API
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="../static/jq/jquery-3.6.0.js"></script>
<script>
//入口函数放在html页面head部分必须加。
// 防止文档在完全加载(就绪)之前运行 jQuery 代码,即在 DOM 加载完成后才可以对 DOM 进行操作。
// 如果在文档没有完全加载之前就运行函数,操作可能失败。
// jQuery 入口函数:
// $(document).ready(function(){
// // jQuery执行代码
// });
// 或者
// $(function(){
// // jQuery执行代码
// });
//
// JavaScript 入口函数:
// window.onload = function () {
// // js 执行代码
// }
//使用jquery查询,添加用户信息,2022年5月6日11:48:08
$(function(){
//从数据库获取单个用户信息
$("#ajaxBtn").click(function(){
$.ajax({
url:"http://localhost:8080/jsondata/getuser/8",
//data:"",
//data:{action:"jQueryAjax"},
type:"GET",
success:function (data) {
alert(" 服务器返回的数据是: " + data);
// var jsonObj = JSON.parse(data);
$("#div01").html(" 编号:" + data.id + " , 姓名:" + data.username);
},
dataType : "json"
});
// $.getJSON("http://localhost:8080/jsondata/getjData", function(data) {
// alert(" 服务器返回的数据是: " + data.arrlist);
// });
// $.get("http://localhost:8080/jsondata/getuser/8",function(data,status){
// alert("数据: " + data.username + "\n状态: " + status);
// $("#div01").html(" 编号:" + data.id + " , 姓名:" + data.username);
// },"json"); //get方法加上第三个参数数据类型json时,data返回的就是一个json对象。不加时返回的是一个json格式的字符串
});
//获得json格式对象
function GetJsonData() {
var json = {
"username": $("#username").val(),
"password": $("#pwd").val()
};
return json;
}
//提交新用户信息,保存到数据库
$("#ajaxsubmit").click(function(){
$.ajax({
url:"http://localhost:8080/jsondata/addpostusr",
contentType: "application/json",
data:JSON.stringify(GetJsonData()),
type:"post",
success:function (data) {
alert(" 服务器返回的数据是: " + data);
},
dataType : "json"
});
});
});
</script>
</head>
<body>
<button id="ajaxBtn">ajaxBtn jquery查询用户数据</button>
<hr>
<div id="div01">
</div>
<br>
<br>
<button id="ajaxBtn22">获取数据getjData</button>
<hr>
<div id="div02">
</div>
<br>
<br>
<b>添加用户</b>
<br>
<br>
用户名:<input type="text" name="uname" id="username" style="width: 150px;">
<br>
<br>
密 码:<input type="password" name="upwd" id="pwd" style="width: 150px;">
<br>
<br>
<button id="ajaxsubmit">jquery提交 添加用户</button>
<hr>
<script type="text/javascript">
$("#ajaxBtn22").click(function(){
$.ajax({
url:"http://localhost:8080/jsondata/getjData",
// data:"action=jQueryAjax",
//data:{action:"jQueryAjax"},
type:"GET",
success:function (data) {
alert(" 服务器返回的数据是: " + data);
// var jsonObj = JSON.parse(data);
$("#div02").html(" 编号:" + data.id + " , 姓名:" + data.title);
},
dataType : "json"
});
});
</script>
</body>
</html>
总结
创建RESTful控制器需要使用@RestController注解,此注解会告诉Spring,控制器中的所有处理器方法的返回值都要直接写入响应体中,而不是将值放到模型中并传递给一个视图以便于进行渲染。@RestController注解相当于@ResponseBody + @Controller合在一起的作用,方法返回字符串值。
@Controller 这个注解可返回显示视图页面,将值放到模型中并传递给一个视图以便于进行渲染。