0

The idea is, I receive POST request with some parameters already included e.g., car name and price

I need to add some parameter that client should not know about (for example, car's VIN, which client should not know before he makes a purchase)

Then, with parameter added, I want to forward this request to another site, which all data that I have passed (car name, price, vin)

Is there a way to implement on Controller level, not filters?

@RequestMapping(value = "/abc")
public void ABC(final HttpServletRequest request) {
     request.getParameterMap().put("vin", VIN_CODE); // cannot do that because it is read-only
     return "forward:https://completelyanothersite.com";
}

EDIT: Based on comments, forwarding is not solution, instead redirecting is the one

Aleksandr
  • 3
  • 3
  • You can copy input parameters, modify them and then send the modified parameter to other service , see this : https://stackoverflow.com/questions/3324717/sending-http-post-request-in-java – Adil Shaikh Mar 08 '19 at 16:03
  • 1
    `forward:` is meant for forwarding to another controller in the same server. What you should be doing is creating a new request (e.g. with RestTemplate), copying across the parameters you need and setting the new ones. Don't blindly copy across all parameters from the first call otherwise you open up the second private server to possible URL/parameter manipulation attacks. – Andy Brown Mar 08 '19 at 16:05
  • @MohammadAdil sorry, I forgot to mention, but user has to receive response, but as far as I see the answer you are referencing fits in case we handle response on server side – Aleksandr Mar 08 '19 at 16:22
  • It's nearly always a mistake to pass in `HttpServletRequest`, since one of the big benefits of Spring is that it handles parsing and resolution for you. At a minimum, use `@RequestParams Map params`. (And you can always just use the `HashMap` copy constructor.) Note that your "forward" approach still won't work for the reasons described above. – chrylis -cautiouslyoptimistic- Mar 08 '19 at 16:25
  • I have done some testing based on answers, and I find that chrylis' is one that is the solution for my problem @chrylis can you post it as an answer so I'd mark it? – Aleksandr Mar 08 '19 at 17:03

3 Answers3

1

The little-less dirty (that I know of) way to do that is by extending the request:

public class WrappedHttpServletRequestWrapper extends HttpServletRequestWrapper
{
    private final Map<String, String[]> modifiableParameters;
    private Map<String, String[]> allParameters = null;


    public WrappedHttpServletRequestWrapper (final HttpServletRequest request, 
                                                    final Map<String, String[]> additionalParams)
    {
        super(request);
        modifiableParameters = new TreeMap<String, String[]>();
        modifiableParameters.putAll(additionalParams);
    }

    @Override
    public Map<String, String[]> getParameterMap()
    {
        // allParameters contains old parameters + the ones you added 
        return Collections.unmodifiableMap(allParameters);
    }
    //... other overriden methods
}

And use that one to add your parameters. Here is the reference.

And here is how you will use it:

Map<String, String[]> extraParams = new TreeMap<String, String[]>()
HttpServletRequest wrappedRequest = new WrappedHttpServletRequestWrapper(request, extraParams);
request.getRequestDispatcher("url").forward(wrappedRequest, response);
NiVeR
  • 9,644
  • 4
  • 30
  • 35
0

You can send a redirect to another website, but can not forward it to another website. Use resp.sendRedirect(url);

Refer this thread Difference between JSP forward and redirect

Sheel Prabhakar
  • 409
  • 2
  • 6
0

Spring MVC provides a powerful set of features to automatically parse and map HTTP requests and responses for you so you don't have to do it manually and can focus on business logic. In this case, Spring can hand you a map of all request parameters like this:

@PostMapping("/abc")
public void abc(@RequestParam Map<String, String> params) { ... }

(or, if you need multi-valued parameters, you can use MultiValueMap, which is slightly more standards-correct but a bit more complicated to work with). You get a private copy of the map, which in practice is a mutable LinkedHashMap, but if you're ever unsure you can always just say new HashMap<>(params).

Once you have this params map, you can add whatever additional values you want to it, but unless you can send someone to another controller inside your own application you'll need to either generate a redirect: response (in which case the VIN will be visible in the URL) or make a REST request yourself to the other service and then relay the information back to the user.

chrylis -cautiouslyoptimistic-
  • 75,269
  • 21
  • 115
  • 152