Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

spring mvc rest service redirect / forward / proxy

I have build a web application using spring mvc framework to publish REST services. For example:

@Controller @RequestMapping("/movie") public class MovieController {  @RequestMapping(value = "/{id}", method = RequestMethod.GET) public @ResponseBody Movie getMovie(@PathVariable String id, @RequestBody user) {      return dataProvider.getMovieById(user,id);  } 

Now I need to deploy my application but I have the following problem: The clients do not have direct access to the computer on which the application resides (There is a firewall). Therefore I need a redirection layer on a proxy machine (accessible by the clients) which calls the actual rest service.

I tried making a new call using RestTemplate: For Example:

@Controller @RequestMapping("/movieProxy") public class MovieProxyController {      private String address= "http://xxx.xxx.xxx.xxx:xx/MyApp";      @RequestMapping(value = "/{id}", method = RequestMethod.GET)     public @ResponseBody Movie getMovie(@PathVariable String id,@RequestBody user,final HttpServletResponse response,final HttpServletRequest request) {          HttpHeaders headers = new HttpHeaders();         headers.setContentType(MediaType.APPLICATION_JSON);         RestTemplate restTemplate = new RestTemplate();         return restTemplate.exchange( address+ request.getPathInfo(), request.getMethod(), new HttpEntity<T>(user, headers), Movie.class);  } 

This is ok but I need to rewrite each method in the controller to use the resttemplate. Also, this causes redundant serialization/deserialization on the proxy machine.

I tried writing a generic function using restemplate, but it did not work out:

@Controller @RequestMapping("/movieProxy") public class MovieProxyController {      private String address= "http://xxx.xxx.xxx.xxx:xx/MyApp";      @RequestMapping(value = "/**")     public ? redirect(final HttpServletResponse response,final HttpServletRequest request) {                 HttpHeaders headers = new HttpHeaders();         headers.setContentType(MediaType.APPLICATION_JSON);         RestTemplate restTemplate = new RestTemplate();         return restTemplate.exchange( address+ request.getPathInfo(), request.getMethod(), ? , ?);  } 

I could not find a method of resttemplate which works with request and response objects.

I also tried spring redirect and forward. But redirect does not change the request's client ip address so i think it is useless in this case. I could not forward to another URL either.

Is there a more appropriate way to achieve this? Thanks in advance.

like image 676
nilgun Avatar asked Feb 06 '13 09:02

nilgun


People also ask

What is the difference between forward and redirect in Spring MVC?

redirect will respond with a 302 and the new URL in the Location header; the browser/client will then make another request to the new URL. forward happens entirely on a server side. The Servlet container forwards the same request to the target URL; the URL won't change in the browser.

How do I forward a Spring MVC request?

A request can be basically processed in three ways: a) resolved by Spring in a controller action, b) forwarded to a different controller action, c) redirected to client to fetch another URL. Forward: performed internally by Spring. the browser is completely unaware of forward, so its original URL remains intact.

How use redirect attribute in Spring MVC?

You can use RedirectAttributes to store flash attributes and they will be automatically propagated to the "output" FlashMap of the current request. A RedirectAttributes model is empty when the method is called and is never used unless the method returns a redirect view name or a RedirectView.

How do I redirect a URL in spring boot RestController?

@RestController public class RedirectController { @RequestMapping("/redirect") public String redirect() { return "redirect:/other/controller/"; } } and if we will try to access that url curl localhost:8080/redirect we will simply see redirect:/other/controller/ string as result.


1 Answers

You can mirror/proxy all requests with this:

private String server = "localhost"; private int port = 8080;  @RequestMapping("/**") @ResponseBody public String mirrorRest(@RequestBody String body, HttpMethod method, HttpServletRequest request) throws URISyntaxException {     URI uri = new URI("http", null, server, port, request.getRequestURI(), request.getQueryString(), null);      ResponseEntity<String> responseEntity =         restTemplate.exchange(uri, method, new HttpEntity<String>(body), String.class);      return responseEntity.getBody(); } 

This will not mirror any headers.

like image 83
derkoe Avatar answered Sep 28 '22 03:09

derkoe