如何在JavaEE应用程序中使用丰富的头将请求代理到另一个位置

如何在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环境中设置或

我面临以下问题。我需要在websphere上运行的JavaEE应用程序(不带Spring)中创建一种方法,以将请求代理到另一个位置,并使用承载令牌丰富头部

以下面的例子为例

获取请求:

需要转发给

获取请求:带有授权:令牌

我在另一个应用程序中解决了这个问题,但这是一个使用Netflix Zuul和spring cloud starter Netflix Zuul的spring引导应用程序

然而现在我处于一个严格的EE环境中,根本不允许使用spring。我没有找到任何关于如何在纯EE环境中设置或配置netflix zuul的好文档或示例

我还需要其他哪些方法来解决这个问题?我在想以下几点

  • 在**/proxy/*上设置一个Servlet,并创建一个用于转发的筛选器
  • 在互联网上搜索类似于Zuul的东西,并提供更好的文档,以便在EE中运行它
我真的很感激任何能为我指明正确方向的事情

对我来说不是一个解决方案,因为这是针对特定端点和特定http方法的

获取请求:

可能是

获取请求:

获取请求:


它需要能够处理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