首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在java EE应用程序中使用丰富的标头将请求代理到另一个位置

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

Stack Overflow用户
提问于 2020-04-16 14:32:56
回答 1查看 437关注 0票数 2

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

以以下例子为例

GET请求:http://servicehost.com/proxy/targetapi/userresource

需要转寄给

GET请求:具有授权的http://othertargethost.com/targetapi/userresource:承载随机令牌

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

然而,现在我处于严格的EE上下文中,根本不允许弹簧。我还没有找到任何关于如何在纯EE上下文中设置或配置netflix的好文档或示例。

我还有什么办法可以解决这个问题呢?我在想以下几点

forwarding

  • Search

  • 在**//*上安装了一个Servlet,并创建了一个过滤器,该过滤器将为类似Zuul的东西创建一个过滤器,该过滤器具有更好的文档,可以在EE
  • ...

中运行

我真的很感激任何能指引我走向正确方向的东西。

对于我来说,Jersey web service proxy不是一种解决方案,因为它在特定的端点上和特定的http方法中都有定位。

GET请求:http://servicehost.com/proxy/targetapi/userresource

可能是

GET请求:http://servicehost.com/proxy/targetapi/contractresource

GET请求:http://servicehost.com/proxy/specialapi/userresource

它需要能够处理GET、POST、PUT和DELETE。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-08-07 07:20:05

我无法在EE中使用Zuul,所以我只有一个追索权,那就是编写我自己的servlet

代码语言:javascript
复制
@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 "";
    }
}

不太理想,但我没看到别的出路

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61252851

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档