Bahar JSON isteği 406 alıyor (Kabul Edilemez)


85

bu benim javascript'im:

    function getWeather() {
        $.getJSON('getTemperature/' + $('.data option:selected').val(), null, function(data) {
            alert('Success');                               
        });
    }

bu benim kontrolörüm:

@RequestMapping(value="/getTemperature/{id}", headers="Accept=*/*", method = RequestMethod.GET)
@ResponseBody
public Weather getTemparature(@PathVariable("id") Integer id){
    Weather weather = weatherService.getCurrentWeather(id);
        return weather;
}

spring-servlet.xml

<context:annotation-config />
<tx:annotation-driven />

Bu hatayı alıyorum:

GET http://localhost:8080/web/getTemperature/2 406 (Not Acceptable)

Başlıklar:

Yanıt Başlıkları

Server  Apache-Coyote/1.1
Content-Type    text/html;charset=utf-8
Content-Length  1070
Date    Sun, 18 Sep 2011 17:00:35 GMT

Üstbilgi İste

Host    localhost:8080
User-Agent  Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0.2) Gecko/20100101 Firefox/6.0.2
Accept  application/json, text/javascript, */*; q=0.01
Accept-Language en-us,en;q=0.5
Accept-Encoding gzip, deflate
Accept-Charset  ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection  keep-alive
X-Requested-With    XMLHttpRequest
Referer http://localhost:8080/web/weather
Cookie  JSESSIONID=7D27FAC18050ED84B58DAFB0A51CB7E4

İlginç not:

406 hatası alıyorum, ancak bu arada hazırda bekletme sorgusu çalışıyor. Dropbox'ta seçimi her değiştirdiğimde tomcat günlüğünün söylediği şu:

 select weather0_.ID as ID0_0_, weather0_.CITY_ID as CITY2_0_0_, weather0_.DATE as DATE0_0_, weather0_.TEMP as TEMP0_0_ from WEATHER weather0_ where weather0_.ID=?

Sorun ne olabilir? SO'da daha önce benzer iki soru vardı, kabul edilen tüm ipuçlarını orada denedim, ama işe yaramadı sanırım ...

Herhangi bir öneri? Soru sormaktan çekinmeyin ...

Yanıtlar:


107

406 Kabul Edilemez

Talep tarafından tanımlanan kaynak, yalnızca talepte gönderilen kabul başlıklarına göre kabul edilebilir olmayan içerik özelliklerine sahip yanıt varlıkları oluşturabilir.

Bu nedenle, kabul etme başlığınız application / json'dur ve denetleyiciniz bunu döndüremez. Bu, @ResponseBody ek açıklamalı dönüş değerini karşılayacak doğru HTTPMessageConverter bulunamadığında gerçekleşir. HTTPMessageConverter, sınıf yolundaki <mvc:annotation-driven>belirli 3-d parti kitaplıkları verildiğinde, kullandığınızda otomatik olarak kaydedilir .

Ya sınıf yolunuzda doğru Jackson kitaplığına sahip değilsiniz ya da <mvc:annotation-driven>yönergeyi kullanmadınız.

Senaryonuzu başarıyla kopyaladım ve bu iki kitaplığı kullanarak ve hiçbir headers="Accept=*/*"yönerge olmadan sorunsuz çalıştı .

  • jackson-core-asl-1.7.4.jar
  • jackson-mapper-asl-1.7.4.jar

Hayır, sorun bu değildi, cevabımı kontrol et.
Jaanus

HttpMessageConverters'ı yapılandırmak sorununuzu manuel olarak çözdüyse, mvc: annotation-drive kullanımı, dönüştürücüleri ve HandlerAdapters'ı (HA) otomatik olarak yapılandırmasıyla aynı şeyi yapacaktır. Herhangi bir HA'yı açıkça yapılandırırsanız, diğer tüm varsayılanları iptal edeceğini unutmayın.
Villu Sepman

Hmm, mvcorada ne var? Ben kullandım <tx:annotation-driven />ve txxmlns:tx="http://www.springframework.org/schema/tx"
Jaanus

1
Gibi bir şey var: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">ve spring-web-3.0.x ve spring-webmvc-3.0.x kavanozları?
Villu Sepman

1
Ah orada o şema konumu yoktu ... ama teşekkürler, bu bana yardımcı oldu. Bunun tx:annotation-drivenaynı mvc:annotation-driveya da smthin olduğunu düşündüm .
Jaanus

