springboot的服务端Restful风格 API接口,在不同场景下,设置不同的请求及传参方式的设计,及其他异常场景解决方案
Posted 阿啄debugIT
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot的服务端Restful风格 API接口,在不同场景下,设置不同的请求及传参方式的设计,及其他异常场景解决方案相关的知识,希望对你有一定的参考价值。
Restful风格API设计
Restful本身不是一项什么高深的技术,而只是一种编程风格,是通过HTTP的方法get、post、PUT、DELETE、HEAD等CRUD相关的操作。
序号 | 方法 | 描述 |
1 | GET | 发送请求来获得服务器上的资源,请求体中不会包含请求数据,请求数据放在协议头中。另外get支持快取、缓存 |
、可保留书签等。幂等 | ||
2 | POST | 和get一样很常见,向服务器提交资源让服务器处理,比如提交表单、上传文件等,可能导致建立新的资源或者对 |
原有资源的修改。提交的资源放在请求体中。不支持快取。非幂等 | ||
3 | HEAD | 本质和get一样,但是响应中没有呈现数据,而是http的头信息,主要用来检查资源或超链接的有效性或是否可以可达、检 |
查网页是否被串改或更新,获取头信息等,特别适用在有限的速度和带宽下。 | ||
5 | DELETE | 请求服务器删除某资源。和put都具有破坏性,可能被防火墙拦截。如果是https协议,则无需担心。幂等 |
6 | CONNECT | HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。就是把服务器作为跳板,去访问其他网页 |
然后把数据返回回来,连接成功后,就可以正常的get、post了。 | ||
7 | OPTIONS | 获取http服务器支持的http请求方法,允许客户端查看服务器的性能,比如ajax跨域时的预检等。 |
8 | TRACE | 回显服务器收到的请求,主要用于测试或诊断。一般禁用,防止被恶意攻击或盗取信息。 |
@RestController
@RequestMapping("/rest")
public class DebugItRestController {
@RequestMapping(value = "/debugit/{id}", method = DELETE, produces = "application/json")
public WebResponse<?> deletedebugIt(@PathVariable Long id) {
DebugIt debugIt = debugItService.getById(id);
debugIt.setStatus(-1);
debugItService.updatedebugIt(debugIt);
WebResponse<Object> response = WebResponse.getSuccessResponse(null);
return response;
}
}
分析一下这段代码,这段@RestController代码和之前@Controller代码的区别在于:
(1)使用的是@RestController这个注解,而不是@Controller,不过这个注解同样不是Spring boot提供的,而是Spring MVC4中的提供的注解,表示一个支持Restful的控制器。
(2)若在@RestController标识的类中方法有(delete、get、post、update)等上的注解URL映射可以相同,即都是/debugit/{id},但在@Controller标识的类不能出现。这里的在@RestController标识的类,可以通过method来进行区分,produces的作用是表示返回结果的类型是JSON。
(3)@PathVariable这个注解,也是Spring MVC提供的,其作用是,表示该变量的值是从访问路径中获取。
0、场景:请求路径传参,若中间参数为空怎么解决
@RequestMapping(value = "/get/{id}/{userId}", method = RequestMethod.GET)
public Result getMemberShip(@PathVariable("id") int id,@PathVariable("userId") int userId) {
假如id为非必需参数
//可以指定多个匹配路径
@RequestMapping(value = {"/get/{userId}", "/get/{id}/{userId}"}, method = RequestMethod.GET)
//然后设置参数非必须
@PathVariable(required = false) String id
A、直接把表单的参数,写在Controller相应的方法的形参中,适用于get方式提交,不适用于post方式提交。
url形式:http://localhost/server-servlet-context-path/insertUser1?username=阿啄debugIT&password=111111 提交的参数需要和Controller方法中的入参名称一致。
前段的请求
POST请求方式
<script>
var xhr = new XMLHttpRequest()
xhr.open('POST', 'http://localhost:8080/server-servlet-context-path/insertUser1') // 设置请求行
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
xhr.send('username=阿啄debugIT&password=111111') // 以 urlencoded 格式设置请求体
xhr.onload=function(){
if(xhr.readyState!==4) return
console.log(xhr.responseText)
}
</script>
GET请求方式:
<script>
var xhr = new XMLHttpRequest()
xhr.open('GET', 'http://localhost:8080/server-servlet-context-path/insertUser1?username=阿啄debugIT&password=123') // 设置请求行
xhr.send()
xhr.onload=function(){
if(xhr.readyState!==4) return
console.log(xhr.responseText)
}
</script>
Controller相应的方法的形参
/**
* 直接把表单的参数写在Controller相应的方法的形参中
* @param username
* @param password
* @return
*/
@RequestMapping("/insertUser1")
public String insertUser1(String username,String password) {
System.out.println("username is:"+username);
System.out.println("password is:"+password);
return "index";
}
B、通过HttpServletRequest接收,post方式和get方式都可以。
通过HttpServletRequest对象获取请求参数。
/**
* 通过HttpServletRequest接收
* @param request
* @return
*/
@RequestMapping("/insertUser2")
public String insertUser2(HttpServletRequest request) {
String username=request.getParameter("username");
String password=request.getParameter("password");
System.out.println("username is:"+username);
System.out.println("password is:"+password);
return "index";
}
C、通过一个bean来接收,post方式和get方式都可以。
建立一个和表单中参数对应的bean
public class UserModel {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
用这个bean来封装接收的参数
/**
* 通过一个bean来接收
* @param user
* @return
*/
@RequestMapping("/insertUser3")
public String insertUser3(UserModel user) {
System.out.println("username is:"+user.getUsername());
System.out.println("password is:"+user.getPassword());
return "index";
}
D、通过@PathVariable获取路径中的参数
例如:访问http://localhost/server-servlet-context-path/insertUser4/lixiaoxi/111111 路径时,
前端请求
<script>
var xhr = new XMLHttpRequest()
xhr.open('GET', 'http://localhost:8080/server-servlet-context-path/insertUser4/username=阿啄debugIT/password=111111') // 设置请求行
xhr.send()
xhr.onload=function(){
if(xhr.readyState!==4) return
console.log(xhr.responseText)
}
</script>
后端controller
/**
* 通过@PathVariable获取路径中的参数
* @param username
* @param password
* @return
*/
@RequestMapping(value="/insertUser4/{username}/{password}",method=RequestMethod.GET)
public String insertUser4(@PathVariable String username,@PathVariable String password) {
System.out.println("username is:"+username);
System.out.println("password is:"+password);
return "index";
}
则自动将URL中模板变量{username}和{password},绑定到通过@PathVariable注解的同名参数上,即入参后username=阿啄debugIT、password=111111。
E、使用@ModelAttribute注解获取POST请求的FORM表单数据
Jsp表单如下:
<form action ="<%=request.getContextPath()%>/insertUser5" method="post">
用户名: <input type="text" name="username"/><br/>
密 码: <input type="password" name="password"/><br/>
<input type="submit" value="提交"/>
<input type="reset" value="重置"/>
</form>
或者
<script>
var xhr = new XMLHttpRequest()
xhr.open('POST', 'http://localhost:8080/server-servlet-context-path/insertUser5') // 设置请求行
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
xhr.send('username=阿啄debugIT&password=111111')
xhr.onload=function(){
if(xhr.readyState!==4) return
console.log(xhr.responseText)
}
/script>
Java Controller如下:
/**
* 使用@ModelAttribute注解获取POST请求的FORM表单数据
* @param user
* @return
*/
@RequestMapping(value="/insertUser5",method=RequestMethod.POST)
public String insertUser5(@ModelAttribute("user") UserModel user) {
System.out.println("username is:"+user.getUsername());
System.out.println("password is:"+user.getPassword());
return "index";
}
F、用注解@RequestParam绑定请求参数到方法入参
当请求参数username不存在时,会有异常发生,可以通过设置属性required=false解决,
例如: @RequestParam(value="username", required=false)
/**
* 用注解@RequestParam绑定请求参数到方法入参
* @param username
* @param password
* @return
*/
@RequestMapping(value="/insertUser6",method=RequestMethod.GET)
public String insertUser6(@RequestParam("username") String username,@RequestParam("password") String password) {
System.out.println("username is:"+username);
System.out.println("password is:"+password);
return "index";
}
G、用注解@RequestBody绑定请求参数到方法入参,用于POST请求
前段请求
<script>
var xhr = new XMLHttpRequest()
xhr.open('POST', 'http://localhost:8080/server-servlet-context-path/insertUser7') // 设置请求行
xhr.setRequestHeader('Content-Type','application/json')
xhr.send('{"username":"阿啄debugIT","password":"111111"}')
xhr.onload=function(){
if(xhr.readyState!==4) return
console.log(xhr.responseText)
}
</script>
后端处理
@RequestBody主要用来接收前端传递给后端的json字符串中的数据的(请求体中的数据的)
@RestController
@RequestMapping("/tools")
public class InnerController {
@RequestMapping(value="/insertUser7",method=RequestMethod.POST)
public String insertUser7(@RequestBody DemoUser user) {
System.out.println("username is:"+user.getUsername());
System.out.println("password is:"+user.getPassword());
return "success";
}
}
以上是关于springboot的服务端Restful风格 API接口,在不同场景下,设置不同的请求及传参方式的设计,及其他异常场景解决方案的主要内容,如果未能解决你的问题,请参考以下文章
spring boot 快速搭建 基于 Restful 风格的微服务