gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 10:12:38 25 4
gpt4 key购买 nike

我面临以下问题。我需要在 websphere(没有 Spring)上运行的 java EE 应用程序中创建一种方法来将请求代理到另一个位置并使用不记名 token 丰富 header 。

拿下面的例子

GET request: http://servicehost.com/proxy/targetapi/userresource



需要转发给

GET request: http://othertargethost.com/targetapi/userresource with Authorization: Bearer randomtoken



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

但是,现在我处于严格的 EE 环境中,根本不允许使用 Spring 。我还没有找到关于如何在纯 EE 上下文中设置或配置 netflix zuul 的任何好的文档或示例。

我还有哪些其他选择来解决这个问题?我在考虑以下问题
  • 在 **/proxy/* 上设置一个 Servlet 并创建一个过滤器来进行转发
  • 在互联网上搜索类似于 Zuul 的东西,并提供更好的文档以在 EE 中运行它
  • ...

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

    Jersey web service proxy对我来说不是解决方案,因为这是在特定端点和特定 http 方法上精确定位的

    GET request: http://servicehost.com/proxy/targetapi/userresource



    可能

    GET request: http://servicehost.com/proxy/targetapi/contractresource



    或者

    GET request: http://servicehost.com/proxy/specialapi/userresource



    它需要能够处理 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 "";
    }
    }
    不理想,但我没有看到其他出路

    关于java - 如何在 Java EE 应用程序中使用丰富的 header 将请求代理到另一个位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61252851/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com