74

Aynı sorunu yaşadım, En Son Bahar 4.1.1'den itibaren aşağıdaki kavanozları pom.xml'ye eklemeniz gerekiyor.

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.4.1</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.4.1.1</version>
</dependency>

ayrıca aşağıdaki kavanozlara sahip olduğunuzdan emin olun:

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-core-asl</artifactId>
    <version>1.9.13</version>
</dependency>

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.13</version>
</dependency>

406 Spring MVC Json, başlıklar "kabul et" isteğine göre kabul edilemez


Bu cevap, en iyi cevabın Maven'in farkında olan versiyonudur ve mükemmel şekilde çalışır! Maven istisnaları, kaputun altında gerçekte neler olup bittiği konusunda daha net olabilir.
Cotta

4
Bunun Springs Resmi belgelerinde belgelendiği yeri sağlayabilir misiniz? Birisi sorunun bu olduğunu nasıl bilebilir?
Adelin

Sadece jackson-databind ve jackson-mapper-asl için bağımlılıkları belirtmeniz gerekir, diğer ikisi geçişli bağımlılıklardır ve yine de çözülecektir.
anre

1
Bu sadece ikinci iki bağımlılığı ekledikten sonra benim için çalıştı. Teşekkürler.
docwatson

İkisine de kesinlikle ihtiyacınız yok. Spring, MappingJacksonHttpMessageConverterJackson 1 ve MappingJackson2HttpMessageConverterJackson 2'yi ekleyecektir . Bunların her biri, JSON'u serileştirmek / seriyi kaldırmak için yeterince iyidir. Sadece bir tanesine ihtiyacınız var (daha zengin özellikli olduğu için Jackson 2 ile gidin).
Sotirios Delimanolis

16

Bu durumun döndürüleceği başka bir durum daha var: Jackson eşleştiricisi fasulyenizi nasıl serileştireceğinizi çözemezse. Örneğin, aynı boole özelliği için iki erişimci yönteminiz varsa isFoo()ve getFoo().

Ne oluyor Spring'in olmasıdır MappingJackson2HttpMessageConverter Jackson'ın çağırır StdSerializerProvider sizin nesneye dönüştürebilirsiniz olup olmadığını görmek için. Çağrı zincirinin altında, bilgilendirici bir mesajla birlikte bir StdSerializerProvider._createAndCacheUntypedSerializeratar JsonMappingException. Ancak, bu istisna tarafından yutulur StdSerializerProvider._createAndCacheUntypedSerializerve Spring'e nesneyi dönüştüremeyeceğini söyler. Dönüştürücülerin tükenmesiyle, Spring Accept, kullanabileceği bir başlık verilmediğini bildirdi, ki bu elbette bunu verirken sahte */*.

Bu davranış için bir hata var , ancak "yeniden üretilemez" olarak kapatıldı: çağrılan yöntem fırlatabileceğini ilan etmiyor, bu nedenle istisnaları yutmak görünüşe göre uygun bir çözüm (evet, bu alaydı). Maalesef, Jackson'ın herhangi bir kaydı yok ... ve kod tabanında olmasını dileyen çok sayıda yorum var, bu yüzden bunun tek gizli bilgi olmadığından şüpheleniyorum.


Çok teşekkür ederim! Spring MVC'de yeniyim ve JSON'u nasıl iade edeceğimi bulmakta gerçekten zorlanıyordum. Herkes 406 hatanın nedeni olarak eksik @ResponseBody ek açıklamaları ve Jackson bağımlılıklarından bahseder. Benim durumumda, JSON olarak döndürmek istediğim nesneye ait bir genel alan için bir erişimci yöntemini kaçırdığım ortaya çıktı.
Anthony Jack

Teşekkürler @kdgregory! Bir alan için alıcı / ayarlayıcı eklemeyi unuttum. Bunları eklemek bu sorunu çözdü.
Rubens MARIUZZO

16

Benim denetleyicisi yöntemi yürütür aynı problem vardı ama tepki Hata 406. Ben hataların bulunması AbstractMessageConverterMethodProcessor#writeWithMessageConvertersve bu yöntemi bulduk ContentNegotiationManager#resolveMediaTypeshep döner text/htmltarafından desteklenmemektedir MappingJacksonHttpMessageConverter. Sorun şu ki, org.springframework.web.accept.ServletPathExtensionContentNegotiationStrategydaha önce çalışıyor org.springframework.web.accept.HeaderContentNegotiationStrategyve isteğimin uzantısı /get-clients.htmlHata 406 ile ilgili sorunumun nedeni. İstek url'sini olarak değiştirdim /get-clients.


