406 Not Acceptable Error in Spring MVC: Deep Dive into Accept Headers and JSON Responses

Dec 04, 2025 · Programming · 11 views · 7.8

Keywords: Spring MVC | 406 Not Acceptable | JSON Response

Abstract: This article provides an in-depth analysis of the common 406 Not Acceptable error in Spring MVC, typically caused by mismatches between client Accept headers and server response types. Based on a real-world case study, it examines Accept header configuration, JSON response generation mechanisms, and Spring MVC's content negotiation strategies. By comparing various solutions, it emphasizes correctly setting Accept headers to support application/json, supplemented by other potential causes such as class member visibility and path extension handling. Covering Spring versions 3.x to 4.x, it includes code examples and configuration recommendations to help developers comprehensively understand and resolve this issue.

Introduction

In web application development with Spring MVC, developers often encounter the HTTP status code 406 Not Acceptable when handling JSON responses. This error indicates that the server cannot generate a response that meets the client's Accept header requirements. This article analyzes the causes of this error through a typical case study and provides solutions based on best practices.

Problem Description and Context

A user using Spring 3.2.2 and Tomcat 7 attempted to generate a simple JSON response but received a 406 error. Tomcat logs indicated: "The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request 'accept' headers." Despite the client sending an Accept header of: Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8. Configurations included web.xml, dispatcher-servlet.xml, and controller code, with attempts to add Jackson converters proving ineffective.

Core Problem Analysis

According to the best answer (Answer 3), the key issue is the absence of application/json in the Accept header. Spring MVC's content negotiation mechanism relies on the Accept header to determine the response type. When a controller method is annotated with @ResponseBody and returns an object, Spring attempts to serialize it to JSON, but this only works if the Accept header explicitly specifies or matches application/json via wildcards. The provided Accept header prioritized HTML and XML types, causing Spring to fail in finding an acceptable representation, resulting in a 406 error.

Solutions and Implementation

To resolve this, adjust the client request's Accept header. For example, use tools like the Firefox plugin "Poster" to set the Accept header to application/json. At the code level, specify the response type using Spring MVC's produces attribute, e.g., @RequestMapping(value="foobar.htm", method = RequestMethod.GET, produces="application/json"). This ensures the method only handles requests for JSON, avoiding content negotiation failures.

Supplementary Analysis and Considerations

Other answers provide additional insights. Answer 1 recommends using Maven to manage Jackson dependencies, simplifying configuration; Answer 2 notes that classes without public members might cause 406 errors, requiring structural checks; Answer 4 mentions the use of @EnableWebMvc in Spring 4; Answer 5 highlights that path extensions (e.g., {fileName:.+}) can interfere with content negotiation, solvable by configuring favorPathExtension(false) or using query parameters. Overall, 406 errors may stem from multiple factors, necessitating systematic troubleshooting.

Code Examples and Configuration Optimization

Below is an optimized controller example to ensure correct JSON response generation:

package com.example.controller;

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
public class ApiController {
    
    @GetMapping(value = "/data", produces = "application/json")
    public DataObject getData() {
        DataObject obj = new DataObject();
        obj.setValue("test");
        return obj;
    }
}

class DataObject {
    private String value;
    
    public String getValue() {
        return value;
    }
    
    public void setValue(String value) {
        this.value = value;
    }
}

In dispatcher-servlet.xml, ensure annotation-driven is enabled and Jackson is configured (for Spring 3.x):

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/mvc 
                           http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    
    <mvc:annotation-driven />
    
    <!-- Optional: Explicit Jackson converter configuration -->
    <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
        <property name="supportedMediaTypes">
            <list>
                <value>application/json</value>
            </list>
        </property>
    </bean>
</beans>

Conclusion and Best Practices

The 406 Not Acceptable error in Spring MVC often results from content negotiation failures. The core solution is to ensure the Accept header includes application/json or use the produces attribute to restrict response types. Developers should: 1) Check client request headers; 2) Properly configure Spring MVC and Jackson; 3) Pay attention to class design and path handling. By understanding HTTP protocols and Spring mechanisms, such issues can be effectively avoided, enhancing application robustness.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.