1

after solving this Do we have to have to post json object with exactly same fields as in pojo object in controller? im getting 415 error while posting from AJAX ,I m using spring rest . And yes i have seen other similar questions but non of them solved my problem

controller:

@RequestMapping(value = "/createTest", method = RequestMethod.POST )

public  @ResponseBody String createTest(@RequestBody TestJsonDTO testJson)
        throws JsonProcessingException, IOException {
    TestSet test = new TestSet();
    //................

AJAX:

         function createTest() {
$.ajax({
    type : 'POST',
    url : "http://localhost:8085/annotationBased/admin/createTest",
    dataType : "json",
    accept:"application/json",
    contentType : "application/json",
    data : testToJSON(),

    success : function() {
        alert("success")
    },
    complete : function(){
        findAllTEst()
        alert("OK")

    },  

});
 function testToJSON() {

listOfQuestionForTest = questionToAdd;
return JSON.stringify({

    "testSet" : {name : $('#testname').val(),
        fullmark : parseInt($('#fullmark').val()),
        passmark : parseInt($('#passmark').val())},
    "questionsInTest" : listOfQuestionForTest
// "testDate":$('#testDate').value()
})

}

and i have added those class u suggested.

Community
  • 1
  • 1
CodeBlooded
  • 185
  • 5
  • 16
  • Have you checked if request's `Accept` header is the same as response's `Content-Type` header? You could check that with Postman or SaopUI, or any other REST console. – fps Feb 02 '15 at 04:56
  • i have not changed any thing in my code yet . – CodeBlooded Feb 02 '15 at 04:58
  • Try sending `Accept: application/json` header from jQuery. – fps Feb 02 '15 at 05:05
  • oh yes i m getting Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8 and Content-Type:application/x-www-form-urlencoded in my request header – CodeBlooded Feb 02 '15 at 05:07
  • i did that but same problem – CodeBlooded Feb 02 '15 at 05:14
  • Ok, if you're sending `Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.‌​8` and `Content-Type:application/x-www-form-urlencoded` headers in the request, then the jQuery ajax post is not working well. `JSON.stringify()` needs an object, I believe you're not forming it well. Try with `{ testSet: { name: $('#testname').val(), fullmark: parseInt($('#fullmark').val()), passmark: parseInt($('#passmark').val()) }, questionsInTest: listOfQuestionForTest }` in your `testToJSON()` function. – fps Feb 02 '15 at 05:49
  • no , didnt work . And one thing i doubt "Accept" and "Content-Type " are not for my POST but for error page I m getting on browser. sorry!! – CodeBlooded Feb 02 '15 at 05:57
  • Oh, OK, so you're getting them in the response, I thought you were sending them in the request. So, if your server is responding in html due to a server side exception, then you're getting 415 in your client because it is expecting json (and not html). You can solve it either by making the server *always* respond json, or by letting your client also accept html. – fps Feb 02 '15 at 06:10
  • And how can i do that ?? Please – CodeBlooded Feb 02 '15 at 06:16
  • Please try removing the quotes in testSet and questionsInTest – fps Feb 02 '15 at 16:27
  • no change , but here are request heders : accept:application/json, text/javascript, */*; q=0.01 and content type:"application/json; charset=UTF-8" – CodeBlooded Feb 02 '15 at 16:45
  • {"testSet":{"name":"ggggg","fullmark":8,"passmark":7},"questionsInTest":[ ]} this is my request payload – CodeBlooded Feb 02 '15 at 16:52
  • and firefox is showing Type-plan for this request i think that is the problem – CodeBlooded Feb 02 '15 at 17:23
  • That's the problem for sure! Try to force jQuery to send JSON. Try with [jQuery post() function](http://api.jquery.com/jquery.post/). – fps Feb 02 '15 at 17:25
  • turns out it was due to form tag in html. my mistake :( – CodeBlooded Feb 04 '15 at 14:53
  • Uhhh... Hope all back and forth communication has been of help to you anyways, and hope it helps others who have similar problems. – fps Feb 04 '15 at 14:56
  • sure it was a great help Magnamag. Thank you – CodeBlooded Feb 04 '15 at 15:11

1 Answers1

1

You're getting a 415 status code because the server is sending html in the response, while your client expects json.

This might indicate that a server-side exception occured. In such a case, application servers send back a html response.

You have to either make the server respond with json, even if an exception has occured, or let the client handle not only json responses, but also html ones.

I recommend you take the first approach:

@ControllerAdvice
public class ExceptionControllerAdvice {

    @ExceptionHandler(Exception.class)
    public ErrorResponse handleException(Exception ex) {
        ErrorResponse err = new ErrorResponse();
        err.setStatusCode(/* 4XX or 500, depending on exception type */);
        err.setERrorMessage(ex.getMessage());
        return err;
    }

}