Merhaba atott, aynı sorunu yaşıyorum ve isteğin uzantısını değiştirmeyle ilgili ipucunuz sorunumu çözdü. Çözümünüzü paylaştığınız için çok teşekkürler !!
jherranzm

Benim durumumda, normal denetleyici çalışırken (dinlenme yolu kimliğinde bir uzantı kullansanız bile) 406'ya aynı nedenle neden olan (testte) bir uzantıya sahip bir dinlenme yoluydu.
Jur_

9

Aşağıdaki jar2'lerin sınıf yolunda bulunduğundan emin olun .

Herhangi biri veya her ikisi de eksikse bu hata gelecektir.

jackson-core-asl-1.9.X.jar jackson-mapper-asl-1.9.X.jar

6

Sonunda cevabı buradan buldum:

Huzurlu ajax isteklerini bahara eşleme

Alıntı yaparım:

@ RequestBody / @ ResponseBody ek açıklamaları normal görünüm çözümleyicileri kullanmaz, kendi HttpMessageConverter'larını kullanırlar. Bu ek açıklamaları kullanmak için, bu dönüştürücüleri AnnotationMethodHandlerAdapter içinde, başvuruda açıklandığı gibi yapılandırmalısınız (muhtemelen MappingJacksonHttpMessageConverter'a ihtiyacınız vardır).


3

<mvc:annotation-driven />Eklemediyseniz dispatcherservlet.xml dosyasını kontrol edin . Ve Ekle

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-core-asl</artifactId>
    <version>1.9.13</version>
</dependency>

<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.13</version>
</dependency>

pom.xml dosyanızdaki bu bağımlılıklar


2
<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-base</artifactId>
    <version>2.6.3</version>
</dependency>

2
Bu kod soruyu yanıtlayabilirken, sorunun nasıl ve / veya neden çözüldüğüne ilişkin ek bağlam sağlamak , yanıtlayanın uzun vadeli değerini artıracaktır.
sünger

2

Muhtemelen hiç kimse bu kadar aşağı kaydırmıyor, ancak yukarıdaki çözümlerden hiçbiri benim için düzeltmedi, ancak tüm alıcı yöntemlerimi yapmak publicyaptı.

