8 changed files with 166 additions and 448 deletions
@ -1,215 +0,0 @@
@@ -1,215 +0,0 @@
|
||||
[[webflux-ann-httpexchange]] |
||||
= HttpExchange |
||||
|
||||
[.small]#xref:web/webmvc/mvc-controller/ann-httpexchange.adoc[See equivalent in the Servlet stack]# |
||||
|
||||
Similarly to |
||||
xref:web/webflux/controller/ann-requestmapping.adoc[`@RequestMapping`], |
||||
you can use the `@HttpExchange` annotation to map requests to controllers |
||||
methods. However, while `@RequestMapping` is only supported on the server side, `@HttpExchange` can be used both to create a server-side mapping and |
||||
xref:integration/rest-clients.adoc#rest-http-interface[an HTTP |
||||
Interface Client] that allows making requests. |
||||
|
||||
`@HttpExchange` has various attributes to match by URL, HTTP method, and media |
||||
types. You can use it at the class level to express shared mappings or at the |
||||
method level to narrow down to a specific endpoint mapping. |
||||
|
||||
There are also HTTP method specific shortcut variants of `@HttpExchange`: |
||||
|
||||
* `@GetExchange` |
||||
* `@PostExchange` |
||||
* `@PutExchange` |
||||
* `@DeleteExchange` |
||||
* `@PatchExchange` |
||||
|
||||
// TODO |
||||
The shortcuts are xref:web/webflux/controller/ann-httpexchange.adoc#webflux-ann-httpexchange-composed[Custom Annotations] that are provided |
||||
because, arguably, most controller methods should be mapped to a specific |
||||
HTTP method versus using `@HttpExchange`, which, by default, matches |
||||
to all HTTP methods. |
||||
An `@HttpExchange` is still needed at the class level to express shared mappings. |
||||
|
||||
The following example has type and method level mappings: |
||||
|
||||
[tabs] |
||||
====== |
||||
Java:: |
||||
+ |
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"] |
||||
---- |
||||
@RestController |
||||
@HttpExchange("/persons") |
||||
class PersonController { |
||||
|
||||
@GetExchange("/{id}") |
||||
public Person getPerson(@PathVariable Long id) { |
||||
// ... |
||||
} |
||||
|
||||
@PostExchange |
||||
@ResponseStatus(HttpStatus.CREATED) |
||||
public void add(@RequestBody Person person) { |
||||
// ... |
||||
} |
||||
} |
||||
---- |
||||
|
||||
Kotlin:: |
||||
+ |
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] |
||||
---- |
||||
@RestController |
||||
@HttpExchange("/persons") |
||||
class PersonController { |
||||
|
||||
@GetExchange("/{id}") |
||||
fun getPerson(@PathVariable id: Long): Person { |
||||
// ... |
||||
} |
||||
|
||||
@PostExchange |
||||
@ResponseStatus(HttpStatus.CREATED) |
||||
fun add(@RequestBody person: Person) { |
||||
// ... |
||||
} |
||||
} |
||||
---- |
||||
====== |
||||
|
||||
|
||||
`@HttpExhange` supports a very similar method signature to `@MessageMapping`, |
||||
however, since it needs to be suitable both for requester and responder use, |
||||
there are slight differences. |
||||
|
||||
[[webflux-ann-httpexchange-uri-templates]] |
||||
== URI patterns |
||||
[.small]#xref:web/webmvc/mvc-controller/ann-httpexchange.adoc#mvc-ann-httpexchange-uri-templates[See equivalent in the Servlet stack]# |
||||
|
||||
URI patterns resolution support is very similar to the one offered by xref:web/webflux/controller/ann-requestmapping.adoc#webflux-ann-requestmapping-uri-templates[`@RequestMapping`], with the difference |
||||
that while `@RequestMapping` accepts a `String` array as its `value` or `path` |
||||
parameter that is used to specify the URI patterns, only a single `String` can be passed |
||||
as the `value` of `@HttpExchange`. |
||||
|
||||
[[webflux-ann-httpexchange-contenttype]] |
||||
== Consumable Media Types |
||||
[.small]#xref:web/webmvc/mvc-controller/ann-httpexchange.adoc#mvc-ann-httpexchange-contenttype[See equivalent in the Servlet stack]# |
||||
|
||||
You can narrow the request mapping based on the `Content-Type` of the request, |
||||
as the following example shows: |
||||
|
||||
[tabs] |
||||
====== |
||||
Java:: |
||||
+ |
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"] |
||||
---- |
||||
@PostExchange(path = "/pets", contentType = "application/json") // <1> |
||||
public void addPet(@RequestBody Pet pet) { |
||||
// ... |
||||
} |
||||
---- |
||||
<1> Using a `contentType` attribute to narrow the mapping by the content type. |
||||
|
||||
Kotlin:: |
||||
+ |
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] |
||||
---- |
||||
@PostExchange("/pets", contentType = "application/json") // <1> |
||||
fun addPet(@RequestBody pet: Pet) { |
||||
// ... |
||||
} |
||||
---- |
||||
<1> Using a `contentType` attribute to narrow the mapping by the content type. |
||||
====== |
||||
|
||||
The `contentType` attribute accepts a single `String` as the attribute value. |
||||
|
||||
You can also declare a shared `contentType` attribute at the class level. |
||||
Unlike most other request-mapping attributes, however, when used at the |
||||
class level, a method-level `contentType` attribute overrides rather than |
||||
extends the class-level declaration. |
||||
|
||||
TIP: `MediaType` provides constants for commonly used media types, such as |
||||
`APPLICATION_JSON_VALUE` and `APPLICATION_XML_VALUE`. |
||||
|
||||
|
||||
[[webflux-ann-httpexchange-accept]] |
||||
== Producible Media Types |
||||
[.small]#xref:web/webmvc/mvc-controller/ann-httpexchange.adoc#mvc-ann-httpexchange-accept[See equivalent in the Servlet stack]# |
||||
|
||||
You can narrow the request mapping based on the `Accept` request header and the list of |
||||
content types that a controller method produces, as the following example shows: |
||||
|
||||
[tabs] |
||||
====== |
||||
Java:: |
||||
+ |
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"] |
||||
---- |
||||
@GetExchange(path = "/pets/{petId}", accept = "application/json") // <1> |
||||
@ResponseBody |
||||
public Pet getPet(@PathVariable String petId) { |
||||
// ... |
||||
} |
||||
---- |
||||
<1> Using an `accept` attribute to narrow the mapping by the content type that |
||||
can be served. |
||||
|
||||
Kotlin:: |
||||
+ |
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] |
||||
---- |
||||
@GetExchange("/pets/{petId}", accept = ["application/json"]) // <1> |
||||
@ResponseBody |
||||
fun getPet(@PathVariable petId: String): Pet { |
||||
// ... |
||||
} |
||||
---- |
||||
<1> Using an `accept` attribute to narrow the mapping by the content type that |
||||
can be served. |
||||
====== |
||||
|
||||
The `accept` attribute accepts a `String` array as the attribute value. |
||||
|
||||
You can declare a shared `accept` attribute at the class level. Unlike most |
||||
other request-mapping attributes, however, when used at the class level, |
||||
a method-level `accept` attribute |
||||
overrides rather than extends the class-level declaration. |
||||
|
||||
TIP: `MediaType` provides constants for commonly used media types, such as |
||||
`APPLICATION_JSON_VALUE` and `APPLICATION_XML_VALUE`. |
||||
|
||||
|
||||
[[webflux-ann-httpexchange-params-and-headers]] |
||||
== Parameters, headers |
||||
[.small]#xref:web/webmvc/mvc-controller/ann-httpexchange.adoc#mvc-ann-httpexchange-params-and-headers[See equivalent in the Servlet stack]# |
||||
|
||||
You can narrow request mappings based on request parameter and headers |
||||
conditions. It is supported for `@HttpExchange` in the same way as in xref:web/webflux/controller/ann-requestmapping.adoc#webflux-ann-requestmapping-params-and-headers[`@RequestMapping` parameters and headers support]. |
||||
|
||||
|
||||
[[webflux-ann-httpexchange-head-options]] |
||||
== HTTP HEAD, OPTIONS |
||||
[.small]#xref:web/webmvc/mvc-controller/ann-httpexchange.adoc#mvc-ann-httpexchange-head-options[See equivalent in the Servlet stack]# |
||||
|
||||
The support of `HTTP HEAD` and `HTTP OPTIONS` in `@HttpExchange` annotated |
||||
controllers is the same xref:web/webflux/controller/ann-requestmapping.adoc#webflux-ann-requestmapping-head-options[ |
||||
as in `@RequestMapping` annotated controllers]. |
||||
|
||||
[[webflux-ann-httpexchange-composed]] |
||||
== Custom Annotations |
||||
[.small]#xref:web/webmvc/mvc-controller/ann-httpexchange.adoc#mvc-ann-httpexchange-composed[See equivalent in the Servlet stack]# |
||||
|
||||
`@HttpExchange` annotated controllers support the use of xref:core/beans/classpath-scanning.adoc#beans-meta-annotations[composed annotations] |
||||
for request mapping. Those are annotations that are themselves meta-annotated |
||||
with `@HttpExchange` and composed to redeclare a subset (or all) of the |
||||
`@HttpExchange` attributes with a narrower, more specific purpose. |
||||
|
||||
`@GetExchange`, `@PostExchange`, `@PutExchange`, `@DeleteExchange`, |
||||
and `@PatcExchange` are examples of composed annotations. They are provided |
||||
because, arguably, most controller methods should be mapped to a specific |
||||
HTTP method versus using `@HttpExchange`, which, by default, |
||||
matches to all HTTP methods. If you need an example of composed annotations, |
||||
look at how those are declared. |
||||
|
||||
|
@ -1,215 +0,0 @@
@@ -1,215 +0,0 @@
|
||||
[[mvc-ann-httpexchange]] |
||||
= HttpExchange |
||||
|
||||
[.small]#xref:web/webflux/controller/ann-httpexchange.adoc[ |
||||
See equivalent in the Reactive stack]# |
||||
|
||||
Similarly to |
||||
xref:web/webmvc/mvc-controller/ann-requestmapping.adoc[`@RequestMapping`], |
||||
you can use the `@HttpExchange` annotation to map requests to controllers |
||||
methods. However, while `@RequestMapping` is only supported on the server side, `@HttpExchange` can be used both to create a server-side mapping and |
||||
xref:integration/rest-clients.adoc#rest-http-interface[an HTTP |
||||
Interface Client] that allows making requests. |
||||
|
||||
`@HttpExchange` has various attributes to match by URL, HTTP method, and media |
||||
types. You can use it at the class level to express shared mappings or at the |
||||
method level to narrow down to a specific endpoint mapping. |
||||
|
||||
There are also HTTP method specific shortcut variants of `@HttpExchange`: |
||||
|
||||
* `@GetExchange` |
||||
* `@PostExchange` |
||||
* `@PutExchange` |
||||
* `@DeleteExchange` |
||||
* `@PatchExchange` |
||||
|
||||
The shortcuts are xref:web/webmvc/mvc-controller/ann-httpexchange.adoc#mvc-ann-httpexchange-composed[Custom Annotations] that are provided |
||||
because, arguably, most controller methods should be mapped to a specific |
||||
HTTP method versus using `@HttpExchange`, which, by default, matches |
||||
to all HTTP methods. |
||||
An `@HttpExchange` is still needed at the class level to express shared mappings. |
||||
|
||||
The following example has type and method level mappings: |
||||
|
||||
[tabs] |
||||
====== |
||||
Java:: |
||||
+ |
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"] |
||||
---- |
||||
@RestController |
||||
@HttpExchange("/persons") |
||||
class PersonController { |
||||
|
||||
@GetExchange("/{id}") |
||||
public Person getPerson(@PathVariable Long id) { |
||||
// ... |
||||
} |
||||
|
||||
@PostExchange |
||||
@ResponseStatus(HttpStatus.CREATED) |
||||
public void add(@RequestBody Person person) { |
||||
// ... |
||||
} |
||||
} |
||||
---- |
||||
|
||||
Kotlin:: |
||||
+ |
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] |
||||
---- |
||||
@RestController |
||||
@HttpExchange("/persons") |
||||
class PersonController { |
||||
|
||||
@GetExchange("/{id}") |
||||
fun getPerson(@PathVariable id: Long): Person { |
||||
// ... |
||||
} |
||||
|
||||
@PostExchange |
||||
@ResponseStatus(HttpStatus.CREATED) |
||||
fun add(@RequestBody person: Person) { |
||||
// ... |
||||
} |
||||
} |
||||
---- |
||||
====== |
||||
|
||||
|
||||
`@HttpExhange` supports a very similar method signature to `@MessageMapping`, |
||||
however, since it needs to be suitable both for requester and responder use, |
||||
there are slight differences, which are discussed below. |
||||
|
||||
[[mvc-ann-httpexchange-uri-templates]] |
||||
== URI patterns |
||||
[.small]#xref:web/webflux/controller/ann-httpexchange.adoc#webflux-ann-httpexchange-uri-templates[See equivalent in the Reactive stack]# |
||||
|
||||
URI patterns resolution support is very similar to the one offered by xref:web/webmvc/mvc-controller/ann-requestmapping.adoc#mvc-ann-requestmapping-uri-templates[`@RequestMapping`], with the difference |
||||
that while `@RequestMapping` accepts a `String` array as its `value` or `path` |
||||
parameter that is used to specify the URI patterns, only a single `String` can be passed |
||||
as the `value` of `@HttpExchange`. |
||||
|
||||
[[mvc-ann-httpexchange-contenttype]] |
||||
== Consumable Media Types |
||||
[.small]#xref:web/webflux/controller/ann-httpexchange.adoc#webflux-ann-httpexchange-contenttype[See equivalent in the Reactive stack]# |
||||
|
||||
You can narrow the request mapping based on the `Content-Type` of the request, |
||||
as the following example shows: |
||||
|
||||
[tabs] |
||||
====== |
||||
Java:: |
||||
+ |
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"] |
||||
---- |
||||
@PostExchange(path = "/pets", contentType = "application/json") // <1> |
||||
public void addPet(@RequestBody Pet pet) { |
||||
// ... |
||||
} |
||||
---- |
||||
<1> Using a `contentType` attribute to narrow the mapping by the content type. |
||||
|
||||
Kotlin:: |
||||
+ |
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] |
||||
---- |
||||
@PostExchange("/pets", contentType = "application/json") // <1> |
||||
fun addPet(@RequestBody pet: Pet) { |
||||
// ... |
||||
} |
||||
---- |
||||
<1> Using a `contentType` attribute to narrow the mapping by the content type. |
||||
====== |
||||
|
||||
The `contentType` attribute accepts a single `String` as the attribute value. |
||||
|
||||
You can also declare a shared `contentType` attribute at the class level. |
||||
Unlike most other request-mapping attributes, however, when used at the |
||||
class level, a method-level `contentType` attribute overrides rather than |
||||
extends the class-level declaration. |
||||
|
||||
TIP: `MediaType` provides constants for commonly used media types, such as |
||||
`APPLICATION_JSON_VALUE` and `APPLICATION_XML_VALUE`. |
||||
|
||||
|
||||
[[mvc-ann-httpexchange-accept]] |
||||
== Producible Media Types |
||||
[.small]#xref:web/webflux/controller/ann-httpexchange.adoc#webflux-ann-httpexchange-accept[See equivalent in the Reactive stack]# |
||||
|
||||
You can narrow the request mapping based on the `Accept` request header and the list of |
||||
content types that a controller method produces, as the following example shows: |
||||
|
||||
[tabs] |
||||
====== |
||||
Java:: |
||||
+ |
||||
[source,java,indent=0,subs="verbatim,quotes",role="primary"] |
||||
---- |
||||
@GetExchange(path = "/pets/{petId}", accept = "application/json") // <1> |
||||
@ResponseBody |
||||
public Pet getPet(@PathVariable String petId) { |
||||
// ... |
||||
} |
||||
---- |
||||
<1> Using an `accept` attribute to narrow the mapping by the content type that |
||||
can be served. |
||||
|
||||
Kotlin:: |
||||
+ |
||||
[source,kotlin,indent=0,subs="verbatim,quotes",role="secondary"] |
||||
---- |
||||
@GetExchange("/pets/{petId}", accept = ["application/json"]) // <1> |
||||
@ResponseBody |
||||
fun getPet(@PathVariable petId: String): Pet { |
||||
// ... |
||||
} |
||||
---- |
||||
<1> Using an `accept` attribute to narrow the mapping by the content type that |
||||
can be served. |
||||
====== |
||||
|
||||
The `accept` attribute accepts a `String` array as the attribute value. |
||||
|
||||
You can declare a shared `accept` attribute at the class level. Unlike most |
||||
other request-mapping attributes, however, when used at the class level, |
||||
a method-level `accept` attribute |
||||
overrides rather than extends the class-level declaration. |
||||
|
||||
TIP: `MediaType` provides constants for commonly used media types, such as |
||||
`APPLICATION_JSON_VALUE` and `APPLICATION_XML_VALUE`. |
||||
|
||||
|
||||
[[mvc-ann-httpexchange-params-and-headers]] |
||||
== Parameters, headers |
||||
[.small]#xref:web/webflux/controller/ann-httpexchange.adoc#webflux-ann-httpexchange-params-and-headers[See equivalent in the Reactive stack]# |
||||
|
||||
You can narrow request mappings based on request parameter and headers |
||||
conditions. It is supported for `@HttpExchange` in the same way as in xref:web/webmvc/mvc-controller/ann-requestmapping.adoc#mvc-ann-requestmapping-params-and-headers[`@RequestMapping` parameter and header support] . |
||||
|
||||
|
||||
[[mvc-ann-httpexchange-head-options]] |
||||
== HTTP HEAD, OPTIONS |
||||
[.small]#xref:web/webflux/controller/ann-httpexchange.adoc#webflux-ann-httpexchange-head-options[See equivalent in the Reactive stack]# |
||||
|
||||
The support of `HTTP HEAD` and `HTTP OPTIONS` in `@HttpExchange` annotated |
||||
controllers is the same xref:web/webmvc/mvc-controller/ann-requestmapping.adoc#mvc-ann-requestmapping-head-options[ |
||||
as in `@RequestMapping` annotated controllers]. |
||||
|
||||
[[mvc-ann-httpexchange-composed]] |
||||
== Custom Annotations |
||||
[.small]#xref:web/webflux/controller/ann-httpexchange.adoc#webflux-ann-httpexchange-head-options[See equivalent in the Reactive stack]# |
||||
|
||||
`@HttpExchange` annotated controllers support the use of xref:core/beans/classpath-scanning.adoc#beans-meta-annotations[composed annotations] |
||||
for request mapping. Those are annotations that are themselves meta-annotated |
||||
with `@HttpExchange` and composed to redeclare a subset (or all) of the |
||||
`@HttpExchange` attributes with a narrower, more specific purpose. |
||||
|
||||
`@GetExchange`, `@PostExchange`, `@PutExchange`, `@DeleteExchange`, |
||||
and `@PatcExchange` are examples of composed annotations. They are provided |
||||
because, arguably, most controller methods should be mapped to a specific |
||||
HTTP method versus using `@HttpExchange`, which, by default, |
||||
matches to all HTTP methods. If you need an example of composed annotations, |
||||
look at how those are declared. |
||||
|
||||
|
Loading…
Reference in new issue