其实http协议中定义了八种请求方式,比较常用的是四种。post,delete,put,get。就好像Java的增删改查一样,有不同的用法。
post常用于表单,地址栏无法直接看到参数,保密性比get要强。get的参数直接用于url拼接后面的,所以关于一些用户隐私比如账号密码,不适合用get去传。其实平常,我只使用get和post,这段时间,与第三方接口对接,才了解到put和delete的用法。
感兴趣可以去了解一下 rest API 规范以及设计思想。
那么接下来,我将在一个项目中创建接收和发送模块,接收模块会设置put,post , delete , get 接收方式接口,除了get以外,其他模块多设置 一个JSON数据接收的接口。
想直接看请求方法,就翻过这一段。
其实我觉得post表单数据比较长又保密,转成JSON我能理解,但是put和delete传输的数据一般不会很多,没想通为什么也要要求JSON格式数据传输,不过遇到了以防万一,也记录下来。
1、创建一个controller层,json数据接收的都加上了 @RequestBody 注解,并且会打印参数,名字都带Json。
这里接收实体只有两个属性,随便建立的。
package com.example.reply.controller;
import com.example.reply.dto.ReplyDTO;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("study")
public class StudyController {
@PostMapping("/postJson")
public String postJSON(@RequestBody ReplyDTO replyDTO){
System.out.println("拿到postJson数据:"+replyDTO);
return "访问成功!";
}
@PostMapping("/post")
public String post( ReplyDTO replyDTO){
System.out.println("拿到post数据:"+replyDTO);
return "访问成功!";
}
@GetMapping("/get")
public String get(ReplyDTO replyDTO){
System.out.println("拿到post数据:"+replyDTO);
return "访问成功!";
}
@PutMapping("/put")
public String put(ReplyDTO replyDTO){
System.out.println("拿到put数据:"+replyDTO);
return "访问成功!";
}
@PutMapping("/putJson")
public String putJson(@RequestBody ReplyDTO replyDTO){
System.out.println("拿到putJson数据:"+replyDTO);
return "访问成功!";
}
@DeleteMapping("/deleteJson")
public String deleteJson(@RequestBody ReplyDTO replyDTO){
System.out.println("拿到deleteJson数据:"+replyDTO);
return "访问成功!";
}
@DeleteMapping("/delete")
public String delete(ReplyDTO replyDTO){
System.out.println("拿到deleteJson数据:"+replyDTO);
return "访问成功!";
}
}
2、现在用postman来测试一下,是不是想象中的效果。
拿post举例
现在访问的 " /post " 接口,正确访问方式为 post请求,非JSON格式,也就是url拼接参数
(1)首先用 get 去请求 “ /post ” 接口 405,不被允许。
(2)用 post 去请求 “ /post ” 接口 ,参数为JSON格式。可以看到请求成功,但是后台并没有获取到参数。
(3)用 post 去请求 “ /post ” 接口,参数为url拼接。可以看到,请求成功,并且后台接收参数成功。
现在访问的 " /postJson " 接口,正确访问方式为 post请求,JSON格式,请求头要设置为 Content-Type : application/json
(1)用 post 请求 " /postJson " 接口,非JSON格式,系统直接报400,你没有JSON格式我不要。
(2)用 post 请求 " /postJson " 接口,JSON格式。可以看到请求正确,后台也获取到了数据。
其他的接口也测试一下,看看是否和自己想象中的一样。
3、写方法来请求这些接口。
详情请看下面。
get比较简单,因为没有JSON格式,可能有我没有发现。
这里参数用的URIBuilder ,会把url和参数拼接起来,其实直接手动拼接“http://loaclhost:8888/sent/get?id=1&str=get”,也是可以的。不过这样看起来要高大上一点。
创建一个HttpGet 和 CloseableHttpClient 。
需要的请求头呀,或者是其他设置都可以在 HttpGet 这里设置。然后用CloseableHttpClient.execute 来访问设置的路径。
最后用 ResponseHandler < String >去接收,这样返回的值就变成了String,然后需要在转呗。推荐阿里巴巴的JSON转换,好用不要钱。文章最后放maven的依赖。
/**
* get请求
* @param url
* @return
*/
public static String get(String url, Map<String,String> params){
try{
System.out.println("访问路径:"+url);
CloseableHttpClient httpClient = HttpClients.createDefault();
//设置参数
// 创建访问的地址,拼接参数到url后方
URIBuilder uriBuilder = new URIBuilder(url);
for(Map.Entry<String, String> entry : params.entrySet()){
uriBuilder.setParameter(entry.getKey(),entry.getValue());
}
//设置url
HttpGet httpGet=new HttpGet(uriBuilder.build());
//设置请求头
// httpGet.setHeader("Content-Type","application/json");
//发送请求,设置返回数据。
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String str = httpClient.execute(httpGet, responseHandler);
return str;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
post请求的非JSON格式,和get请求是一样的。只要把 “ HttpGet ” 换成 “ HttpPost ”即可。
/**
* post请求非JSON格式,其实就是参数直接拼接
* @param url
* @return
*/
public static String post(String url, Map<String,String> params){
try{
System.out.println("访问路径:"+url);
CloseableHttpClient httpClient = HttpClients.createDefault();
//设置参数
// 创建访问的地址,拼接参数到url后方
URIBuilder uriBuilder = new URIBuilder(url);
for(Map.Entry<String, String> entry : params.entrySet()){
uriBuilder.setParameter(entry.getKey(),entry.getValue());
}
//设置url
HttpPost httpPost=new HttpPost(uriBuilder.build());
//发送请求,设置返回数据。
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String str = httpClient.execute(httpPost, responseHandler);
return str;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
post请求的JSON格式数据,和直接拼接不一样。
用自带的 ” httpPost.setEntity “ 的方法去设置,传入的参数变成JSON字符串,用阿里巴巴的 " JSON.toJSONString " 方法即可转换成JSON字符串,我个人觉得比较方便。其他的方式也可以洛。
必须加上请求头,他才承认你
” httpPost.setHeader(“Content-Type”,“application/json”); “
/**
* post请求JSON格式
* @param url
* @param string
* @return
*/
public static String postAndJson(String url,String string){
try{
System.out.println("访问路径:"+url);
CloseableHttpClient httpClient = HttpClients.createDefault();
//设置url
HttpPost httpPost=new HttpPost(url);
//设置参数
StringEntity requestEntity = new StringEntity(string,"utf-8");
requestEntity.setContentEncoding("UTF-8");
httpPost.setEntity(requestEntity);
//设置请求头
httpPost.setHeader("Content-Type","application/json");
//发送请求,设置返回数据。
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String str = httpClient.execute(httpPost, responseHandler);
return str;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
根据post请求可以得出,这一系列规律。非JSON数据,就是直接拼接url。而json格式需要加上请求头和设置json参数。
根据这个规律,可以把put和delete方法,写出来。但是delete方法比较特殊,他没有设置参数的 setEntity 方法,预知后事如何,请翻篇。
根据规律可以写出put方法。
非JSON格式,url拼接。
/**
* put请求非JSON格式,其实就是参数直接拼接
* @param url
* @return
*/
public static String put(String url, Map<String,String> params){
try{
System.out.println("访问路径:"+url);
CloseableHttpClient httpClient = HttpClients.createDefault();
//设置参数
// 创建访问的地址,拼接参数到url后方
URIBuilder uriBuilder = new URIBuilder(url);
for(Map.Entry<String, String> entry : params.entrySet()){
uriBuilder.setParameter(entry.getKey(),entry.getValue());
}
//设置url
HttpPut httpPut=new HttpPut(uriBuilder.build());
//发送请求,设置返回数据。
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String str = httpClient.execute(httpPut, responseHandler);
return str;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
JSON格式
/**
* put请求JSON格式
* @param url
* @param string
* @return
*/
public static String putAndJson(String url,String string){
try{
System.out.println("访问路径:"+url);
CloseableHttpClient httpClient = HttpClients.createDefault();
//设置url
HttpPut httpPut=new HttpPut(url);
//设置参数
StringEntity requestEntity = new StringEntity(string,"utf-8");
requestEntity.setContentEncoding("UTF-8");
httpPut.setEntity(requestEntity);
//设置请求头
httpPut.setHeader("Content-Type","application/json");
//发送请求,设置返回数据。
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String str = httpClient.execute(httpPut, responseHandler);
return str;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
非json格式
/**
* delete请求非JSON格式,其实就是参数直接拼接
* @param url
* @return
*/
public static String delete(String url, Map<String,String> params){
try{
System.out.println("访问路径:"+url);
CloseableHttpClient httpClient = HttpClients.createDefault();
//设置参数
// 创建访问的地址,拼接参数到url后方
URIBuilder uriBuilder = new URIBuilder(url);
for(Map.Entry<String, String> entry : params.entrySet()){
uriBuilder.setParameter(entry.getKey(),entry.getValue());
}
//设置url
HttpDelete httpDelete=new HttpDelete(uriBuilder.build());
//发送请求,设置返回数据。
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String str = httpClient.execute(httpDelete, responseHandler);
return str;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
JSON格式
由于delete方法没有设置参数的方法,所以要用JSON格式的话我们要重新写一个类用来替代HttpDelete。这个类也是网上多篇文章总和尝试之后写出来的。
HttpDeleteWithBody
package com.example.send.util;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import java.net.URI;
/**
* 替代HttpDelete ,让delete的方法可以添加JSON数据集
*/
public class HttpDeleteWithBody extends HttpEntityEnclosingRequestBase {
public static final String METHOD_NAME = "DELETE";
public HttpDeleteWithBody() {
super();
}
@Override
public String getMethod() {
return METHOD_NAME;
}
public HttpDeleteWithBody(final String uri) {
super();
setURI(URI.create(uri));
}
public HttpDeleteWithBody(final URI uri) {
super();
setURI(uri);
}
}
剩下的用法和put,post一样。设置请求头,设置参数就好了。
/**
* delete请求JSON格式
* @param url
* @param string
* @return
*/
public static String deleteAndJson(String url,String string){
try{
System.out.println("访问路径:"+url);
CloseableHttpClient httpClient = HttpClients.createDefault();
//设置url
HttpDeleteWithBody httpDelete=new HttpDeleteWithBody(url);
//设置参数
StringEntity requestEntity = new StringEntity(string,"utf-8");
requestEntity.setContentEncoding("UTF-8");
httpDelete.setEntity(requestEntity);
//设置请求头
httpDelete.setHeader("Content-Type","application/json");
//发送请求,设置返回数据。
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String str = httpClient.execute(httpDelete, responseHandler);
return str;
}catch (Exception e){
e.printStackTrace();
}
return null;
}
其他里面很多还没有搞懂,也可能写错一些。不过现在能用,我也就勉勉强强用一下吧,万一有问题,就会有下一篇博客。(●’◡’●)
记录一下遇到的问题,希望能帮到自己也帮到别人( * ^ _ ^ * )。
阿里巴巴json转换依赖。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</dependency>