【问题标题】:Spring MVC Redirect with Response from HTTP POST带有来自 HTTP POST 的响应的 Spring MVC 重定向
【发布时间】:2017-03-15 22:02:17
【问题描述】:

我需要使用 Spring MVC 使用带有已构建对象的 POST 重定向到外部服务。

通过阅读this previous question,我了解到无法通过 Spring MVC 重定向执行此操作,因此需要通过 Java 代码中的 HTTP 客户端完成 POST 请求,我可以通过示例来完成,例如找到here的那个。

我需要能够将浏览器重定向到 POST 请求的响应,但我不确定如何使用 Spring MVC 来做到这一点。

控制器

@RequestMapping(method = RequestMethod.GET, value = "/handoff")
public HttpEntity dispatch(HttpServletRequest request,
  @RequestParam(value = "referralURL", required = false) String referralUrl) {

    String redirectURL = "http://desinationURL.com/post";

    HttpClientHelper httpHelper = new HttpClientHelper();
    HttpEntity entity = httpHelper.httpClientPost(redirectURL, null);

    // Redirect
    return entity;
}

HttpClientHelper.java

public HttpEntity httpClientPost(String url, List<NameValuePair> params) throws ClientProtocolException, IOException {

    HttpClient httpclient = HttpClients.createDefault();
    HttpPost httppost = new HttpPost(url);

    // Request parameters and other properties.
    if (params != null) {
        httppost.setEntity(new UrlEncodedFormEntity(params, Constants.UTF_8_ENCODING));
    }

    // Execute and get the response.
    HttpResponse response = httpclient.execute(httppost);
    HttpEntity entity = response.getEntity();

    return entity;

}

我可以看到目标服务被 POST 请求成功命中,我需要从 MCV 控制器读取响应的输出作为返回值,因为它当前只返回 404。

【问题讨论】:

    标签: java spring spring-mvc redirect apache-httpclient-4.x


    【解决方案1】:

    您不能重定向浏览器响应 POST 请求。您所能做的就是将调用结果发送回外部 URL。或者以某种方式处理响应,然后转发到应用程序中显示有关响应的一些信息的其他页面。

    例如

    @RequestMapping(method = RequestMethod.GET, value = "/handoff")
    public void dispatch(HttpServletRequest request,
      @RequestParam(value = "referralURL", required = false) String referralUrl, HttpServletResponse response) {
    
        String redirectURL = "http://desinationURL.com/post";
    
        HttpClientHelper httpHelper = new HttpClientHelper();
        HttpEntity entity = httpHelper.httpClientPost(redirectURL, null);
    
        //streams the raw response
        entity.writeTo(response.getOutputSStream());
    }
    

    【讨论】:

      【解决方案2】:

      我就是这样做的

          CloseableHttpClient httpClient = HttpClients.custom()
                  .setRedirectStrategy(new LaxRedirectStrategy())
                  .build();
      
          //this reads the input stream from POST
          ServletInputStream str = request.getInputStream();
      
          HttpPost httpPost = new HttpPost(path);
          HttpEntity postParams = new InputStreamEntity(str);
          httpPost.setEntity(postParams);
      
          HttpResponse httpResponse = null ;
          int responseCode = -1 ;
          StringBuffer response  = new StringBuffer();
      
          try {
      
              httpResponse = httpClient.execute(httpPost);
      
              responseCode = httpResponse.getStatusLine().getStatusCode();
              logger.info("POST Response Status::  {} for file {}  ", responseCode, request.getQueryString());
      
              //return httpResponse ;
              BufferedReader reader = new BufferedReader(new InputStreamReader(
                      httpResponse.getEntity().getContent()));
      
              String inputLine;
              while ((inputLine = reader.readLine()) != null) {
                  response.append(inputLine);
              }
              reader.close();
      
              logger.info(" Final Complete Response {}  " + response.toString());
              httpClient.close();
      
          } catch (Exception e) {
      
              logger.error("Exception ", e);
      
          } finally {
      
              IOUtils.closeQuietly(httpClient);
      
          }
      
          // Return the response back to caller
          return  new ResponseEntity<String>(response.toString(), HttpStatus.ACCEPTED);
      

      【讨论】:

        【解决方案3】:

        使用 sendRedirect 而不是 HttpClient,您的控制器方法应如下所示。

        @RequestMapping(method = RequestMethod.GET, value = "/handoff")
        public HttpEntity dispatch(HttpServletRequest request, HttpServletResponse response,
          @RequestParam(value = "referralURL", required = false) String referralUrl) {
        
            String redirectURL = "http://desinationURL.com/post";
        
            response.setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT);
            response.setHeader("Location", redirectURL);
        
            // Redirect
            return entity;
        }
        

        【讨论】:

        • 我已经包含了 HttpServletResponse 并按照建议设置了状态和标头值,但是它没有重定向,仍然返回 404。我是否需要更改方法以返回响应而不是 HttpEntity?
        【解决方案4】:

        如果您对更复杂的解决方案感兴趣,您可以利用 Zuul 并让 zuul 管理请求转发。 https://github.com/Netflix/zuul 在过滤器链中,您可以随心所欲地操纵请求。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-07-23
          相关资源
          最近更新 更多