OkHttp依赖包:
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.83</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
基于JSONObject的OkHttp工具类:
如果不喜欢用 json 做参数,可以跳过,看后面的 基于map的OkHttp工具类:
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.io.FileUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
@Slf4j
public class OkHttpUtil {
public static final String MEDIA_TYPE_JSON = "application/json; charset=utf-8";
private OkHttpUtil() {
}
/**
* 获取默认的OkHttpClient
* @return
*/
public static OkHttpClient getOkHttpClient() {
return getOkHttpClient(10, 10, 10);
}
public static OkHttpClient getOkHttpClient(int connectTimeout, int readTimeOut, int writeTimeOut) {
OkHttpClient.Builder builder = new okhttp3.OkHttpClient().newBuilder();
builder.connectTimeout(connectTimeout, TimeUnit.SECONDS);
builder.readTimeout(readTimeOut, TimeUnit.SECONDS);
builder.writeTimeout(writeTimeOut, TimeUnit.SECONDS);
return builder.build();
}
/**
* get请求
* @param okHttpClient
* @param url
* @param headers header参数
* @return
*/
public static String get(OkHttpClient okHttpClient, String url, Headers headers) {
log.info("okHttpClient get url:{}.", url);
Request request = new Request.Builder().url(url).headers(headers).get().build();
String responseData = request(okHttpClient, url, request);
log.info("okHttpClient get url:{},request responseData====> {}", url, responseData);
return responseData;
}
public static String get(OkHttpClient okHttpClient, String url) {
Headers headers = new Headers.Builder().build();
return get( okHttpClient, url, headers);
}
/**
* GET请求。使用默认的 okHttpClient 和 headers
* @param url
* @return
*/
public static String get(String url) {
OkHttpClient okHttpClient = getOkHttpClient();
Headers headers = new Headers.Builder().build();
return get( okHttpClient, url, headers);
}
/**
* post请求,获取响应结果
*
* @param okHttpClient
* @param url
* @param bodyJson
* @param headers
* @return
*/
public static String post(OkHttpClient okHttpClient, String url, JSONObject bodyJson, Headers headers) {
log.info("okHttpClient post url:{}, body====> {}", url, bodyJson);
MediaType mediaTypeJson = MediaType.parse(MEDIA_TYPE_JSON);
RequestBody requestBody = RequestBody.create(mediaTypeJson, JSON.toJSONString(bodyJson));
Request request = new Request.Builder().url(url).headers(headers).post(requestBody).build();
String responseData = request(okHttpClient, url, request);
log.info("okHttpClient post url:{},post responseData====> {}", url, responseData);
return responseData;
}
public static String post(OkHttpClient okHttpClient, String url, JSONObject bodyJson) {
Headers headers = new Headers.Builder().build();
return post( okHttpClient, url, bodyJson, headers);
}
/**
* post请求。使用默认的 okHttpClient 和 headers
* @param url
* @param bodyJson
* @return
*/
public static String post( String url, JSONObject bodyJson) {
//使用默认的 okHttpClient
OkHttpClient okHttpClient = getOkHttpClient();
Headers headers = new Headers.Builder().build();
//如果需要自定义 okHttpClient或headers传参,可以调用以下方法
return post( okHttpClient, url, bodyJson, headers);
}
/**
* 获取响应结果
*
* @param okHttpClient
* @param url
* @param request
* @return
*/
public static String request(OkHttpClient okHttpClient, String url, Request request) {
String responseData = "";
try (Response response = okHttpClient.newCall(request).execute()) {
if (response != null && response.body() != null) {
return response.body().string();
}
} catch (Exception e) {
log.error("okHttpClient getResponse error.url:{}", url, e);
}
return responseData;
}
/**
* 上传文件
*
* @param okHttpClient okHttp客户端
* @param uploadFileUrl 上传文件的url
* @param multipartFile 文件对应的multipartFile
* @param fileKey 文件对应的key
* @param formDataJson form-data参数
* @param headers
* @return
*/
public static String uploadFile(OkHttpClient okHttpClient, String uploadFileUrl,
MultipartFile multipartFile, String fileKey, JSONObject formDataJson, Headers headers) {
log.info("uploadFile url:{}, uploadFile formDataJson====> {}", uploadFileUrl, formDataJson);
// 支持传文件的同时,传参数。
MultipartBody requestBody = getMultipartBody(multipartFile, fileKey, formDataJson);
// 构建request请求体
Request request = new Request.Builder().url(uploadFileUrl).headers(headers).post(requestBody).build();
String responseData = request(okHttpClient, uploadFileUrl, request);
File file = getFile(multipartFile);
// 会在本地产生临时文件,用完后需要删除
if (file.exists()) {
file.delete();
}
return responseData;
}
public static String uploadFile(OkHttpClient okHttpClient, String uploadFileUrl,
MultipartFile multipartFile, String fileKey, JSONObject formDataJson) {
Headers headers = new Headers.Builder().build();
return uploadFile(okHttpClient, uploadFileUrl, multipartFile, fileKey, formDataJson, headers);
}
/**
* 上传文件
* @param uploadFileUrl
* @param multipartFile
* @param fileKey form-data文件对应的key
* @param formDataJson form-data参数
* @return
*/
public static String uploadFile( String uploadFileUrl,
MultipartFile multipartFile, String fileKey, JSONObject formDataJson) {
//使用默认的okHttpClient
OkHttpClient okHttpClient = getOkHttpClient();
Headers headers = new Headers.Builder().build();
return uploadFile(okHttpClient, uploadFileUrl, multipartFile, fileKey, formDataJson, headers);
}
/**
* 上传文件用。构建form-data 参数
*
* @param multipartFile 文件对应的multipartFile
* @param fileKey 文件对应的key
* @param formDataJson form-data参数
* @return
*/
public static MultipartBody getMultipartBody(MultipartFile multipartFile, String fileKey, JSONObject formDataJson) {
File file = getFile(multipartFile);
RequestBody fileBody = RequestBody.create(MultipartBody.FORM, file);
MultipartBody.Builder bodyBuilder = new MultipartBody.Builder();
// 设置传参为form-data格式
bodyBuilder.setType(MultipartBody.FORM);
bodyBuilder.addFormDataPart(fileKey, file.getName(), fileBody);
// 添加 form-data参数
for (Map.Entry<String, Object> entry : formDataJson.entrySet()) {
//参数通过 bodyBuilder.addFormDataPart(key, value) 添加
bodyBuilder.addFormDataPart(entry.getKey(), Objects.toString(entry.getValue(),""));
}
return bodyBuilder.build();
}
/**
* 获取文件
* @param multipartFile
* @return
*/
public static File getFile(MultipartFile multipartFile) {
File file = new File(Objects.requireNonNull(multipartFile.getOriginalFilename()));
try {
FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), file);
} catch (IOException e) {
log.error("copyInputStreamToFile error.", e);
}
return file;
}
}
okHttp配置类
如果使用的是SpringBoot,也可以用 @Configuration 配置一下okHttp。
如果不想配置,也可以直接用默认的。
@Configuration
public class OkHttpConfig {
@Bean
public OkHttpClient okHttpClient() {
OkHttpClient.Builder builder = new okhttp3.OkHttpClient().newBuilder();
builder.connectTimeout(10, TimeUnit.SECONDS);
builder.readTimeout(10, TimeUnit.SECONDS);
builder.writeTimeout(10, TimeUnit.SECONDS);
return builder.build();
}
}
配置好了之后,直接用 @Autowired 实例化。
@Autowired
private OkHttpClient okHttpClient;
使用示例:
- POST请求:
@Test
public void testPost() {
//bean对象转json
JSONObject json = (JSONObject) JSONObject.toJSON(bean);
String url = "http://xx.xx.xx.xx:8080/xx/xx";
String response = OkHttpUtil.post( url, json);
}
- GET请求:
@Test
public void testGet() {
String url = "http://xx.xx.xx.xx:8080/xx/xx";
String response = OkHttpUtil.get( url);
}
- 上传文件:
@Test
public void testUploadFile() throws Exception {
//表单的key和value
JSONObject formDataJson = new JSONObject();
formDataJson.put("XX", "XX");
// 上传文件, 采用form-data格式, multipartFile类从spring控制层拿到,"fileData"为文件对应的key
String responseData = OkHttpUtil.uploadFile(url, multipartFile, "fileData", formDataJson);
}
对应的postman请求如下:
基于Map的OkHttp 工具类:
如果不喜欢用 json 做参数,可以用以下的基于 map 的OkHttp工具类:
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.io.FileUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
@Slf4j
public class OkHttpUtil {
public static final String MEDIA_TYPE_JSON = "application/json; charset=utf-8";
private OkHttpUtil() {
}
/**
* 获取默认的OkHttpClient
* @return
*/
public static OkHttpClient getOkHttpClient() {
return getOkHttpClient(10, 10, 10);
}
public static OkHttpClient getOkHttpClient(int connectTimeout, int readTimeOut, int writeTimeOut) {
OkHttpClient.Builder builder = new okhttp3.OkHttpClient().newBuilder();
builder.connectTimeout(connectTimeout, TimeUnit.SECONDS);
builder.readTimeout(readTimeOut, TimeUnit.SECONDS);
builder.writeTimeout(writeTimeOut, TimeUnit.SECONDS);
return builder.build();
}
/**
* get请求
* @param okHttpClient
* @param url
* @param headers header参数
* @return
*/
public static String get(OkHttpClient okHttpClient, String url, Headers headers) {
log.info("okHttpClient get url:{}.", url);
Request request = new Request.Builder().url(url).headers(headers).get().build();
String responseData = request(okHttpClient, url, request);
log.info("okHttpClient get url:{},request responseData====> {}", url, responseData);
return responseData;
}
public static String get(OkHttpClient okHttpClient, String url) {
Headers headers = new Headers.Builder().build();
return get( okHttpClient, url, headers);
}
/**
* GET请求。使用默认的 okHttpClient 和 headers
* @param url
* @return
*/
public static String get(String url) {
OkHttpClient okHttpClient = getOkHttpClient();
Headers headers = new Headers.Builder().build();
return get( okHttpClient, url, headers);
}
/**
* post请求,获取响应结果
*
* @param okHttpClient
* @param url
* @param map
* @param headers
* @return
*/
public static String post(OkHttpClient okHttpClient, String url, Map<String,Object> map, Headers headers) {
log.info("okHttpClient post url:{}, body====> {}", url, map);
MediaType mediaTypeJson = MediaType.parse(MEDIA_TYPE_JSON);
//map需要转成json字符串
RequestBody requestBody = RequestBody.create(mediaTypeJson, JSON.toJSONString(map));
Request request = new Request.Builder().url(url).headers(headers).post(requestBody).build();
String responseData = request(okHttpClient, url, request);
log.info("okHttpClient post url:{},post responseData====> {}", url, responseData);
return responseData;
}
public static String post(OkHttpClient okHttpClient, String url, Map<String,Object> map) {
Headers headers = new Headers.Builder().build();
return post( okHttpClient, url, map, headers);
}
/**
* post请求。使用默认的 okHttpClient 和 headers
* @param url
* @param map
* @return
*/
public static String post( String url, Map<String,Object> map) {
//使用默认的 okHttpClient
OkHttpClient okHttpClient = getOkHttpClient();
Headers headers = new Headers.Builder().build();
//如果需要自定义 okHttpClient或headers传参,可以调用以下方法
return post( okHttpClient, url, map, headers);
}
/**
* 获取响应结果
*
* @param okHttpClient
* @param url
* @param request
* @return
*/
public static String request(OkHttpClient okHttpClient, String url, Request request) {
String responseData = "";
try (Response response = okHttpClient.newCall(request).execute()) {
if (response != null && response.body() != null) {
return response.body().string();
}
} catch (Exception e) {
log.error("okHttpClient getResponse error.url:{}", url, e);
}
return responseData;
}
/**
* 上传文件
*
* @param okHttpClient okHttp客户端
* @param uploadFileUrl 上传文件的url
* @param multipartFile 文件对应的multipartFile
* @param fileKey 文件对应的key
* @param map form-data参数
* @param headers
* @return
*/
public static String uploadFile(OkHttpClient okHttpClient, String uploadFileUrl,
MultipartFile multipartFile, String fileKey, Map<String,Object> map, Headers headers) {
log.info("uploadFile url:{}, uploadFile formDataJson====> {}", uploadFileUrl, map);
// 支持传文件的同时,传参数。
MultipartBody requestBody = getMultipartBody(multipartFile, fileKey, map);
// 构建request请求体
Request request = new Request.Builder().url(uploadFileUrl).headers(headers).post(requestBody).build();
String responseData = request(okHttpClient, uploadFileUrl, request);
File file = getFile(multipartFile);
// 会在本地产生临时文件,用完后需要删除
if (file.exists()) {
file.delete();
}
return responseData;
}
public static String uploadFile(OkHttpClient okHttpClient, String uploadFileUrl,
MultipartFile multipartFile, String fileKey, Map<String,Object> map) {
Headers headers = new Headers.Builder().build();
return uploadFile(okHttpClient, uploadFileUrl, multipartFile, fileKey, map, headers);
}
/**
* 上传文件
* @param uploadFileUrl
* @param multipartFile
* @param fileKey form-data文件对应的key
* @param map form-data参数
* @return
*/
public static String uploadFile( String uploadFileUrl,
MultipartFile multipartFile, String fileKey, Map<String,Object> map) {
//使用默认的okHttpClient
OkHttpClient okHttpClient = getOkHttpClient();
Headers headers = new Headers.Builder().build();
return uploadFile(okHttpClient, uploadFileUrl, multipartFile, fileKey, map, headers);
}
/**
* 上传文件用。构建form-data 参数
*
* @param multipartFile 文件对应的multipartFile
* @param fileKey 文件对应的key
* @param formDataMap form-data参数
* @return
*/
public static MultipartBody getMultipartBody(MultipartFile multipartFile, String fileKey, Map<String,Object> formDataMap) {
File file = getFile(multipartFile);
RequestBody fileBody = RequestBody.create(MultipartBody.FORM, file);
MultipartBody.Builder bodyBuilder = new MultipartBody.Builder();
// 设置传参为form-data格式
bodyBuilder.setType(MultipartBody.FORM);
bodyBuilder.addFormDataPart(fileKey, file.getName(), fileBody);
// 添加 form-data参数
for (Map.Entry<String, Object> entry : formDataMap.entrySet()) {
//参数通过 bodyBuilder.addFormDataPart(key, value) 添加
bodyBuilder.addFormDataPart(entry.getKey(), Objects.toString(entry.getValue(),""));
}
return bodyBuilder.build();
}
/**
* 获取文件
* @param multipartFile
* @return
*/
public static File getFile(MultipartFile multipartFile) {
File file = new File(Objects.requireNonNull(multipartFile.getOriginalFilename()));
try {
FileUtils.copyInputStreamToFile(multipartFile.getInputStream(), file);
} catch (IOException e) {
log.error("copyInputStreamToFile error.", e);
}
return file;
}
}
Bean和Map的转换工具
如果使用基于 map 的OkHttp工具类,需要传map做参数时,可以用 Bean和Map转换的工具类。
详情见: https://www.cnblogs.com/expiator/p/17357352.html