2

I have a requirement to use Spring MVC to redirect to an external service using a POST with an object that is built.

From reading this previous question I understand that it is not possible to do so via Spring MVC redirect, so it is required to complete the POST request via a HTTP client in the Java code, which I can do via an example such as the one found here.

I need to be able to redirect the browser to the response of the POST request, but I am not sure how to do so using Spring MVC.

Controller

@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;

}

I can see that the target service is being hit by the POST request successfully, I need to read the output of the response as a return value from the MCV controller as it currently just returns a 404.

Community
  • 1
  • 1
Matt Brooks
  • 21
  • 1
  • 2

4 Answers4

1

You cannot redirect the browser to the response of the POST request. All you can do is send back the result of the call to the external URL. Or process the response in some way and then forward to some other page in your application which displays some information about the response.

e.g.

@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());
}
Alan Hay
  • 22,665
  • 4
  • 56
  • 110
1

This is how I did it

    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);
vsingh
  • 6,365
  • 3
  • 53
  • 57
0

Use sendRedirect instead of HttpClient, your controller method should look like below.

@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;
}
Avinash
  • 4,115
  • 2
  • 22
  • 41
  • I have included the HttpServletResponse and set the status and header values as suggested, however it does not redirect, still returning a 404. Do I need to change the method to return the response instead of HttpEntity? – Matt Brooks Jan 12 '17 at 16:51
0

If you're interested in a more involved solution you can leverage Zuul for that and have zuul manage the request forwarding. https://github.com/Netflix/zuul During the filter chain you can manipulate the request however you want.

bjoern
  • 1,009
  • 3
  • 15
  • 31