java转发器

目的:写一个外壳,把用户请求转发到不一样的微服务中java

思路:经过过滤器filter把全部请求拦截下来,而后调用okHttpHelper方法获取响应。
okHttpHelper方法内判断请求类型,调用不一样的方法进行拼接请求。
getRemoteResponse封装响应类
createCookieJar生成CookieJar能够理解为cookie的一个集合web

使用的是httpclient封装请求okhttp3,以前使用的RestTemplate,请求体会产生乱码,没法解决,最后换成okhttp3。spring

注意事项:
1.设置响应,再响应体Headers里面遍历添加
if (!CollectionUtils.isEmpty(okResponseWrap.getHeaders())) {
okResponseWrap.getHeaders().get(“Set-Cookie”).forEach(cookie -> {
servletResponse.addHeader(“Set-Cookie”, cookie);
});
}
servletResponse.setStatus(okResponseWrap.getCode());
out.write(String.valueOf(okResponseWrap.getBody()));
out.flush();
2.springboot初始化bean的顺序为:listener -> filter -> servlet -> 普通bean因此没法在filter中注入普通的bean,只能经过init方法中手工进行bean注入
ServletContext servletContext = filterConfig.getServletContext();
WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
okHttpHelper = applicationContext.getBean(OkHttpHelper.class);
3.构建请求参数遍历数组的时候记得加上索引
在这里插入图片描述json

结构

两个帮助类数组

import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;浏览器

import java.io.IOException;
import java.util.Iterator;
import java.util.Map;springboot

