一、背景:
我们写 http请求的post json方法,也写了post form方法,当调用的时候,我们要根据不同的类型使用,不同的post方法。
这里引入责任链模式,我们则在做请求的时候,不需要判断参数的类型,统一使用一种请求方式。
二、实现
1、我们使用责任链模式,post json 不能处理,交给下一个post form处理
2、责任链中的Manger的实现,使用了单例模式
3、在编写自己的HttpRqeust的类时,使用了建造者模式。
2.1 编写自定义的类,HttpRquest 与HttpRespone
okhttp 这个包里,有请求类Request 与返回类Response。
我们为了方便扩展自己的功能,我们重新定义一下自己的类。
HttpRequest
package com.example.autoapi.model;
import lombok.Getter;
import lombok.ToString;
import java.util.Map;
@ToString
@Getter
public class HttpRequest {
private String url;
private Map<String,String> headers;
private Object data;
private Map<String,Object> params;
private MethodType methodType;
private ContentType contentType;
// 这里自己写一个建造者模式,不直接用@Builder,是为了方便自己扩展
// 一个静态的Builder
public static Builder builder(){
return new Builder();
}
// 构造器
public HttpRequest(Builder builder){
this.url = builder.url;
this.headers = builder.headers;
this.data = builder.data;
this.params = builder.params;
this.methodType = builder.methodType;
this.contentType = builder.contentType;
}
// 这是一个内部类
public static class Builder{
private String url;
private Map<String,String> headers;
private Object data;
private Map<String,Object> params;
private MethodType methodType;
private ContentType contentType;
public Builder url(String url) {
this.url = url;
return this;
}
public Builder headers(Map<String, String> headers) {
this.headers = headers;
return this;
}
public Builder data(Object data) {
this.data = data;
return this;
}
public Builder params(Map<String, Object> params) {
this.params = params;
return this;
}
public Builder methodType(MethodType methodType) {
this.methodType = methodType;
return this;
}
public Builder post() {
this.methodType = MethodType.POST;
return this;
}
public Builder postForm() {
this.methodType = MethodType.POST;
this.contentType = ContentType.FORM;
return this;
}
public Builder postJson() {
this.methodType = MethodType.POST;
this.contentType = ContentType.JSON;
return this;
}
public Builder get() {
this.methodType = MethodType.GET;
return this;
}
public Builder contentType(ContentType contentType) {
this.contentType = contentType;
return this;
}
public Builder json() {
this.contentType = ContentType.JSON;
return this;
}
public Builder form() {
this.contentType = ContentType.FORM;
return this;
}
public HttpRequest build(){
return new HttpRequest(this);
}
}
}
这里自己写一个建造者模式,不直接用@Builder,是为了方便自己扩展
HttpResponse
package com.example.autoapi.model;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class HttpResponse {
private String body;
}
2.2 AbstractHttpHandle
责任链模式的学习:
责任链设计模式_傲娇的喵酱的博客-
这里就是具体实现责任链模式了
package com.example.autoapi.http.chain;
import com.example.autoapi.model.HttpRequest;
import com.example.autoapi.model.HttpResponse;
import okhttp3.Call;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
// 抽象类
public abstract class AbstractHttpHandle {
private AbstractHttpHandle httpHandle;
public void setHttpHandle(AbstractHttpHandle httpHandle) {
this.httpHandle = httpHandle;
}
// 抽象方法
// 判断,当时是否能处理,ture,自己处理,false交给下一个处理
protected abstract boolean preHttp(HttpRequest request);
// 具体的
protected abstract Request createRequest(HttpRequest request);
// 抽象方法
// 具体的处理逻辑
protected HttpResponse onHttp(HttpRequest httpRequest){
// 将我们自定义的httpRequest,转成请求要用的request
Request request = createRequest(httpRequest);
// 发送这个请求,并得到返回值
return handleRequest(request);
};
// 发送请求的,得到返回值HttpResponse的固定写法
private HttpResponse handleRequest(Request request){
OkHttpClient client = new OkHttpClient();
Call call = client.newCall(request);
try {
Response response = call.execute();
String body = response.body().string();
return new HttpResponse(body);
} catch (IOException e) {
throw new IllegalStateException(e);
}
}
// 模版,规定好了整个流程的逻辑
public HttpResponse doHttp(HttpRequest request){
if(preHttp(request)){
// 如果能处理,则直接处理
return onHttp(request);
}
// 如果不能处理
// 交给下一个处理
if(httpHandle != null){
return httpHandle.doHttp(request);
}
throw new IllegalStateException("unknow http request");
}
}
实现类 PostFormHttpHandle
package com.example.autoapi.http.chain;
import com.example.autoapi.model.ContentType;
import com.example.autoapi.model.HttpRequest;
import com.example.autoapi.model.MethodType;
import okhttp3.FormBody;
import okhttp3.Headers;
import okhttp3.Request;
import okhttp3.RequestBody;
import java.util.HashMap;
import java.util.Map;
public class PostFormHttpHandle extends AbstractHttpHandle{
@Override
protected boolean preHttp(HttpRequest request) {
// 判断是否能处理
return request.getContentType()== ContentType.FORM && request.getMethodType()== MethodType.POST;
}
@Override
protected Request createRequest(HttpRequest httpRequest) {
FormBody.Builder builder= new FormBody.Builder();
for (Map.Entry<String,Object> entry:httpRequest.getParams().entrySet()){
builder.add(entry.getKey(), String.valueOf(entry.getValue()));
}
RequestBody requestBody = builder.build();
Request request = new Request.Builder()
.url(httpRequest.getUrl())
.headers(Headers.of(httpRequest.getHeaders()==null?new HashMap<>():httpRequest.getHeaders()))
.post(requestBody)
.build();
return request;
}
}
实现类 PostJsonHttpHandle
package com.example.autoapi.http.chain;
import com.example.autoapi.model.ContentType;
import com.example.autoapi.model.HttpRequest;
import com.example.autoapi.model.MethodType;
import com.google.gson.Gson;
import okhttp3.Headers;
import okhttp3.MediaType;
import okhttp3.Request;
import okhttp3.RequestBody;
import java.util.HashMap;
public class PostJsonHttpHandle extends AbstractHttpHandle{
@Override
protected boolean preHttp(HttpRequest request) {
// 判断是否能处理
return request.getContentType()== ContentType.JSON && request.getMethodType()== MethodType.POST;
}
// 这里的具体处理方式,不是去发送请求,而是构建request
// 将 HttpRequest --》 Request
// 构建post json 的request
@Override
protected Request createRequest(HttpRequest httpRequest) {
MediaType mediaType = MediaType.parse("application/json");
// Gson是json工具类,将x转成json
Gson gson = new Gson();
RequestBody requestBody = RequestBody.create(gson.toJson(httpRequest.getData()), mediaType);
Request request = new Request.Builder()
.url(httpRequest.getUrl())
.headers(Headers.of(httpRequest.getHeaders()==null?new HashMap<>():httpRequest.getHeaders()))
.post(requestBody)
.build();
return request;
}
}
HttpHandleManager
package com.example.autoapi.http.chain;
import com.example.autoapi.model.HttpRequest;
import com.example.autoapi.model.HttpResponse;
public class HttpHandleManager {
private AbstractHttpHandle httpHandle;
// 构造器,私有,不能被new
private HttpHandleManager(){
httpHandle = initHandle();
}
private AbstractHttpHandle initHandle() {
PostJsonHttpHandle postJsonHttpHandle = new PostJsonHttpHandle();
PostFormHttpHandle postFormHttpHandle = new PostFormHttpHandle();
// 将json与form串起来
postJsonHttpHandle.setHttpHandle(postFormHttpHandle);
return postJsonHttpHandle;
}
// ClassHolder属于静态内部类,在加载类Demo03的时候,只会加载内部类ClassHolder,
// 但是不会把内部类的属性加载出来
private static class ClassHolder{
// 这里执行类加载,是jvm来执行类加载,它一定是单例的,不存在线程安全问题
// 这里不是调用,是类加载,是成员变量
private static final HttpHandleManager holder =new HttpHandleManager();
}
public static HttpHandleManager of(){//第一次调用getInstance()的时候赋值
return ClassHolder.holder;
}
// 去做请求
// 用第一个节点/用这条链,去处理请求
public HttpResponse doRequest(HttpRequest httpRequest){
return httpHandle.doHttp(httpRequest);
}
}
调用
package com.example.autoapi.http;
import com.example.autoapi.http.chain.HttpHandleManager;
import com.example.autoapi.http.service.HttpService;
import com.example.autoapi.model.HttpRequest;
import com.example.autoapi.model.HttpResponse;
public class HttpFacade {
public static String doPostJson(String url,Object data){
return new HttpService().doPostJson(url, data);
}
public static HttpResponse doRequest(HttpRequest httpRequest){
return HttpHandleManager.of().doRequest(httpRequest);
}
}
HttpRequest httpRequest = HttpRequest.builder()
.postJson()
.url(url)
.data(data)
.build();
HttpFacade.doRequest(httpRequest);
上一章:
下一章:
十一、junit5 自定义参数化注解_傲娇的喵酱的博客