Alıcı görünürlüğümü özel pakete bıraktım; Jackson onları bulamayacağına karar verdi ve havaya uçtu. (Kullanmak @JsonAutoDetect(getterVisibility=NON_PRIVATE)sadece kısmen düzeltildi.


Bu tam olarak benim sorunumdu. Ayarlayıcılarımı halktan korumalı olarak değiştirdim ve Jackson çalışmayı bıraktı.
JuanMiguel

Burada aynı sorun, AbstractMap.SimpleImmutableEntrydaha sonra indirgeme yaptım, AbstractMap.SimpleEntryanahtar için bir pasör olmadığı için hala zar yok. Bunun üzerine pojo gitti.
Robert Bain

2

Gönderilen nesnenin (bu durumda Hava Durumu) alıcı / ayarlayıcı içerdiğinden emin olun


1

Denetleyicide, yanıt gövdesi ek açıklaması yöntemde değil, dönüş türünde olmamalıdır, örneğin:

@RequestMapping(value="/getTemperature/{id}", headers="Accept=*/*", method = RequestMethod.GET)
public @ResponseBody Weather getTemparature(@PathVariable("id") Integer id){
    Weather weather = weatherService.getCurrentWeather(id);
        return weather;
}

Ayrıca ham jquery.ajax işlevini kullanır ve contentType ve dataType'ın doğru ayarlandığından emin olurdum.

Farklı bir kayda göre, json'un yay kullanımını oldukça sorunlu buluyorum. Dizeleri ve GSON kullanarak hepsini kendim yaptığımda daha kolaydı.


@ResponseBodyÖğesinin yerleştirilmesi önemli olmamalı ... GSON'a bakacağım ... ama yine de mümkünse bu JSON'un çalışmasını istiyorum.
Jaanus

1

@Atott'un bahsettiği gibi .

Jackson'ın en son sürümünü pom.xml'nize eklediyseniz ve Spring 4.0 veya daha yenisiyle, @ResponseBodyeylem yönteminizi kullanarak ve @RequestMappingyapılandırdıysanız produces="application/json;charset=utf-8", ancak yine de 406 (Kabul Edilemez) sürümünüz varsa, sanırım bunu denemeniz gerekir. MVC DispatcherServlet bağlam yapılandırmanız:

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

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

Sonunda sorunumu bu şekilde çözdüm.


1

İlkbahar 4.3.10: Sorunu çözmek için aşağıdaki ayarları kullandım.

1. Adım: Aşağıdaki bağımlılıkları ekleyin

    <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.6.7</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.6.7</version>
</dependency>
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-core-asl</artifactId>
    <version>1.9.13</version>
</dependency>
<dependency>
    <groupId>org.codehaus.jackson</groupId>
    <artifactId>jackson-mapper-asl</artifactId>
    <version>1.9.13</version>
</dependency>

Adım 2: Aşağıdakileri MVC DispatcherServlet bağlam yapılandırmanıza ekleyin:

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

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

Yay 3.2'den beri, varsayılan konfigürasyona göre favorPathExtension true olarak ayarlanmıştır, çünkü bu nedenle, istek uri'nin .htmspring gibi herhangi bir uygun uzantıya sahip olması, uzantı için öncelik verecektir. 2. adımda bunu geçersiz kılmak için contentNegotiationManager bean ekledim.


1

@EnableWebMvc ek açıklamasını kaçırdığım için aynı sorunu yaşıyordum. (Tüm yay konfigürasyonlarım açıklama tabanlıdır, XML eşdeğeri mvc olacaktır: açıklama temelli)


0

sınıf yolunuzda doğru jackson sürümüne sahip olduğunuzdan emin olun


Jackson-all-1.8.5.jar dosyasını klasörüme ekledim WEB-INF/lib, ancak yine de aynı sorun: /
Jaanus

0

Jackson'ın doğru sürümü için @joyfun'un yaptığı gibi kontrol edin, ancak başlıklarımızı da kontrol edin ... Kabul edin / istemci tarafından iletilmeyebilir ... alma isteğinizin gerçekte ne gönderdiğini kontrol etmek için firebug veya eşdeğerini kullanın. Ben% 100 emin olmasam da ek açıklamanın başlık özniteliğinin değişmez değerleri kontrol ettiğini düşünüyorum.


Firebug'dan başlıkları ana gönderiye ekledim. İyiler mi?
Jaanus

0

Diğer sonra, Spring sunucu uygulamasına olası tüm JAR'ları, bağımlılıkları ve ek açıklamaları dahil etsem de çözemediğim bir sorun daha vardı. Sonunda, yanlış dosya uzantısına sahip olduğumu fark ettim, yani aynı kapsayıcıda çalışan iki ayrı sunucu uygulaması olduğunu ve birinin ".do" olduğu ve diğerinin abonelikler için kullanıldığı şekliyle rastgele "adlandırıldığı farklı dosya uzantılarıyla eşlemem gerekti. alt". Hepsi iyi ama SUB, normalde filmler altyazı dosyaları için kullanılan geçerli bir dosya uzantısıdır ve bu nedenle Tomcat, başlığı geçersiz kılıyor ve "text / x-dvd.sub ..." gibi bir şey döndürüyordu, bu yüzden her şey yolundaydı, ancak uygulama JSON bekliyordu ancak Altyazılar alıyordu bu nedenle tek yapmam gereken, web.xmleklediğim dosyadaki eşlemeyi değiştirmek oldu :

<mime-mapping>
    <extension>sub</extension>
    <mime-type>application/json</mime-type>
</mime-mapping>

0

Aynı problemi yaşadım maalesef buradaki hiçbir çözüm problemimi çözmedi çünkü problemim farklı bir sınıftaydı.

Önce @bekur tarafından önerildiği gibi tüm bağımlılıkların yerinde olup olmadığını kontrol ettim, sonra istemcilerden sunucuya giden istek / yanıtı kontrol ettim, tüm başlıkların Jquery tarafından uygun şekilde ayarlandığını kontrol ettim. Sonra kontrol ettim RequestMappingHandlerAdapter MessageConvertersve 7'sinin de yerinde olduğunu kontrol ettim, gerçekten Spring'den nefret etmeye başladım! Daha sonra Spring'den 4.0.6.RELEASEolarak güncelledim 4.2.0.RELEASE, yukarıdakiler yerine başka bir yanıt aldım. ÖyleydiRequest processing failed; nested exception is java.lang.IllegalArgumentException: No converter found for return value of type

İşte benim kontrolör yöntemim

  @RequestMapping(value = "/upload", method = RequestMethod.POST,produces = "application/json")
    public ResponseEntity<UploadPictureResult> pictureUpload(FirewalledRequest initialRequest) {

        DefaultMultipartHttpServletRequest request = (DefaultMultipartHttpServletRequest) initialRequest.getRequest();

        try {
            Iterator<String> iterator = request.getFileNames();

            while (iterator.hasNext()) {
                MultipartFile file = request.getFile(iterator.next());
                session.save(toImage(file));
            }
        } catch (Exception e) {
            return new ResponseEntity<UploadPictureResult>(new UploadPictureResult(),HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return new ResponseEntity<UploadPictureResult>(new UploadPictureResult(), HttpStatus.OK);
    } 




    public class UploadPictureResult extends WebResponse{

    private List<Image> images;

    public void setImages(List<Image> images) {
        this.images = images;
    }
}






    public class WebResponse implements Serializable {


    protected String message;

    public WebResponse() {
    }

    public WebResponse(String message) {

        this.message = message;
    }


    public void setMessage(String message) {
        this.message = message;
    }
}

Çözüm, UploadPictureResult'un WebResponse'u genişletmemesini sağlamaktı

Spring, bazı nedenlerden dolayı, WebResponse'u genişlettiğinde UploadPictureReslt'in nasıl dönüştürüleceğini belirleyemedi


0
<dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.8.0</version>
    </dependency>

ssl kimlik doğrulamasını kullanmıyorum ve bu jackson-databind, jackson-core.jar ve jackson-databind.jar içerir ve ardından RequestMapping içeriğini şu şekilde değiştirir:

@RequestMapping(value = "/id/{number}", produces = "application/json; charset=UTF-8", method = RequestMethod.GET)
public @ResponseBody Customer findCustomer(@PathVariable int number){
    Customer result = customerService.findById(number);
    return result;
}

dikkat: eğer ürünleriniz "application / json" türü değilse ve ben bunu fark etmediysem ve 406 hatası aldıysam, bu size yardımcı olabilir.


0

bu konuyu kontrol edin. spring mvc restcontroller return json string p / s: WebMvcConfig sınıfınıza jack son eşleme yapılandırması eklemelisiniz

@Override protected void configureMessageConverters( List<HttpMessageConverter<?>> converters) { // put the jackson converter to the front of the list so that application/json content-type strings will be treated as JSON converters.add(new MappingJackson2HttpMessageConverter()); // and probably needs a string converter too for text/plain content-type strings to be properly handled converters.add(new StringHttpMessageConverter()); }


0

Bu, springVersion = 5.0.3.RELEASE için güncelleme yanıtıdır.

Yukarıdaki cevaplar yalnızca eski springVersion <4.1 sürümünde çalışacaktır . son bahar için gradle dosyasına aşağıdaki bağımlılıkları eklemelisiniz:

compile group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: fasterxmljackson
compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: fasterxmljackson

fasterxmljackson=2.9.4

Umarım bu, en son bahar sürümünü kullananlar için yararlı olur.


-3

@RequestMapping'deki üstbilgi öğesini kaldırıp deneyebilir misiniz ..

Sevmek


@RequestMapping(value="/getTemperature/{id}", method = RequestMethod.GET)

Sanırım bahar, kabul başlıkları için tam eşleşme yerine bir 'içerir kontrolü' yapıyor. Ancak yine de, başlıklar öğesini kaldırmaya ve kontrol etmeye değer.


Kaldırdım ama hala hata yapıyorum Btw tomcat günlüğüne baktığımda, ardından bununla sorgu weatherService.getCurrentWeather(id);"etkinleştirildi" ... yani bir şey çalışıyor ... 406'nın görünmesi ve Hibernate SQL seçiminin aynı anda çalışması mümkün mü?
Jaanus

Lütfen işe yaraması gereken bunu deneyin. Bu ek açıklamayı denetleyici @RequestMapping'e ekleyin (yöntem = RequestMethod.GET, headers = {"Accept = text / xml, application / json"})
sats
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.