public class OkHttpUtil {
private static final Logger logger = LoggerFactory.getLogger(OkHttpUtil.class);服务器

/**cookie

  • get
  • @param url 请求的url
  • @param queries 请求的参数,在浏览器 ? 后面的数据,没有能够传null
  • @return
    */
    public static String get(String url, Map<String, String> queries) {
    String responseBody = “”;
    StringBuffer sb = new StringBuffer(url);
    if (queries != null && queries.keySet().size() > 0) {
    boolean firstFlag = true;
    Iterator iterator = queries.entrySet().iterator();
    while (iterator.hasNext()) {
    Map.Entry entry = (Map.Entry<String, String>) iterator.next();
    if (firstFlag) {
    sb.append("?" + entry.getKey() + “=” + entry.getValue());
    firstFlag = false;
    } else {
    sb.append("&" + entry.getKey() + “=” + entry.getValue());
    }
    }
    }
    Request request = new Request.Builder().url(sb.toString()).build();
Response response = null;

try {
  OkHttpClient okHttpClient = new OkHttpClient();
  response = okHttpClient.newCall(request).execute();
  int status = response.code();
  if (response.isSuccessful()) {
    return response.body().string();
  }
} catch (Exception e) {
  logger.error("okhttp3 put error >> ex = {}", e.getStackTrace());
} finally {
  if (response != null) {
    response.close();
  }
}
return responseBody;

}网络

/**

  • post
  • @param url 请求的url
  • @param params post form 提交的参数
  • @return
    */
    public static String post(String url, Map<String, String> params) {
    String responseBody = “”;
    FormBody.Builder builder = new FormBody.Builder();
    //添加参数
    if (params != null && params.keySet().size() > 0) {
    for (String key : params.keySet()) {
    builder.add(key, params.get(key));
    }
    }
    Request request = new Request.Builder().url(url).post(builder.build()).build();
    Response response = null;
    try {
    OkHttpClient okHttpClient = new OkHttpClient();
    response = okHttpClient.newCall(request).execute();
    int status = response.code();
    if (response.isSuccessful()) {
    return response.body().string();
    }
    } catch (Exception e) {
    logger.error(“okhttp3 post error >> ex = {}”, e.getStackTrace());
    } finally {
    if (response != null) {
    response.close();
    }
    }
    return responseBody;
    }

/**

  • getForHeader
  • @param url 请求的url
  • @param queries 请求的参数,在浏览器 ? 后面的数据,没有能够传null
  • @return
    */
    public static String getForHeader(String url, Map<String, String> queries) {
    String responseBody = “”;
    StringBuffer sb = new StringBuffer(url);
    if (queries != null && queries.keySet().size() > 0) {
    boolean firstFlag = true;
    Iterator iterator = queries.entrySet().iterator();
    while (iterator.hasNext()){
    Map.Entry entry = (Map.Entry<String,String>)iterator.next();
    if (firstFlag){
    sb.append("?"+entry.getKey()+"="+entry.getValue());
    firstFlag = false;
    }else {
    sb.append("&"+entry.getKey()+"="+entry.getValue());
    }
    }
    }
    Request request = new Request.Builder()
    .addHeader(“key”,“value”)
    .url(sb.toString())
    .build();
    Response response = null;
    try {
    OkHttpClient okHttpClient = new OkHttpClient();
    response = okHttpClient.newCall(request).execute();
    int status = response.code();
    if (response.isSuccessful()) {
    return response.body().string();
    }
    } catch (Exception e) {
    logger.error(“okhttp3 put error >> ex = {}”, e.getStackTrace());
    } finally {
    if (response != null) {
    response.close();
    }
    }
    return responseBody;
    }

/**

  • Post请求发送JOSN数据…{“name”:“zhangsan”,“password”:“1234”}
  • @param url 请求的url
  • @param jsonParams 请求的JSON
  • 请求回调
  • @return
    */
    public static String postJsonParams(String url,String jsonParams){
    String responseBody = null;
    RequestBody requestBody = RequestBody.create(MediaType.parse(“application/json; charset=utf8”), jsonParams);
    Request request = new Request.Builder()
    .url(url)
    .post(requestBody)
    .build();
    Response response = null;
    try {
    OkHttpClient okHttpClient = new OkHttpClient();
    response = okHttpClient.newCall(request).execute();
    int status = response.code();
    if (response.isSuccessful()) {
    return response.body().string();
    }
    } catch (Exception e) {
    logger.error(“okhttp3 post error >> ex = {}”, e.getStackTrace());
    } finally {
    if (response != null) {
    response.close();
    }
    }
    return responseBody;
    }

/**

  • Post请求发送xml数据…
  • 参数一:请求Url
  • 参数二:请求的xmlString
  • 参数三:请求回调
    */
    public static String postXmlParams(String url, String xml) {
    String responseBody = “”;
    RequestBody requestBody = RequestBody.create(MediaType.parse(“application/xml; charset=utf-8”), xml);
    Request request = new Request.Builder()
    .url(url)
    .post(requestBody)
    .build();
    Response response = null;
    try {
    OkHttpClient okHttpClient = new OkHttpClient();
    response = okHttpClient.newCall(request).execute();
    int status = response.code();
    if (response.isSuccessful()) {
    return response.body().string();
    }
    } catch (Exception e) {
    logger.error(“okhttp3 post error >> ex = {}”, e.getStackTrace());
    } finally {
    if (response != null) {
    response.close();
    }
    }
    return responseBody;
    }
    }

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.*;
import java.nio.charset.Charset;

