在近期的项目开发过程,因客户方为自封装SpringBoot微服务模式的框架,且通信模式为Grpc,导致内部封装后的 SpringBoot 原始很多特性都不支持(这个很坑,没办法(客户嘛,甲方嘛)每一家都想要搞自己的标准),为了能够很好的支持客户已有的技术标准我们进行整体的改造,将框架的底层算是釜底抽薪改了个彻底。 在此感谢团队内部各位小伙伴的辛苦付出。 在改造的期间碰到的一些问题,我这里也会记录一下主要是为了防止后续有人还会继续踩坑,也为后续有这种需求的人提前做一些参考资料 下面代码片段为,springCloud zuul 拦截参数,修改后,并转发至客户方的API 统一网关,通过zuul本人的路由机制,将相同的url 直接转发至客户方的路由管控中心,进行实际地址的请求
package com.xxx.filter.forward;
import com.alibaba.fastjson.JSONObject;
import com.xxx.common.LoginConstant;
import com.xxx.common.WebProperties;
import com.xxx.utils.StringUtils;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.http.HttpServletRequestWrapper;
import com.netflix.zuul.http.ServletInputStreamWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import.org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;
import org.springframework.util.StreamUtils;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import static com.netflix.zuul.context.RequestContext.getCurrentContext;
/**
* 请求参数拼接
* 参数拼接后转发
*/
@Slf4j
@Component
public class RequestForwardPreFilter extends ZuulFilter {
@Autowired
WebProperties webProperties;
/**
* 修改请求参数
*
* @return
*/
@Override
public Object run() {
//未开启直接转发,微服务中将接收不到UserCode相关的用户信息
if (!webProperties.isEnableForwad()) {
return null;
} else {
RequestContext ctx = getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String body = "";
try {
InputStream stream = request.getInputStream();
body = StreamUtils.copyToString(stream, Charset.forName("UTF-8"));
JSONObject object = JSONObject.parseObject(body);
String userInfo = this.getUserInfo(request);
object.put(LoginConstant.LOGIN_KEY, userInfo);
body = object.toString();
//转发参数重置
final byte[] reqBodyBytes = body.getBytes();
ctx.setRequest(new HttpServletRequestWrapper(request) {
@Override
public ServletInputStream getInputStream() throws IOException {
return new ServletInputStreamWrapper(reqBodyBytes);
}
@Override
public int getContentLength() {
return reqBodyBytes.length;
}
@Override
public long getContentLengthLong() {
return reqBodyBytes.length;
}
});
} catch (IOException e) {
log.error("",e.getMessage());
}
}
return null;
}
/**
* 组织客户端用户信息
*
* @param request
* @return
*/
private String getUserInfo(HttpServletRequest request) {
String remoteAddr = StringUtils.getRemoteAddr(request);
String proxyName = request.getHeader(LoginConstant.LOGIN_AGENT);
String userInfo = (String) request.getSession().getAttribute(LoginConstant.LOGIN_KEY);
JSONObject object = JSONObject.parseObject(userInfo);
object.put("remoteAddr", remoteAddr);
object.put("proxyName", proxyName);
return object.toJSONString();
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public int filterOrder() {
return 1;
}
@Override
public String filterType() {
return FilterConstants.ROUTE_TYPE;
}
}
注意FilterType类型需要定义为 ROUTE_TYPE 过程类型,否则将不会生效。
注意:本文归作者所有,未经作者允许,不得转载