Search

Dark theme | Light theme

February 8, 2025

Helidon SE Helpings: Return Response Based On Request Accept Header

Suppose you want to return a response based on the Accept header of the request. If the Accept header is application/json you want to return a JSON response and if the Accept header is application/xml you want to return an XML response. You can use the isAccepted(MediaType) of the ServerRequestHeaders class to check if the value of the request header Accept is equal to the specified media type. The method returns true if the media type is defined for the request header Accept and false if not.

In order to convert an object to XML you need to add the dependency com.fasterxml.jackson.dataformat:jackson-dataformat-xml to your pom.xml file:

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
</dependency>

In the following example HttpService implementation the request header Accept is used to determine if the response should be in XML or default JSON format:

package mrhaki;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import io.helidon.common.media.type.MediaTypes;
import io.helidon.http.HeaderNames;
import io.helidon.webserver.http.HttpRules;
import io.helidon.webserver.http.HttpService;
import io.helidon.webserver.http.ServerRequest;
import io.helidon.webserver.http.ServerResponse;

/** Example service to return data in either XML or JSON depending on the request header Accept. */
class SampleService implements HttpService {
  /** Use for converting an object to XML. */
  private final XmlMapper xmlMapper = new XmlMapper();

  @Override
  public void routing(HttpRules rules) {
    rules.get("/content", this::handle);
  }

  private void handle(ServerRequest req, ServerResponse resp) throws JsonProcessingException {
    // Define record for data structure to send in the response.
    record Message(String content) {}

    // Check if the Accept header is set with the value application/xml.
    if (req.headers().isAccepted(MediaTypes.APPLICATION_XML)) {
      // Return XML response.
      resp.header(HeaderNames.CONTENT_TYPE, MediaTypes.APPLICATION_XML.text())
          .send(xmlMapper.writeValueAsString(new Message("Sample")));
    } else {
      // Return default JSON response.
      resp.send(new Message("Sample"));
    }
  }
}

When you access the endpoint with different values for the request header Accept you get a response in the format you specified:

$ curl -s -X GET --location "http://localhost:8080/sample/content" \
    -H "Accept: application/xml" | xmllint --format -
<?xml version="1.0">
<Message>
  <content>Sample</content>
</Message>
$
$ curl -s -X GET --location "http://localhost:8080/sample/content" \
    -H "Accept: application/json" | jq -r .
{
  "content": "Sample"
}
$

Written with Helidon SE 4.1.6.