public class HttpHelper {
/**

  • 获取post请求中的Body
  • @param request
  • @return
    */
    public static String getBodyString(ServletRequest request) {
    StringBuilder sb = new StringBuilder();
    InputStream inputStream = null;
    BufferedReader reader = null;
    try {
    inputStream = request.getInputStream();
    //读取流并将流写出去,避免数据流中断; //设置编码
    reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName(“UTF-8”)));
    //reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName(“GBK”)));
    String line = “”;
    while ((line = reader.readLine()) != null) {
    sb.append(line);
    }
    } catch (IOException e) {
    e.printStackTrace();
    } finally {
    if (inputStream != null) {
    try {
    inputStream.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    if (reader != null) {
    try {
    reader.close();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    return sb.toString();
    }

public static String getResponseBodyString(ServletResponse response) {
StringBuilder sb = new StringBuilder();
OutputStream outputStream = null;
BufferedWriter writer = null;
try {
outputStream = response.getOutputStream();
//读取流并将流写出去,避免数据流中断;
writer = new BufferedWriter(new OutputStreamWriter(outputStream, Charset.forName(“UTF-8”)));
String body = “”;
writer.write(body);
sb = sb.append(body);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return sb.toString();
}

//添加自定义的信息到请求体中;
public static String appendCustomMsgToReqBody(String newReqBodyStr) {
StringBuilder sb = new StringBuilder();
InputStream inputStream = null;
BufferedReader reader = null;
String newReqBody = null;
try {
//经过字符串构造输入流;
inputStream = String2InputStream(newReqBodyStr);
reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName(“UTF-8”)));
String line = “”;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//返回字符串;
newReqBody = sb.toString();
return newReqBody;

}

//将字符串转化为输入流;
public static InputStream String2InputStream(String str) {
ByteArrayInputStream stream = null;
try {
stream = new ByteArrayInputStream(str.getBytes(“UTF-8”));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return stream;
}
}

实现方法

import okhttp3.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;

@Component
@EnableConfigurationProperties({TransmitProperties.class})
public class OkHttpHelper {

@Autowired
private OkHttpClient okHttpClient;

@Autowired
private TransmitProperties transmitProperties;

/**

  • 执行远程调用,获取响应状态码和响应体
  • @param request
  • @return
    */
    public OkResponseWrap execute(HttpServletRequest request) {
    String method = request.getMethod();
    if (method.equalsIgnoreCase(“GET”)) {
    return this.get(request);
    } else if (method.equalsIgnoreCase(“POST”)) {
    return this.post(request);
    } else if (method.equalsIgnoreCase(“DELETE”)) {
    return this.delete(request);
    } else if (method.equalsIgnoreCase(“PUT”)) {
    return this.put(request);
    } else {
    OkResponseWrap okResponseWrap = new OkResponseWrap();
    okResponseWrap.setCode(400);
    okResponseWrap.setBody(“请求异常,请检查网络!”);
    return okResponseWrap;
    }
    }

/**

  • 发起put请求
  • @param request
  • @return
    */
    private OkResponseWrap put(HttpServletRequest request) {
    //获取请求路径
    String requestUrl = request.getRequestURI().toString();
    //获取请求体
    String jsonParams = HttpHelper.getBodyString(request);
    //构造请求体
    //StringBuffer remoteUrl = new StringBuffer(this.transmitProperties.getRemoteUrl() + requestUrl.replaceFirst(this.transmitProperties.getHostUrl(), “”));
    StringBuffer remoteUrl = requestUrl(requestUrl);
    RequestBody requestBody = RequestBody.create(MediaType.parse(“application/json;charset=utf-8”), jsonParams);
    Request.Builder builder = new Request.Builder().url(remoteUrl.toString()).put(requestBody);
    Request okRequest = this.createOkRequest(builder, request);
    //发起请求
    return this.getRemoteResponse(okRequest, request);
    }

/**

  • 发起delete请求
  • @param request
  • @return
    */
    private OkResponseWrap delete(HttpServletRequest request) {
    //获取请求路径
    String requestUrl = request.getRequestURI().toString();
    //获取请求体
    String jsonParams = HttpHelper.getBodyString(request);
    //StringBuffer remoteUrl = new StringBuffer(this.transmitProperties.getRemoteUrl() + requestUrl.replaceFirst(this.transmitProperties.getHostUrl(), “”));
    StringBuffer remoteUrl = requestUrl(requestUrl);
    RequestBody requestBody = RequestBody.create(MediaType.parse(“application/json;charset=utf-8”), jsonParams);
    //构造请求体
    Request.Builder builder = new Request.Builder().url(remoteUrl.toString()).delete(requestBody);
    Request okRequest = this.createOkRequest(builder, request);
    //发起请求
    return this.getRemoteResponse(okRequest, request);
    }

/**

  • 发起post请求,参数为json
  • @param request
  • @return
    */
    private OkResponseWrap post(HttpServletRequest request) {
    //获取请求路径
    String requestUrl = request.getRequestURI().toString();
    //获取请求体
    String jsonParams = HttpHelper.getBodyString(request);
    //构造请求体
    //StringBuffer remoteUrl = new StringBuffer(this.transmitProperties.getRemoteUrl() + requestUrl.replaceFirst(this.transmitProperties.getHostUrl(), “”));
    StringBuffer remoteUrl = requestUrl(requestUrl);
    RequestBody requestBody = RequestBody.create(MediaType.parse(“application/json;charset=ut-8”), jsonParams);
    Request.Builder builder = new Request.Builder().url(remoteUrl.toString()).post(requestBody);
    Request okRequest = this.createOkRequest(builder, request);
    //发起请求
    return this.getRemoteResponse(okRequest, request);
    }

/**

  • 发起get请求
  • @param request
  • @return
    */
    private OkResponseWrap get(HttpServletRequest request) {
    //获取请求路径
    String requestUrl = request.getRequestURI().toString();
String[] split = requestUrl.split("/");
System.out.println(split[1]);


//获取请求头
Enumeration<String> headerNames = request.getHeaderNames();
//获取请求参数
Map<String, String[]> queries = request.getParameterMap();
StringBuffer sb = this.buildRemoteUrlWithParam(requestUrl, queries);
//构建请求体
Request.Builder builder = new Request.Builder().url(sb.toString()).get();
Request okRequest = this.createOkRequest(builder, request);
return getRemoteResponse(okRequest, request);

}

/**

  • 根据请求域名前缀不一样,拼接不一样的情趣地址
  • @param requestUrl
  • @return
    */
    private StringBuffer requestUrl(String requestUrl) {
    StringBuffer remoteUrl = null;
    String[] split = requestUrl.split("/");
    String path = split[1];
if (path != null && path.equalsIgnoreCase("v1")) {
   remoteUrl = new StringBuffer(this.transmitProperties.getOmsJavaUrl() + requestUrl.replaceFirst(this.transmitProperties.getHostUrl(), ""));
} else {
   remoteUrl = new StringBuffer(this.transmitProperties.getRemoteUrl() + requestUrl.replaceFirst(this.transmitProperties.getHostUrl(), ""));
}
return remoteUrl;

}

private OkResponseWrap getRemoteResponse(Request request, HttpServletRequest servletRequest) {
OkResponseWrap okResponseWrap = new OkResponseWrap();
Response okResponse = null;
try {
//设置cookie
OkHttpClient build = okHttpClient.newBuilder().cookieJar(this.createCookieJar(servletRequest)).build();
//向remote服务器发起请求
okResponse = build.newCall(request).execute();
//封装okResponseWrap类
int code = okResponse.code();
String body = okResponse.body().string();
List cookieHeaders = okResponse.headers(“Set-Cookie”);
okResponseWrap.setCode(code);
okResponseWrap.setBody(body);
Map<String, List> headers = new ConcurrentHashMap<>();
if (!CollectionUtils.isEmpty(cookieHeaders)) {
headers.put(“Set-Cookie”, cookieHeaders);
okResponseWrap.setHeaders(headers);
}
} catch (IOException e) {
//此处添加日志
e.printStackTrace();
okResponseWrap.setCode(500);
okResponseWrap.setBody(“服务器异常,请联系管理员!”);
} finally {
if (okResponse != null) {
okResponse.close();
}
}
return okResponseWrap;
}

/**

  • 生成cookieJar(能够理解为cookie一个集合)

  • @param request

  • @return
    */
    private CookieJar createCookieJar(HttpServletRequest request) {
    return new CookieJar() {
    @Override
    public void saveFromResponse(HttpUrl httpUrl, List<okhttp3.Cookie> list) {

    }

    @Override
    public List<okhttp3.Cookie> loadForRequest(HttpUrl httpUrl) {
    List<okhttp3.Cookie> cookieList = new ArrayList<>();
    Cookie[] cookies = request.getCookies();
    okhttp3.Cookie.Builder cookieBuilder = new okhttp3.Cookie.Builder();
    Stream.of(cookies).forEach(cookie -> {
    //
    cookieList.add(cookieBuilder.domain(transmitProperties.getRemoteDomain()).name(cookie.getName()).value(cookie.getValue()).build());
    });
    return cookieList;
    }
    };
    }

/**

  • 生成OkRequest请求
  • @param builder
  • @param request
  • @return
    */
    private Request createOkRequest(Request.Builder builder, HttpServletRequest request) {
//********
Enumeration<String> headerNames = request.getHeaderNames();
//遍历请求头,添加到okRequest中
while (headerNames.hasMoreElements()) {
  String headerName = headerNames.nextElement();
  String header = request.getHeader(headerName);
  builder.addHeader(headerName, header);
}
return builder.build();

}

private StringBuffer buildRemoteUrlWithParam(String requestUrl, Map<String, String[]> queries) {
// StringBuffer sb = new StringBuffer(this.transmitProperties.getRemoteUrl() + requestUrl.replaceFirst(this.transmitProperties.getHostUrl(), “”));
StringBuffer sb = requestUrl(requestUrl);

if (queries != null && queries.keySet().size() > 0) {
  boolean firstFlag = true;
  Iterator<Map.Entry<String, String[]>> iterator = queries.entrySet().iterator();
  while (iterator.hasNext()) {
    Map.Entry<String, String[]> entry = iterator.next();
    if (firstFlag) {
      for (int i = 0; i < entry.getValue().length; i++) {
        if (firstFlag) {
          sb.append("?" + entry.getKey() + "=" + entry.getValue()[i]);
          firstFlag = false;
        } else {
          sb.append("&" + entry.getKey() + "=" + entry.getValue()[i]);
        }
      }
    }
  }
}
return sb;

}

}

拦截器

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

;import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**

  • 任意请求转发处理过滤器
    */
    @Component
    public class RequestTransmitFilter implements Filter {

/**

@Autowired
private OkHttpHelper okHttpHelper;

/**

  • springboot初始化bean的顺序为:listener -> filter -> servlet -> 普通bean
  • 因此没法在filter中注入普通的bean,只能经过init方法中手工进行bean注入
  • @param filterConfig
  • @throws ServletException
    */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    ServletContext servletContext = filterConfig.getServletContext();
    WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext);
    okHttpHelper = applicationContext.getBean(OkHttpHelper.class);
    }

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

/*chain.doFilter(request, response);
if(false){*/
/*response.setCharacterEncoding(this.filterConfig.getInitParameter("encoding"));
System.out.println("HttpRequestAndResponseFilterBefore");
chain.doFilter(request, response);*/

HttpServletRequest servletRequest = (HttpServletRequest) request;
HttpServletResponse servletResponse = (HttpServletResponse) response;
//设置响应头
servletResponse.setCharacterEncoding("UTF-8");
servletResponse.setContentType("application/json;charset=utf-8");
//发起请求,获取响应
OkResponseWrap okResponseWrap = this.okHttpHelper.execute((HttpServletRequest) request);
PrintWriter out = null;

try {
  out = servletResponse.getWriter();
  //设置响应
  if (!CollectionUtils.isEmpty(okResponseWrap.getHeaders())) {
    okResponseWrap.getHeaders().get("Set-Cookie").forEach(cookie -> {
      servletResponse.addHeader("Set-Cookie", cookie);
    });
  }
  servletResponse.setStatus(okResponseWrap.getCode());
  out.write(String.valueOf(okResponseWrap.getBody()));
  out.flush();
} catch (Exception e) {
  //服务器异常
  e.printStackTrace();
} finally {
  if (out != null) {
    out.close();
  }
}

/* }*/
}

@Override
public void destroy() {

} }