smiley-http-proxy-servlet做代理时遇到的问题,报错failed to respond

smiley-http-proxy-servlet做代理时遇到的问题,报错failed to respond

背景

被代理的第三方接口基本上是POST请求,同时要求请求的Content-Type为application/x- www-form-urlencoded。结果测试时只要请求体携带参数,就会报错failed to respond,不携带参数就完好无损,通过不断的debug,和百度,最终找到了问题原因所在。

源码分析

  • smiley-http-proxy-servlet的ProxyServlet就是一个servlet
  • 当前端请求代理地址时,首先经过各种FIlter,然后再调用该代理ProxyServlet的 service() 方法
  • 下面是service()方法重点部分
Object proxyRequest;
        if (servletRequest.getHeader("Content-Length") == null && servletRequest.getHeader("Transfer-Encoding") == null) {
            proxyRequest = new BasicHttpRequest(method, proxyRequestUri);
        } else {
            proxyRequest = this.newProxyRequestWithEntity(method, proxyRequestUri, servletRequest);
        }
  • 当然最终走的是newProxyRequestWithEntity方法,下面看看该方法源码
protected HttpRequest newProxyRequestWithEntity(String method, String proxyRequestUri, HttpServletRequest servletRequest) throws IOException {
        HttpEntityEnclosingRequest eProxyRequest = new BasicHttpEntityEnclosingRequest(method, proxyRequestUri);
        eProxyRequest.setEntity(new InputStreamEntity(servletRequest.getInputStream(), this.getContentLength(servletRequest)));
        return eProxyRequest;
    }
  • 这里看到了最终是通过getInputStream将请求的Stream流传给新的代理请求Request
  • 再调试的时候getInputStream一直拿不到数据,所以请求代理的时候报错failed to respond

问题原因

  • 在项目的Filter过滤器链中,通过request.getParameter()获取了某个参数,所以在后面想再通过request.getInputStream()就不能获取了

  • 那么为什么request.getInputStream()就不能获取了呢,这里就的说说request.getParameter()、request.getInputStream()和request.getReader()的区别了

request.getParameter()、request.getInputStream()和request.getReader()的区别

  • 如果Post请求体是application/x- www-form-urlencoded,或是form表单提交。可以通过request.getParameter()方法来获取请求参数值。但当请求体不是该类型时,需要通过request.getInputStream()或request.getReader()方法来获取请求参数值。
  • 当然请求体类型是application/x- www-form-urlencoded时也可以直接调用request.getInputStream()或request.getReader()方法来解析并获取请求参数,前提是还没调用request.getParameter()方法;
  • 此时当request.getInputStream()或request.getReader()获取到请求数据后,无法再调request.getParameter()获取请求数据;
  • 即对该类型的请求,三个方法互斥,只能调其中一个
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
smiley-http-proxy-servlet是一个基于Java代理服务器,可以用于转发请求并修改响应。要创建Proxy Servlet并修改cookie,您可以按照以下步骤进行: 1. 创建一个新的Java类并继承ProxyServlet类。 2. 重写doFilter方法,在方法中获取请求的cookie并进行修改,然后将请求转发给目标服务器。 3. 重写getProxyHost和getProxyPort方法,指定目标服务器的主机和端口。 4. 在web.xml文件中配置Servlet映射,使得请求能够正确地被代理Servlet处理。 下面是一个简单的示例代码,演示如何创建一个Proxy Servlet并修改cookie: ``` public class MyProxyServlet extends ProxyServlet { @Override protected void doFilter(HttpServletRequest servletRequest, HttpServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { // 获取请求的cookie Cookie[] cookies = servletRequest.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { if (cookie.getName().equals("myCookie")) { // 修改cookie cookie.setValue("newCookieValue"); servletResponse.addCookie(cookie); } } } // 转发请求给目标服务器 super.doFilter(servletRequest, servletResponse, filterChain); } @Override protected String getProxyHost(HttpServletRequest servletRequest) { // 指定目标服务器的主机 return "mytargetserver.com"; } @Override protected int getProxyPort(HttpServletRequest servletRequest) { // 指定目标服务器的端口 return 80; } } ``` 在web.xml文件中添加以下配置: ``` <servlet> <servlet-name>MyProxyServlet</servlet-name> <servlet-class>com.example.MyProxyServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>MyProxyServlet</servlet-name> <url-pattern>/proxy/*</url-pattern> </servlet-mapping> ``` 以上示例代码仅供参考,具体实现需要根据您的具体需求进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值