public class ProxyExchange<T> extends Object
@RequestMapping
argument type that can proxy the request to a backend.
Spring will inject one of these into your MVC handler method, and you get return a
ResponseEntity
that you get from one of the HTTP methods get()
,
post()
, put()
, patch()
, delete()
etc. Example:
@GetMapping("/proxy/{id}") public ResponseEntity<?> proxy(@PathVariable Integer id, ProxyExchange<?> proxy) throws Exception { return proxy.uri("http://localhost:9000/foos/" + id).get(); }
By default the incoming request body and headers are sent intact to the downstream
service (with the exception of "sensitive" headers). To manipulate the downstream
request there are "builder" style methods in ProxyExchange
, but only the
uri(String)
is mandatory. You can change the sensitive headers by calling the
sensitive(String...)
method (Authorization and Cookie are sensitive by
default).
The type parameter T
in ProxyExchange<T>
is the type of
the response body, so it comes out in the ResponseEntity
that you return from
your @RequestMapping
. If you don't care about the type of the request and
response body (e.g. if it's just a passthru) then use a wildcard, or
byte[]
or Object
. Use a concrete type if you want to
transform or manipulate the response, or if you want to assert that it is convertible
to the type you declare.
To manipulate the response use the overloaded HTTP methods with a Function
argument and pass in code to transform the response. E.g.
@PostMapping("/proxy") public ResponseEntity<Foo> proxy(ProxyExchange<Foo> proxy) throws Exception { return proxy.uri("http://localhost:9000/foos/") // .post(response -> ResponseEntity.status(response.getStatusCode()) // .headers(response.getHeaders()) // .header("X-Custom", "MyCustomHeader") // .body(response.getBody()) // ); }
The full machinery of Spring message converters
is applied
to the incoming request and response and also to the backend request. If you need
additional converters then they need to be added upstream in the MVC configuration and
also to the RestTemplate
that is used in the backend calls (see the
constructor
for details).
As well as the HTTP methods for a backend call you can also use
forward(String)
for a local in-container dispatch.
Modifier and Type | Class and Description |
---|---|
protected static class |
ProxyExchange.BodyGrabber |
protected static class |
ProxyExchange.BodySender |
Modifier and Type | Field and Description |
---|---|
static Set<String> |
DEFAULT_SENSITIVE
Contains headers that are considered case-sensitive by default.
|
Constructor and Description |
---|
ProxyExchange(org.springframework.web.client.RestTemplate rest,
org.springframework.web.context.request.NativeWebRequest webRequest,
org.springframework.web.method.support.ModelAndViewContainer mavContainer,
org.springframework.web.bind.support.WebDataBinderFactory binderFactory,
Type type) |
Modifier and Type | Method and Description |
---|---|
ProxyExchange<T> |
body(Object body)
|
org.springframework.http.ResponseEntity<T> |
delete() |
<S> org.springframework.http.ResponseEntity<S> |
delete(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter) |
void |
forward(String path) |
org.springframework.http.ResponseEntity<T> |
get() |
<S> org.springframework.http.ResponseEntity<S> |
get(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter) |
org.springframework.http.ResponseEntity<T> |
head() |
<S> org.springframework.http.ResponseEntity<S> |
head(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter) |
ProxyExchange<T> |
header(String name,
String... value)
Sets a header for the downstream call.
|
ProxyExchange<T> |
headers(org.springframework.http.HttpHeaders headers)
Additional headers, or overrides of the incoming ones, to be used in the downstream
call.
|
org.springframework.http.ResponseEntity<T> |
options() |
<S> org.springframework.http.ResponseEntity<S> |
options(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter) |
org.springframework.http.ResponseEntity<T> |
patch() |
<S> org.springframework.http.ResponseEntity<S> |
patch(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter) |
String |
path() |
String |
path(String prefix) |
org.springframework.http.ResponseEntity<T> |
post() |
<S> org.springframework.http.ResponseEntity<S> |
post(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter) |
org.springframework.http.ResponseEntity<T> |
put() |
<S> org.springframework.http.ResponseEntity<S> |
put(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter) |
ProxyExchange<T> |
sensitive(String... names)
Sets the names of sensitive headers that are not passed downstream to the backend
service.
|
ProxyExchange<T> |
uri(String uri)
Sets the uri for the backend call when triggered by the HTTP methods.
|
ProxyExchange<T> |
uri(URI uri)
Sets the uri for the backend call when triggered by the HTTP methods.
|
public ProxyExchange(org.springframework.web.client.RestTemplate rest, org.springframework.web.context.request.NativeWebRequest webRequest, org.springframework.web.method.support.ModelAndViewContainer mavContainer, org.springframework.web.bind.support.WebDataBinderFactory binderFactory, Type type)
public ProxyExchange<T> body(Object body)
post()
, put()
or patch()
). The body can be omitted if you just want to pass the incoming
request downstream without changing it. If you want to transform the incoming
request you can declare it as a @RequestBody
in your
@RequestMapping
in the usual Spring MVC way.body
- the request body to send downstreampublic ProxyExchange<T> header(String name, String... value)
name
- Header namevalue
- Header valuespublic ProxyExchange<T> headers(org.springframework.http.HttpHeaders headers)
headers
- the http headers to use in the downstream callpublic ProxyExchange<T> sensitive(String... names)
names
- the names of sensitive headerspublic ProxyExchange<T> uri(URI uri)
uri
- the backend uri to send the request topublic ProxyExchange<T> uri(String uri)
uri
- the backend uri to send the request topublic String path()
public void forward(String path)
public org.springframework.http.ResponseEntity<T> get()
public <S> org.springframework.http.ResponseEntity<S> get(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
public org.springframework.http.ResponseEntity<T> head()
public <S> org.springframework.http.ResponseEntity<S> head(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
public org.springframework.http.ResponseEntity<T> options()
public <S> org.springframework.http.ResponseEntity<S> options(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
public org.springframework.http.ResponseEntity<T> post()
public <S> org.springframework.http.ResponseEntity<S> post(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
public org.springframework.http.ResponseEntity<T> delete()
public <S> org.springframework.http.ResponseEntity<S> delete(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
public org.springframework.http.ResponseEntity<T> put()
public <S> org.springframework.http.ResponseEntity<S> put(Function<org.springframework.http.ResponseEntity<T>,org.springframework.http.ResponseEntity<S>> converter)
public org.springframework.http.ResponseEntity<T> patch()
Copyright © 2021 Pivotal Software, Inc.. All rights reserved.