415 error while ajax post in spring rest

2019-08-01 16:53发布

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.

标签: ajax spring rest
1条回答
孤傲高冷的网名
2楼-- · 2019-08-01 17:26

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.

查看更多
登录 后发表回答