首页 > 解决方案 > 关于HTTP-Proxy-Servlet如何解决目标路径为动态代理时目标服务器的静态资源加载问题

问题描述

我有一个根据请求路径中的参数动态生成的需求,幸好我做到了。但是现在的问题是当我的拦截规则:'/proxy/*', target_url :'https://www.example.com/',我可以正常访问首页,但是加载的相对路径的静态资源主页,比如js,css,img都是404,因为他们发起的这些资源请求没有携带'/proxy/',所以不能被我的服务器拦截和代理。我真的很烦,谁能帮帮我?

        <dependency>
            <groupId>org.mitre.dsmiley.httpproxy</groupId>
            <artifactId>smiley-http-proxy-servlet</artifactId>
            <version>1.12</version>
        </dependency>
@Configuration
public class ProxyServletConfiguration {

    private final static String SERVLET_URL = "/proxy/*";

    @Bean
    public ServletRegistrationBean<VNCProxyServlet> servletServletRegistrationBean() {
        ServletRegistrationBean<VNCProxyServlet> servletRegistrationBean = new ServletRegistrationBean<>(new VNCProxyServlet(), SERVLET_URL);
        Map<String, String> params = ImmutableMap.of(
                "targetUri", "null",
                ProxyServlet.P_LOG, "true",
                ProxyServlet.P_PRESERVEHOST,"true",
                ProxyServlet.P_PRESERVECOOKIES,"true");
        servletRegistrationBean.setInitParameters(params);
        return servletRegistrationBean;
    }

}

我重写了服务方法

@Override
    protected void service(HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws ServletException, IOException {

        if (StringUtils.isEmpty(TARGET_URL)) {
            throw new ServletException("TARGET_URI is required");
        }

        // Set Url
        if (servletRequest.getAttribute(ATTR_TARGET_URI) == null) {
            servletRequest.setAttribute(ATTR_TARGET_URI, TARGET_URL);
        }

        // Set Host
        if (servletRequest.getAttribute(ATTR_TARGET_HOST) == null) {
            URL trueUrl = URLUtil.url(TARGET_URL);
            servletRequest.setAttribute(ATTR_TARGET_HOST, new HttpHost(trueUrl.getHost(), trueUrl.getPort(), trueUrl.getProtocol()));
        }

        String method = servletRequest.getMethod();
     
        String proxyRequestUri = this.rewriteUrlFromRequest(servletRequest);

        HttpRequest proxyRequest;
        if (servletRequest.getHeader(HttpHeaders.CONTENT_LENGTH) != null ||
                servletRequest.getHeader(HttpHeaders.TRANSFER_ENCODING) != null) {
            proxyRequest = new BasicHttpRequest(method, proxyRequestUri);
        } else {
            proxyRequest = this.newProxyRequestWithEntity(method, proxyRequestUri, servletRequest);
        }

        this.copyRequestHeaders(servletRequest, proxyRequest);
        setXForwardedForHeader(servletRequest, proxyRequest);
        HttpResponse proxyResponse = null;

        try {
            // Execute the request
            proxyResponse = this.doExecute(servletRequest, servletResponse, proxyRequest);

            // Process the response
            int statusCode = proxyResponse.getStatusLine().getStatusCode();

            // "reason phrase" is deprecated but it's the only way to pass
            servletResponse.setStatus(statusCode, proxyResponse.getStatusLine().getReasonPhrase());

            // copying response headers to make sure SESSIONID or other Cookie which comes from remote server
            // will be saved in client when the proxied url was redirected to another one.
            this.copyResponseHeaders(proxyResponse, servletRequest, servletResponse);

            if (statusCode == HttpServletResponse.SC_NOT_MODIFIED) {
                servletResponse.setIntHeader(HttpHeaders.CONTENT_LENGTH, 0);
            } else {
                // Send the content to the client
                copyResponseEntity(proxyResponse, servletResponse, proxyRequest, servletRequest);
            }


        } catch (Exception e) {
            this.handleRequestException(proxyRequest, proxyResponse, e);
        } finally {
            if (proxyResponse != null) {
                EntityUtils.consumeQuietly(proxyResponse.getEntity());
            }

        }
    }

就像我访问'localhost:8080/proxy/',然后我得到代理网址'https://www.example.com',但静态资源加载在'https://www.example.com'都是404,因为是'https://www.example.com'上加载的相对路径,比如'static/img/xxx.img'。如果是绝对路径:'https://www .xxxx.com/xxx.img' 没问题。我应该怎么办?这个方案不可行吗?

这是两张图片:

我可以访问代理主页

我无法访问代理主页的静态资源

标签: java

解决方案


推荐阅读