java:接口请求
1 前言
构建java请求接口的工具类前,先使用SpringBoot增加get、post请求的有参、无参接口。如下:
package com.xiaoxu.controller;
import com.google.common.collect.ImmutableMap;
import com.xiaoxu.domain.Fruit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
/**
* @author xiaoxu
* @date 2022-01-10
* Ymybatis:com.xiaoxu.controller.FruitController
*/
@PropertySource(value = {"classpath:jdbc.properties","classpath:application.yml","classpath:ts.properties"},encoding = "utf-8")
@RestController
@Slf4j
public class FruitController {
// @Autowired
// @Qualifier(value = "myfruit")
// Fruit f;
@Autowired
// @Qualifier(value = "myfruit")
@Qualifier(value = "lizhi_fruit")
Fruit f;
// @Value("#{new BigDecimal(\"12.0\").add(new BigDecimal(\"15.0\"))}")
@Value("#{'Xiaoxu'}")
String a;
@Value("${name}")
String o;
@GetMapping("/fruit/{id}/shop/{address}")
public Map<String,Object> getFruitByAddress(@PathVariable("id") Integer myId,
@PathVariable("address") String ads,
@PathVariable Map<String,String> map,
@RequestHeader("User-Agent") String header,
@RequestHeader Map<String,String> headers)
{
return ImmutableMap.<String,Object>builder().put("number",myId)
.put("MyAddress",ads)
.put("KV",map)
.put("singleUserAgent",header)
.put("allHeaders",headers)
// .put("body",body)
.build();
}
@RequestMapping(path = "/fruit",method = RequestMethod.GET)
public Map<String,Object> fruit(){
return new HashMap<String,Object>(){{
put("Get",f);
put("你好","wohao");
put("我很好","nine");
}};
}
@RequestMapping(value = "/myfruit",method = RequestMethod.POST)
public Map<String,Object> myfruit(){
return ImmutableMap.<String,Object>builder()
.put("value1",a)
.put("value2",o)
.build();
}
@RequestMapping(value = "/newFruit",method = RequestMethod.POST)
public Map<String,Object> newFr(@RequestParam Map<String,Object> payload){
return ImmutableMap.<String,Object>builder()
.put("payload",payload)
.build();
}
@RequestMapping(value = "/newFruit2",method = {RequestMethod.GET,RequestMethod.POST})
public Map<String,Object> newFr2(HttpServletRequest request){
String number = request.getParameter("number");
String[] members = request.getParameter("members").split(",");
List<String> m = Arrays.asList(members);
log.info("我是成员们:{}",m);
return ImmutableMap.<String,Object>builder()
.put("拿到参数",number)
.put("haha",new HashMap<String,String>(){{put("哈哈","嘿嘿");put("嘻嘻","到");}})
.put("哇喔","11111111")
.put("拿到成员",m)
.build();
}
@RequestMapping(value = "/fruit222",method = RequestMethod.POST)
public Map<String,Object> fruit1(){
return new HashMap<String,Object>(){{
put("Post",f);
}};
}
@RequestMapping(value = "/fruit",method = RequestMethod.DELETE)
public Map<String,Object> fruit2(){
return new HashMap<String,Object>(){{
put("Delete",f);
}};
}
@RequestMapping(path = "/fruit",method=RequestMethod.PUT)
public Map<String,Object> fruit3(){
return ImmutableMap.<String,Object>builder().put("Put",f).build();
}
}
2 构建java接口请求工具类
请求方式枚举:
package com.xiaoxu.enums;
public enum RequestMethodEnum {
// 避免java.net.ProtocolException: Invalid HTTP method: get 以及
// java.net.ProtocolException: Invalid HTTP method: post异常,应该是GET和POST
GET("GET","get请求","01"),
POST("POST","post请求","02");
private String name;
private String description;
private String code;
RequestMethodEnum(String name,String description,String code){
this.name = name;
this.description = description;
this.code = code;
}
//根据code获取请求方式
public static RequestMethodEnum getMethodByCode(String code){
for (RequestMethodEnum value : RequestMethodEnum.values()) {
if(value.getCode().equals(code)){
return value;
}
}
return null;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
}
fastjson依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.79</version>
</dependency>
java接口请求封装的工具类:
package com.xiaoxu.utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.xiaoxu.enums.RequestMethodEnum;
import org.springframework.stereotype.Component;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
/**
* @author xiaoxu
* @date 2022-03-03
* spring_boot:com.xiaoxu.utils.RequestUtil
*/
@Component
public class RequestUtil {
public static void main(String[] args) {
RequestUtil.request();
}
public static void request(){
//1 post 无参
String path1 = "http://localhost:8088"+"/myfruit";
//2 get 无参
String path2 = "http://localhost:8088"+"/fruit";
//3 post 有参
String path3 = "http://localhost:8088"+"/newFruit";
//4 get 有参
String path4 = "http://localhost:8088"+"/newFruit2";
//1 post 无参
System.out.println("*************第1次请求************");
RequestUtil.printPrettyJsonResult(RequestUtil.buildRequest(RequestMethodEnum.POST.getName(), path1,null,null));
//2 get 无参
System.out.println("*************第2次请求************");
RequestUtil.printPrettyJsonResult(RequestUtil.buildRequest(RequestMethodEnum.GET.getName(), path2,"",null));
//3 post 有参
System.out.println("*************第3次请求************");
String payload = RequestUtil.buildPayloadStr(new HashMap<String,Object>(){{
put("name","xiaoxu");
put("age",18);
put("interests",new ArrayList<String>(){{add("羽毛球");add("sing");}});
}});
RequestUtil.printPrettyJsonResult(RequestUtil.buildRequest(RequestMethodEnum.POST.getName(),path3,payload,null));
//4 get 有参
System.out.println("*************第4次请求************");
String param = RequestUtil.buildParamsStr(new HashMap<String,Object>(){{
put("members",new ArrayList<String>(){{add("小徐");add("小李");}});
put("number","9527");
put("name","小黑");
put("book","打字入门");
}});
RequestUtil.printPrettyJsonResult(RequestUtil.buildRequest(RequestMethodEnum.GET.getName(),path4,param,null));
}
public static String buildRequest(String method, String urlPath, String data, Map<String,String> headerMap){
StringBuilder str = new StringBuilder();
try {
//处理data,如果data为null,转换成"",否则data.getBytes会抛出空指针异常
data = Optional.ofNullable(data).orElse("");
data = data.replace(" ","");
if("get".equals(method.toLowerCase(Locale.ROOT))){
//get请求需要拼接路径(无参数,data应该是"",有参数则拼接)
urlPath+=data;
}
// System.out.println("请求的url:"+urlPath);
URL url = new URL(urlPath);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
if(headerMap!=null){
//设置请求头的属性,比如:Cookie,Token等等
//System.out.println("key:"+k+";"+"value:"+v);
headerMap.forEach(connection::setRequestProperty);
}
//设置请求方式
connection.setRequestMethod(method);
//post不同于get,get只需要将请求参数拼接到url中,而post请求的是正文
if("post".equals(method.toLowerCase(Locale.ROOT))){
// post请求不能使用缓存
connection.setUseCaches(false);
// post参数不是放在URL字符串里,而是http请求的正文
// post:http正文内,因此需要设为true
connection.setDoOutput(true);
//connection获取输出的流,write写入post请求的参数:格式:key=value&key1=value1
OutputStream outputStream = connection.getOutputStream();
//String的getBytes,字符串转字节
byte[] postBytes = data.getBytes(StandardCharsets.UTF_8);
outputStream.write(postBytes);
}
//获取URLConnection对象对应的输入流
InputStream in = connection.getInputStream();
//将接口请求的接口打印出来
BufferedReader b = new BufferedReader(new InputStreamReader(in));
String s;
while((s=b.readLine())!=null){
str.append(s);
}
//关闭流
in.close();
//关闭连接
connection.disconnect();
} catch (IOException e) {
e.printStackTrace();
}
return str.toString();
}
//构建post请求参数,类似:key = value & key1 = value1
//当post请求是Content-Type:x-www-form-urlencoded(表单提交时使用)
public static String buildPayloadStr(Map<String,Object> payloadMap){
StringBuilder s = new StringBuilder();
for(Map.Entry<String,Object> m:payloadMap.entrySet()){
if(s.length()==0){
s.append(m.getKey()).append("=").append(m.getValue());
}else{
s.append("&").append(m.getKey()).append("=").append(m.getValue());
}
}
return s.toString();
}
//构建post请求2:json字符串格式,当请求头设置了"Content-Type","application/json;charset=UTF-8"时使用
public static String buildJsonPayloadStr(Map<String,Object> payloadMap){
return JSON.toJSONString(payloadMap);
}
//构建get请求的参数url,类似:?key=value&key1=value1
public static String buildParamsStr(Map<String,Object> paramsMap){
paramsMap = Optional.ofNullable(paramsMap).orElse(new HashMap<>());
StringBuilder s = new StringBuilder();
StringBuilder temp = new StringBuilder();
try{
for(Map.Entry<String,Object> m: paramsMap.entrySet()) {
if (m.getValue() instanceof List) {
Iterator<?> iter =((List<?>) m.getValue()).iterator();
StringBuilder rep = new StringBuilder();
while(iter.hasNext()){
String s1 = String.valueOf(iter.next());
if(rep.length()==0){
rep.append(URLEncoder.encode(m.getKey(),"utf-8")).append("=").append(URLEncoder.encode(s1,"utf-8"));
}else{
rep.append(URLEncoder.encode(",","utf-8")).append(URLEncoder.encode(s1,"utf-8"));
}
}
if(temp.length()==0){
temp.append(rep);
}else{
temp.append("&").append(rep);
}
} else if(m.getValue() instanceof String){
if(temp.length()==0){
temp.append(URLEncoder.encode(m.getKey(),"utf-8")).append("=").append(URLEncoder.encode(String.valueOf(m.getValue()),"utf-8"));
}else{
temp.append("&").append(URLEncoder.encode(m.getKey(),"utf-8")).append("=").append(URLEncoder.encode(String.valueOf(m.getValue()),"utf-8"));
}
}else if(m.getValue() instanceof Integer){
if(temp.length()==0){
temp.append(URLEncoder.encode(m.getKey(),"utf-8")).append("=").append(URLEncoder.encode(String.valueOf(m.getValue()),"utf-8"));
}else{
temp.append("&").append(URLEncoder.encode(m.getKey(),"utf-8")).append("=").append(URLEncoder.encode(String.valueOf(m.getValue()),"utf-8"));
}
}
else{
throw new RuntimeException("存在value非String或者List或非Integer的数据");
}
}
}catch (UnsupportedEncodingException e){
e.printStackTrace();
}catch (Exception e){
throw new RuntimeException("未知异常:" + e.getMessage());
}
if (temp.length() != 0) {
s.append("?").append(temp);
}
return s.toString();
}
public static void printPrettyJsonResult(String s){
JSONObject jsonObject = JSON.parseObject(s);
System.out.println("接口返回结果:");
System.out.println(JSON.toJSONString(jsonObject, SerializerFeature.PrettyFormat));
}
}
执行RequestUtil的main方法,结果如下:
*************第1次请求************
请求的url:http://localhost:8088/myfruit
接口返回结果:
{
"value2":"李红",
"value1":"Xiaoxu"
}
*************第2次请求************
请求的url:http://localhost:8088/fruit
接口返回结果:
{
"你好":"wohao",
"Get":{
"fname":"菠萝",
"price":14.6,
"count":300,
"dropDate":"2022-01-10T04:00:00.000+00:00"
},
"我很好":"nine"
}
*************第3次请求************
请求的url:http://localhost:8088/newFruit
接口返回结果:
{
"payload":{
"name":"xiaoxu",
"interests":"[羽毛球,sing]",
"age":"18"
}
}
*************第4次请求************
请求的url:http://localhost:8088/newFruit2?number=9527&members=%E5%B0%8F%E5%BE%90%2C%E5%B0%8F%E6%9D%8E&book=%E6%89%93%E5%AD%97%E5%85%A5%E9%97%A8&name=%E5%B0%8F%E9%BB%91
接口返回结果:
{
"拿到参数":"9527",
"haha":{
"哈哈":"嘿嘿",
"嘻嘻":"到"
},
"哇喔":"11111111",
"拿到成员":[
"小徐",
"小李"
]
}