Class ShaftRestAssuredFilter

java.lang.Object
com.shaft.api.ShaftRestAssuredFilter
All Implemented Interfaces:
io.restassured.filter.Filter

public class ShaftRestAssuredFilter extends Object implements io.restassured.filter.Filter
A SHAFT-native Allure filter for REST Assured that replaces the default AllureRestAssured HTML-template-based filter.

The default AllureRestAssured filter (allure-rest-assured 2.x) uses a Freemarker template whose renderer hard-codes the content type as text/html. In Allure 3 the attachment is therefore treated as an HTML file, so users see raw HTML source (<div>, <pre>, etc.) instead of the actual request/response content — this is the "API attachments styled as HTML files" bug.

This filter creates exactly four attachments per API call, each with the correct MIME type for Allure 3:

  1. Requesttext/plain; HTTP method, URL, request headers, cookies, and form params (metadata only, no body inlined).
  2. Request Body — always created when the request body is non-empty. The body is attached with its detected MIME type (application/json, text/xml, or text/plain); JSON is pretty-printed for readability.
  3. Responsetext/plain; HTTP status line, elapsed time, and response headers.
  4. Response Body — always created when the response body is non-empty. Binary responses (images, PDFs, etc.) are attached with their declared MIME type using the raw byte array; text responses are attached as UTF-8 strings with the appropriate text MIME type.

There is no size threshold for creating body attachments — every non-empty body is always attached separately so it receives the correct MIME type and is rendered with syntax highlighting in Allure 3.

See Also:
  • RestActions.sendRequest(RestActions.RequestType, String, io.restassured.specification.RequestSpecification)
  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    detectContentType(String body, String declaredContentType)
    Determines the best MIME type for an attachment body.
    io.restassured.response.Response
    filter(io.restassured.specification.FilterableRequestSpecification requestSpec, io.restassured.specification.FilterableResponseSpecification responseSpec, io.restassured.filter.FilterContext filterContext)
    Intercepts every REST Assured request, attaches the request and response information to the current Allure step/test, then returns the real response.
    formatBody(String body, String contentType)
    Pretty-prints JSON bodies so they are immediately readable in Allure 3's JSON viewer; returns all other bodies unchanged.
    getFileExtension(String contentType)
    Returns the file extension that corresponds to the given MIME type.
    boolean
    Returns true when the declared Content-Type indicates binary (non-text) content that must be preserved as a byte array rather than decoded as a UTF-8 string.
    boolean
    Returns true when content looks like a JSON object or array.
    boolean
    Returns true when content looks like an XML document or fragment.
    Strips charset and parameter suffixes from a Content-Type header value and returns the bare MIME type.

    Methods inherited from class Object

    equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • ShaftRestAssuredFilter

      public ShaftRestAssuredFilter()
  • Method Details

    • filter

      public io.restassured.response.Response filter(io.restassured.specification.FilterableRequestSpecification requestSpec, io.restassured.specification.FilterableResponseSpecification responseSpec, io.restassured.filter.FilterContext filterContext)
      Intercepts every REST Assured request, attaches the request and response information to the current Allure step/test, then returns the real response.
      Specified by:
      filter in interface io.restassured.filter.Filter
      Parameters:
      requestSpec - the mutable request specification built by REST Assured
      responseSpec - the mutable response specification
      filterContext - used to pass the request to the next filter or to the actual HTTP client
      Returns:
      the HTTP response produced by the server
    • detectContentType

      public String detectContentType(String body, String declaredContentType)
      Determines the best MIME type for an attachment body.

      The declared Content-Type header value is checked first. If it signals JSON (application/json or any *\/json* variant) or XML, the corresponding standard MIME type is returned directly.

      When the declared type is text/html but the body is actually JSON (some APIs serve JSON with the wrong content-type header), the method falls back to content-sniffing so that Allure 3 renders it with syntax highlighting.

      Parameters:
      body - the raw body string to sniff if necessary
      declaredContentType - the Content-Type header value (may be empty)
      Returns:
      the recommended MIME type for the attachment
    • isBinaryContentType

      public boolean isBinaryContentType(String contentType)
      Returns true when the declared Content-Type indicates binary (non-text) content that must be preserved as a byte array rather than decoded as a UTF-8 string.

      Binary types include image/*, audio/*, video/*, application/pdf, application/zip, application/octet-stream, and common compressed/archive formats.

      Parameters:
      contentType - the declared Content-Type header value
      Returns:
      true if the content type represents binary data
    • normalizeMimeType

      public String normalizeMimeType(String contentType)
      Strips charset and parameter suffixes from a Content-Type header value and returns the bare MIME type.

      For example, "application/json; charset=utf-8" becomes "application/json".

      Parameters:
      contentType - the raw Content-Type header value
      Returns:
      the bare MIME type without parameters, or the original string if no semicolon is present
    • looksLikeJson

      public boolean looksLikeJson(String content)
      Returns true when content looks like a JSON object or array.

      Performs a two-stage check: first a lightweight bracket-boundary heuristic, then actual Gson parsing to confirm the content is valid JSON. This eliminates false positives such as "{not valid json}" or "[plain text]" while keeping the fast-path rejection for non-JSON content.

      Parameters:
      content - the string to inspect
      Returns:
      true if content is a syntactically valid JSON object or array
    • looksLikeXml

      public boolean looksLikeXml(String content)
      Returns true when content looks like an XML document or fragment.

      Uses a lightweight structural check: XML must start with < and contain either a closing tag (</) or a self-closing element (/>). This avoids false positives for arbitrary strings that merely start with < and end with > (e.g. "<not xml at all>").

      Note: HTML documents also pass this check because they contain closing tags. In practice, HTML bodies are accompanied by a Content-Type: text/html header which is resolved before this sniff is invoked, so the misclassification scenario is rare.

      Parameters:
      content - the string to inspect
      Returns:
      true if the trimmed content has the structural markers of XML
    • formatBody

      public String formatBody(String body, String contentType)
      Pretty-prints JSON bodies so they are immediately readable in Allure 3's JSON viewer; returns all other bodies unchanged.
      Parameters:
      body - the raw body content
      contentType - the MIME type already determined for the body
      Returns:
      pretty-printed JSON string, or the original body for non-JSON content
    • getFileExtension

      public String getFileExtension(String contentType)
      Returns the file extension that corresponds to the given MIME type.
      Parameters:
      contentType - a standard MIME type string
      Returns:
      a dotted file extension such as ".json" or ".txt"