With our earlier example, we have seen that the server understands the content-types of incoming requests and entities with HTTP request header content-types.
In our code example, we have implemented the following content type and, by default application/JSON, and to represent what content type that the client desired to get, we use application/JSON as the Accept header.
Please note that if no Accept header is present in the request, the server will send a pre-configured default representation type. In our example, it is always application/JSON, as shown in the following screenshot:
The preceding screenshot depicts the Content-Type and Accept headers from our examples.
If we want to implement our earlier example of a w3c image within our investor service application in a similar fashion, all we need to do is add the following dependency to pom.xml:
<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> </dependency>
Modify the @GetMapping annotation in the controller class as follows:
@GetMapping(path="/investors/{investorId}/stocks/{symbol}", produces={MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
So, by using the accept request header, the client either gets the response as XML or as JSON. Cool, isn't it?
With Postman, we will get either a XML or JSON response according to the application/XML or application/JSON Accept header value:
Two other ways that we can pass the content type information to the server are as follows:
- Using specific extensions in resource URIs:
- Using parameters for representing an extension:
The following table provides a quick reference guide of a few other content-negotiation examples as server and client may need to deal with many other aspects of content-negotiation:
Content-Negotiation |
Implementation |
Indicate client preference—allows clients to indicate their capabilities (such as media types and languages) |
Accept:application/json,application/xml;q=0.9,*/*;q=0.8 (support json or xml, q -> preference order) |
Implement media type—how to decide which media type to use for representation in a response |
According to the Accept header from the client (Accept: application/atom+xml), the server can respond with a content-type, that is, Content-Type: application/atom+xml; charset=UTF-8 |
Implement character encoding—know what character encoding to use for textual representations in responses |
Content-Type: charset=UTF-8 (use content-type charset) |
Support compression—know when to enable the compression of representations |
# Request Accept-Encoding: gzip # Response Content-Encoding: gzip Vary: Accept-Encoding |
Send Vary header—know how to use the Vary header to indicate to clients how the server chooses a particular representation |
# Response Content-Language: en Vary: Accept-Language |
Handling negotiation failures—know whether to serve a default representation or return an error |
# Request Accept: application/json,*/*;q=0.0 (client cannot process anything other than JSON) # Response 406 Not Acceptable (the server returns an error code as it does not support JSON. @GetMapping our chapter examples throws this error when the client expects only an XML responses as our example serves the JSON and not XML, except for one—a GET mapping) Link: <http://www.example.org/errors/mediatypes.html>;rel="help" {"message": "This server does not support JSON. See help for alternatives."} (additional help) |