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.
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.