目的:写一个外壳,把用户请求转发到不一样的微服务中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
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;
}网络
/**
/**
/**
请求回调
/**
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.*;
import java.nio.charset.Charset;
public class HttpHelper {
/**
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;
/**
/**
/**
/**
/**
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);
}
/**
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;
}
};
}
/**
//******** 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;
/**
/**
@Autowired
private OkHttpHelper okHttpHelper;
/**
@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() {
} }