Why is controller method not returning Object when i add servlet mapping (.htm) to my request on making AJAX call

StackOverflow https://stackoverflow.com/questions/22954535

  •  30-06-2023
  •  | 
  •  

Question

I am making an ajax call from javascript to my controller and returning an Object.

I am sending Json from ajax and retrieving in controller by @RequestBody and sending Json back from controller using @ResponseBody.

My functionality is perfectly working until i had to add .htm in Request mapping. Now it is throwing HttpMediaTypeNotAcceptableException when i am returning same Object(returning just String is working even with .htm).

this is my ajax call from js:

var user = new Object();
user.id = 1;
user.name = "Noor";
    $.ajax(contextPath + "/createUser.htm", {
        type: 'POST',
        dataType: 'json',
        contentType: 'application/json',
        data: JSON.stringify(user),
        success: function(result) {
             alert("Success");
        },
        error: function(jqXHR, textStatus, errorThrown) {
            alert("Fail");
        }
    });

This is my controller:

@RequestMapping(value = "/createUser.htm", method = RequestMethod.POST)
@ResponseBody
public ResultDTO createUser(@Valid @RequestBody CitizenUser user){
    log.info("Enter Controller");
    ..
    ..
    ..
    log.infor("Exit");
    return new User(100,"DADA");
}

This is perfectly working fine without .htm in mapping.

But my project requires .htm in mapping, so i just cannot remive it.

Can any one help me to fix this issue??

Was it helpful?

Solution

File extension takes precedence over accept headers when determinating which media type is supported. Your .htm will force it to be text/html and not application/json. To disable this you will have to configure the ContentNegotiationManager yourself and disable favoring file extensions.

If you use xml you can use the ContentNegotiationManagerFactoryBean to configure it and pass it as a reference to the <mvc:annotation-driven /> tag.

<bean id="contentNegotiationManager" class=" org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="favorPathExtension" value="false" />
</bean>

<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager" />

When using Java Config you can use the ContentNegotiationConfigurer to do this.

OTHER TIPS

With

dataType: 'json',

you're specifying that you want JSON back in the response. You're effectively setting the request Accept header to

Accept: application/json

So your web application can only respond with application/json content. Without the .htm extension, there's nothing to restrict the generated response on the server side, so all types are producible, but only the Jackson HttpMessageConverter produces application/json, so that one will be used .

With the .htm extension, you additionally have content negotiation happening. This basically determines what your server should be producing even if it is not acceptable. That's why you get a HttpMediaTypeNotAcceptableException. If you can't get rid of the extension, look into ContentNegotiationConfigurer for configuring content negotiation.

See also

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top