Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring web app returns HTTP Status 406

I'm creating a basic spring based web app:

pom dependencies:

<properties>
    <java-version>1.8</java-version>
    <springframework-version>4.3.3.RELEASE</springframework-version>
    <jackson-version>2.8.3</jackson-version>
    <org.slf4j-version>1.7.6</org.slf4j-version>
    <logback.version>1.1.7</logback.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${springframework-version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${springframework-version}</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.0.1</version>
        <scope>provided</scope>
    </dependency>

    <!-- Jackson JSON Mapper -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>${jackson-version}</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson-version}</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>${jackson-version}</version>
    </dependency>

    <!-- Logging -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>${org.slf4j-version}</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>${logback.version}</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.2</version>
    </dependency>

    <!-- @Inject -->
    <dependency>
        <groupId>javax.inject</groupId>
        <artifactId>javax.inject</artifactId>
        <version>1</version>
    </dependency>
</dependencies>

In order to skip the usage of web.xml I'm using WebApplicationInitializer:

public class AppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        WebApplicationContext context = getContext();
        servletContext.addListener(new ContextLoaderListener(context));
        ServletRegistration.Dynamic dispatcher = servletContext.addServlet("DispatcherServlet", new DispatcherServlet(context));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/*");
    }

    private AnnotationConfigWebApplicationContext getContext() {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.setConfigLocation(SpringModule.class.getPackage().getName());
        return context;
    }

Here is my spring config class:

@Configuration
@ComponentScan(basePackages = "com.company.app")
public class SpringModule extends WebMvcConfigurerAdapter {

    public SpringModule() {
        super();
    }

    private MappingJackson2HttpMessageConverter customJackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        jsonConverter.setObjectMapper(objectMapper);
        return jsonConverter;
    }


    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
        messageConverters.add(customJackson2HttpMessageConverter());
        messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
        messageConverters.add(new StringHttpMessageConverter());
        messageConverters.add(new ByteArrayHttpMessageConverter());
        messageConverters.add(new ResourceHttpMessageConverter());
        messageConverters.add(new SourceHttpMessageConverter());
        messageConverters.add(new FormHttpMessageConverter());

        super.configureMessageConverters(messageConverters);
    }

    /*
 * Configure ContentNegotiationManager
 */
    @Override
    public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
        configurer.ignoreAcceptHeader(true).defaultContentType(
                MediaType.APPLICATION_JSON);
    }

Here is my test controller:

@Controller
@RequestMapping(value = "/user")
public class SomeController {

    @RequestMapping(value = "/", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    @ResponseBody
    public Person helloElad() {
        return new Person("some name");
    }
}

When testing the controller (using browser) I'm getting: enter image description here

If I'm returning a plain String it works fine.

I tries to debug method configureMessageConverters and configureContentNegotiation but for some reason it never gets there (on bootstrapping), I'm not sure it is related to the problem though.

Any ideas?

like image 642
forhas Avatar asked Feb 28 '26 08:02

forhas


1 Answers

HTTP 406 is an indication that your request content is not negotiated, it is probably that necessary http message converters are not found in configuration. Simple way to add basic set of message converter would be annotating your controller @EnableMvc

like image 95
kuhajeyan Avatar answered Mar 02 '26 06:03

kuhajeyan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!