public class ErrorResponse {

    private int statusCode;

    private String errorMessage;

    // getters and setters or make the fields public
}

A @ControllerAdvice is like a Spring controller, except that it works for every request. @ExceptionHandler tells Spring to intercept exceptions of the specified type and run the code within the annotated method.

Depending on the type of the exception, you should set the right status code in the ErrorResponse object you'll be returning. This is a very basic example, you can also extend from default Spring exception resolvers and overwrite the default behavior. Please refer to this article for further details.

EDIT: Another thing you could try is to force response's Content-Type to be always application/json, no matter the http stastus returned. You can do this by adding an interceptor in the class where you configure message converters and JSON serialization/deserialization properties:

@Configuration
public class ServiceContext
    extends WebMvcConfigurationSupport {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        MappingJackson2HttpMessageConverter converter = this.getMappingJackson2HttpMessageConverter();
        converters.add(converter);
    }

    @Bean
    public MappingJackson2HttpMessageConverter getMappingJackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
        ObjectMapper objectMapper = this.getObjectMapper();
        mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper);
        return mappingJackson2HttpMessageConverter;
    }

    @Bean
    public ObjectMapper getObjectMapper() {
        JsonFactory jsonFactory = new JsonFactory();
        ObjectMapper objectMapper = new ObjectMapper(jsonFactory);
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); // this is what you need
        objectMapper.setSerializationInclusion(Include.NON_NULL); // this is to not serialize unset properties
        return objectMapper;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        ResponseHeadersInterceptor headersInterceptor = this.getResponseHeadersInterceptor();
        registry.addInterceptor(headersInterceptor).addPathPatterns("/**");
    }

    @Bean
    public ResponseHeadersInterceptor getResponseHeadersInterceptor() {
        return new ResponseHeadersInterceptor();
    }

}

With ResponseHeadersInterceptor being as follows:

public class ResponseHeadersInterceptor
    extends HandlerInterceptorAdapter {

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        response.setContentType(MediaType.APPLICATION_JSON_VALUE + "; charset=UTF-8");
    }
}

This way, the server always responds JSON. If you still get 404 or 415, no doubt it's due to some error in the client side.

fps
  • 33,623
  • 8
  • 55
  • 110
  • That means the URL you are sending from the client doesn't match any @RequestMapping in your server. – fps Feb 02 '15 at 14:51
  • Are you sure you're setting content type and accept headers to application/json in your client? – fps Feb 02 '15 at 14:52
  • yes i did and url is also matching but its returning 404 error – CodeBlooded Feb 02 '15 at 15:01
  • The code is the same as in the other question? Maybe you should post it here, only the parts related to 415 and 404 errors. – fps Feb 02 '15 at 15:06
  • i've updated my question for code and i just found accept should be in lower case\ – CodeBlooded Feb 02 '15 at 15:18
  • can you help me on this (http ://stackoverflow.com/questions/29082840/how-to-parse-list-of-objects-with-list-fields-to-json) – CodeBlooded Mar 16 '15 at 18:19