如何在JavaEE应用程序中使用丰富的头将请求代理到另一个位置
我面临以下问题。我需要在websphere上运行的JavaEE应用程序(不带Spring)中创建一种方法,以将请求代理到另一个位置,并使用承载令牌丰富头部 以下面的例子为例 获取请求: 需要转发给 获取请求:带有授权:令牌 我在另一个应用程序中解决了这个问题,但这是一个使用Netflix Zuul和spring cloud starter Netflix Zuul的spring引导应用程序 然而现在我处于一个严格的EE环境中,根本不允许使用spring。我没有找到任何关于如何在纯EE环境中设置或配置netflix zuul的好文档或示例 我还需要其他哪些方法来解决这个问题?我在想以下几点如何在JavaEE应用程序中使用丰富的头将请求代理到另一个位置,java,java-ee-6,netflix-zuul,Java,Java Ee 6,Netflix Zuul,我面临以下问题。我需要在websphere上运行的JavaEE应用程序(不带Spring)中创建一种方法,以将请求代理到另一个位置,并使用承载令牌丰富头部 以下面的例子为例 获取请求: 需要转发给 获取请求:带有授权:令牌 我在另一个应用程序中解决了这个问题,但这是一个使用Netflix Zuul和spring cloud starter Netflix Zuul的spring引导应用程序 然而现在我处于一个严格的EE环境中,根本不允许使用spring。我没有找到任何关于如何在纯EE环境中设置或
- 在**/proxy/*上设置一个Servlet,并创建一个用于转发的筛选器
- 在互联网上搜索类似于Zuul的东西,并提供更好的文档,以便在EE中运行它
它需要能够处理GET、POST、PUT和DELETE我不能在EE中使用Zuul,所以我只有一个办法,那就是编写自己的servlet
@WebServlet(name = "ProxyServlet", urlPatterns = {"/proxy/*"})
public class ProxyServlet extends HttpServlet {
public static final String SESSION_ID_PARAM = "delijnSessionId";
@Inject
private Logger logger;
@Inject
private ProxyProperties proxyProperties;
@Inject
private SecurityService securityService;
@Inject
private ProxyHttpClientFactory proxyHttpClientFactory;
@Inject
private StreamUtils streamUtils;
@Override
protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
proxy(httpServletRequest, httpServletResponse);
}
@Override
protected void doPost(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
proxy(httpServletRequest, httpServletResponse);
}
@Override
protected void doPut(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
proxy(httpServletRequest, httpServletResponse);
}
@Override
protected void doDelete(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException {
proxy(httpServletRequest, httpServletResponse);
}
private void proxy(HttpServletRequest request, HttpServletResponse response) {
try {
String requestUrl = request.getRequestURI();
String method = request.getMethod();
String sessionId = getSessionId(request);
String protocol = proxyProperties.getProperty(ProxyProperties.PROXY_PROTOCOL);
String server = proxyProperties.getProperty(ProxyProperties.PROXY_SERVER);
String port = proxyProperties.getProperty(ProxyProperties.PROXY_PORT);
String newPath = requestUrl.replaceFirst(".*/proxy", "");
URI uri = new URI(protocol, null, server, Integer.parseInt(port), newPath, request.getQueryString(), null);
ProxyHttpMethod proxyRequest = new ProxyHttpMethod(method);
proxyRequest.setURI(uri);
copyBodyFromRequest(request, method, proxyRequest);
copyHeadersFromRequest(request, proxyRequest);
enrichWithAccessToken(proxyRequest, sessionId);
try (CloseableHttpClient client = proxyHttpClientFactory.produce()) {
logger.info("uri [{}]", uri);
logger.info("method [{}]", method);
execute(client, proxyRequest, response);
} catch (IOException e) {
throw new TechnicalException(e);
}
} catch (URISyntaxException | IOException e) {
throw new TechnicalException(e);
}
}
private void execute(CloseableHttpClient client, ProxyHttpMethod proxyHttpMethod, HttpServletResponse response) {
try (CloseableHttpResponse proxyResponse = client.execute(proxyHttpMethod)) {
int statusCode = proxyResponse.getStatusLine().getStatusCode();
if (statusCode >= 200 || statusCode < 300) {
response.setStatus(statusCode);
HttpEntity entity = proxyResponse.getEntity();
if(entity != null){
String result = streamUtils.getStringFromStream(entity.getContent());
logger.trace("result [" + result + "]");
response.getWriter().write(result);
response.getWriter().flush();
response.getWriter().close();
}
} else {
throw new TechnicalException("[" + statusCode + "] Error retrieving access token");
}
} catch (IOException e) {
throw new TechnicalException(e);
}
}
private void enrichWithAccessToken(ProxyHttpMethod proxyRequest, String sessionId) {
Optional<TokenDto> token = securityService.findTokenBySessionIdWithRefresh(sessionId);
if (token.isPresent()) {
String accessToken = token.get().getAccessToken();
logger.trace(String.format("Enriching headers with: Authorization Bearer %s", accessToken));
proxyRequest.setHeader("Authorization", "Bearer " + accessToken);
} else {
logger.info(String.format("No token found in repository for sessionId [%s]", sessionId));
throw new RuntimeException("No token found in repository");
}
}
private void copyBodyFromRequest(HttpServletRequest request, String method, ProxyHttpMethod proxyRequest) throws IOException {
if ("POST".equalsIgnoreCase(method) || "PUT".equalsIgnoreCase(method)) {
String body = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
StringEntity entity = new StringEntity(body);
proxyRequest.setEntity(entity);
}
}
private void copyHeadersFromRequest(HttpServletRequest request, ProxyHttpMethod proxyRequest) {
Enumeration<String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = headerNames.nextElement();
if (!"host".equalsIgnoreCase(headerName) && !"Content-Length".equalsIgnoreCase(headerName)) {
proxyRequest.setHeader(headerName, request.getHeader(headerName));
}
}
}
private String getSessionId(HttpServletRequest request) {
String sessionId = "";
Cookie[] cookies = request.getCookies();
if(cookies != null){
for (Cookie cookie : cookies) {
if (SESSION_ID_PARAM.equals(cookie.getName())) {
sessionId = cookie.getValue();
}
}
return sessionId;
}
return "";
}
}
@WebServlet(name=“ProxyServlet”,urlPatterns={”/proxy/*“})
公共类ProxyServlet扩展了HttpServlet{
public static final String SESSION_ID_PARAM=“delijnSessionId”;
@注入
私人记录器;
@注入
私有代理属性代理属性;
@注入
私人保安服务;
@注入
私有ProxyHttpClientFactory ProxyHttpClientFactory;
@注入
私人StreamUtils StreamUtils;
@凌驾
受保护的void doGet(HttpServletRequest HttpServletRequest,HttpServletResponse HttpServletResponse)抛出ServletException,IOException{
代理(httpServletRequest、httpServletResponse);
}
@凌驾
受保护的void doPost(HttpServletRequest HttpServletRequest,HttpServletResponse HttpServletResponse)引发ServletException,IOException{
代理(httpServletRequest、httpServletResponse);
}
@凌驾
受保护的void doPut(HttpServletRequest HttpServletRequest,HttpServletResponse HttpServletResponse)抛出ServletException,IOException{
代理(httpServletRequest、httpServletResponse);
}
@凌驾
受保护的void doDelete(HttpServletRequest HttpServletRequest,HttpServletResponse HttpServletResponse)抛出ServletException,IOException{
代理(httpServletRequest、httpServletResponse);
}
私有void代理(HttpServletRequest请求、HttpServletResponse响应){
试一试{
String requestUrl=request.getRequestURI();
String方法=request.getMethod();
字符串sessionId=getSessionId(请求);
字符串协议=proxyProperties.getProperty(proxyProperties.PROXY\u协议);
String server=proxyProperties.getProperty(proxyperties.PROXY\u服务器);
字符串端口=proxyProperties.getProperty(proxyProperties.PROXY\u端口);
字符串newPath=requestUrl.replaceFirst(“.*/proxy”,”);
URI=新URI(协议,null,服务器,Integer.parseInt(端口),newPath,request.getQueryString(),null);
ProxyHttpMethod proxyRequest=新的ProxyHttpMethod(方法);
setURI(uri);
copyBodyFromRequest(请求、方法、代理请求);
copyHeadersFromRequest(请求,代理请求);
enrichWithAccessToken(proxyRequest,sessionId);
try(CloseableHttpClient=proxyHttpClientFactory.product()){
info(“uri[{}]”,uri);
info(“method[{}]”,method);
执行(客户端、代理请求、响应);
}捕获(IOE异常){
抛出新概念(e);
}
}捕获(URISyntaxException | IOException e){
抛出新概念(e);
}
}
私有void执行(CloseableHttpClient客户端,ProxyHttpMethod ProxyHttpMethod,HttpServletResponse){
try(CloseableHttpResponse proxyResponse=client.execute(proxyHttpMethod)){
int statusCode=proxyResponse.getStatusLine().getStatusCode();
如果(状态代码>=200 | |状态代码<300){
响应。设置状态(状态代码);
HttpEntity=proxyResponse.getEntity();
如果(实体!=null){
字符串结果=streamUtils.getStringFromStream(entity.getContent());
logger.trace(“结果[“+结果+”]”);
response.getWriter().write(结果);
response.getWriter().flush();
response.getWriter().close();
}
}否则{
抛出新的TechnicalException(“[”+statusCode+“]检索访问令牌时出错”);
}
}捕获(IOE异常){
抛出新概念(e);
}
}
私有void enrichWithAccessToken(ProxyHttpMethod proxyRequest,字符串sessionId){
可选令牌=securityService.findTokenBySessionIdWithRefresh(sessionId);
if(token.isPresent()){
字符串accessToken=token.get().getAccessToken();
trace(String.format(“使用授权承载%s、accessToken来充实标头”);
setHeader(“授权”、“承载人”+accessToken);
}否则{
logger.info(String.format(“在sessionId[%s]的存储库中找不到令牌”,sessionId));
抛出新的RuntimeException(“No t