Spring 4.0.x JSON/Ajax HTTP/1.1 406 Недопустимо

Я работаю с Spring 4.0.5.RELEASE, Spring MVC только через Java Config

У меня есть в моем pom.xml следующее:

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>${jackson.version}</version>
</dependency>

Where <jackson.version>1.9.13</jackson.version>

Я использую конфигурацию Spring по умолчанию для JSON. В некоторых @Controller у меня есть следующее:

@RequestMapping(value="/getjsonperson", 
                method=RequestMethod.GET, 
                produces=MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody Person getJSONPerson(){
    logger.info("getJSONPerson - getjsonperson");
    return PersonFactory.createPerson();
}

@RequestMapping(value="/getperson.json", method=RequestMethod.GET)
public @ResponseBody Person getPersonJSON(){
    logger.info("getPerson - getpersonJSON");
    return PersonFactory.createPerson();
} 

И работает нормально. Я вижу в браузере возвращенное значение JSON. Пока здесь все ок.

Теперь я хочу интегрировать Spring MVC + (JSON AJAX)

У меня есть этот учебник, как ссылаться на Spring MVC: Ajax & JQuery

Хорошо, у меня есть следующее о JSON с AJAX (работа через поле выбора или поле со списком для загрузки второго набора или коллекции)

Примечание. URL-адрес является статическим, даже если я использую только /spring-utility/facturaajax/findallproductobycategoria.htm, проблема сохраняется.

$("#categoria").change(function(event){

    var json = {"id" : $(this).find("option:selected").val(), "nombre" : $(this).find("option:selected").text() };

    $.ajax({
        url: "http://localhost:8080/spring-utility/facturaajax/findallproductobycategoria.htm" ,
        data: JSON.stringify(json),
        type: "POST",

        beforeSend: function(xhr) {
            xhr.setRequestHeader("Accept", "application/json");
            xhr.setRequestHeader("Content-Type", "application/json");
        },

        success: function(products) {
            alert("all fine!!!!");
        }

    });

    //event.preventDefault();
});

О контроллере У меня есть следующее для обработки процесса ajax

@RequestMapping(value="/findallproductobycategoria.htm", 
                method=RequestMethod.POST,
                consumes = MediaType.APPLICATION_JSON_VALUE,
                produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody Set<Producto> findAllProductoByCategoria(@RequestBody Categoria categoria){
    logger.info("findAllProductoByCategoria: {}", categoria.toString());
    return this.fakeMultipleRepository.findAllProductoByCategoria(categoria.getId());
}

Даже если я использую headers="Accept=application/json" или headers="Content-Type=application/json", проблема сохраняется.

POJO являются сериализуемыми

public class Categoria implements Serializable {

    private static final long serialVersionUID = 5655804710111228325L;

public class Producto implements Serializable {

    private static final long serialVersionUID = -6362590479124787529L;

Проблема: когда я изменяю значение элемента select html, я всегда получаю сообщение HTTP/1.1 406 Not Acceptable (см. два прикрепленных изображения)

Сообщение об ошибке 01

Сообщение об ошибке 02

Кстати: серверная сторона никогда не вызывается.

Я уже прочитал другие сообщения на SO. Практически все они упоминают о Джексоне и основаны на Spring 3.2.x.

Даже если я добавлю следующее, проблема не исчезнет

        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-core-asl</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-jaxrs</artifactId>
            <version>${jackson.version}</version>
        </dependency>

Чего не хватает? Спасибо.


person Manuel Jordan    schedule 23.09.2014    source источник


Ответы (1)


Для зрителей.

Ошибка была в том же URL. Он содержит .htm

Поэтому для всех разработчиков обязательно удалите его

От

@RequestMapping(value="/findallproductobycategoria.htm", method=RequestMethod.POST,
                consumes = MediaType.APPLICATION_JSON_VALUE,
                produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody Set<Producto> findAllProductoByCategoria(@RequestBody Categoria categoria){
    logger.info("findAllProductoByCategoria: {}", categoria.toString());
    return this.fakeMultipleRepository.findAllProductoByCategoria(categoria.getId());
}

To

@RequestMapping(value="/findallproductobycategoria", method=RequestMethod.POST,
                consumes = MediaType.APPLICATION_JSON_VALUE,
                produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody Set<Producto> findAllProductoByCategoria(@RequestBody Categoria categoria){
    logger.info("findAllProductoByCategoria: {}", categoria.toString());
    return this.fakeMultipleRepository.findAllProductoByCategoria(categoria.getId());
}

От:

$.ajax({
    url: "/spring-utility/facturaajax/findallproductobycategoria.htm" ,
    data: JSON.stringify(json),
    dataType: 'json',
    type: "POST",

To:

$.ajax({
    url: "/spring-utility/facturaajax/findallproductobycategoria" ,
    data: JSON.stringify(json),
    dataType: 'json',
    type: "POST",

Потому что у меня есть

@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
    Map<String,MediaType> mediaTypes = new LinkedHashMap<>();
    mediaTypes.put("json", MediaType.APPLICATION_JSON);
    mediaTypes.put("xml", MediaType.APPLICATION_XML);
    configurer.mediaTypes(mediaTypes);
    configurer.defaultContentType(MediaType.TEXT_HTML);
}

Spring отдает большее предпочтение URL-адресу .extension, чем содержимому header.

person Manuel Jordan    schedule 24.09.2014