POST JSON, 415 Desteklenmeyen ortam türü, Yay 3 mvc ile başarısız oluyor


171

Bir sunucu uygulamasına bir POST isteği göndermeye çalışıyorum. İstek şu şekilde jQuery aracılığıyla gönderilir:

var productCategory = new Object();
productCategory.idProductCategory = 1;
productCategory.description = "Descrizione2";
newCategory(productCategory);

newCategory nerede

function newCategory(productCategory)
{
  $.postJSON("ajax/newproductcategory", productCategory, function(
      idProductCategory)
  {
    console.debug("Inserted: " + idProductCategory);
  });
}

ve postJSON

$.postJSON = function(url, data, callback) {
    return jQuery.ajax({
    'type': 'POST',
    'url': url,
    'contentType': 'application/json',
    'data': JSON.stringify(data),
    'dataType': 'json',
    'success': callback
    });
};

Firebug ile JSON doğru gönderildiğini görüyorum:

{"idProductCategory":1,"description":"Descrizione2"}

Ama 415 Desteklenmeyen ortam türü alıyorum. Bahar mvc denetleyicinin imzası var

    @RequestMapping(value = "/ajax/newproductcategory", method = RequestMethod.POST)
public @ResponseBody
Integer newProductCategory(HttpServletRequest request,
        @RequestBody ProductCategory productCategory)

Birkaç gün önce işe yaradı, şimdi değil. Gerekirse daha fazla kod göstereceğim. Teşekkürler


Birkaç gün önce neyi değiştirdin? Ayrıca, var productCategory = { idProductCategory: 1, description: "Descrizione2" };daha kısa ve okunması daha kolay olmaz mıydı ? Spring'e application/jsonözellikle kabul etmesini söylemen gerekir mi? Başka bir deyişle, verilerin bir biçimde gelmesini bekliyor mu?
Dave Newton

Bu projenin diğer kısmında çalıştığımdan beri birçok şey var ve bugün bu gerilemeyi buldum. Bu bölümde hiçbir şey değiştirmedim. Evet, bu şekilde kullanmalıyım çünkü bir formdan girdi alıyorum.
gc5

Hayır, bunu form kodlu verilerle aynı olmayan bir JSON Ajax gönderisinden alıyorsunuz.
Dave Newton

1
Jackson'ın CLASSPATH'inizde hala mevcut olduğundan emin misiniz?
Tomasz Nurkiewicz

1
u uygulama / json yerine metin / json gönderirseniz u aynı hatayı alırsınız
Blacksonic

Yanıtlar:


250

Bunu daha önce Spring @ResponseBody ile yaşadım ve bunun nedeni, istekle birlikte gönderilen bir kabul başlığı olmamasıydı. Kabul etmek başlık jQuery ile ayarlamak için bir acı olabilir, ama bu benim için çalıştı kaynak

$.postJSON = function(url, data, callback) {
    return jQuery.ajax({
    headers: { 
        'Accept': 'application/json',
        'Content-Type': 'application/json' 
    },
    'type': 'POST',
    'url': url,
    'data': JSON.stringify(data),
    'dataType': 'json',
    'success': callback
    });
};

Content-Type üstbilgisi, @RequestBody tarafından istemciden istekte gönderilen verinin hangi formatta olduğunu belirlemek için kullanılır. Kabul üstbilgisi @ResponseBody tarafından, yanıtta verilerin istemciye hangi biçimin geri gönderileceğini belirlemek için kullanılır. Bu yüzden her iki başlığa da ihtiyacınız var.


1
başlıklar: {...} ve JSON.stringify (...) her zaman beni harekete geçirir.
Tim Perry

1
Bunun neden daha fazla belgelenmediği hakkında bir fikrim yok. Bu sorun beni çok zaman kaybettirdi. Çok teşekkür ederim!
Hugo Nava Kopp

Spring'in varsayılan olarak form verilerini desteklemesini bekliyordum, ancak desteklemiyor. Yani, (şimdi oldukça eski) çözüm için teşekkürler.
RiZKiT

Ben koymak için postacı kullanıyordum, sadece içerik türü ekledi: '' application / json ". Teşekkür ederim
Janatbek Sharsheyev

22

application/jsonSorunu çözdüğü için isteğe içerik türü eklemek


18

Benzer bir sorun vardı ama sorun ben @RequestBody ile açıklamalı DTO için varsayılan bir yapıcı sağlamak ihmal olduğunu bulundu.


1
bana da aynı şey oldu. Aynı ada sahip 2 yöntemim vardı ve 415 alıyordum. Teşekkürler!
Daniel Vilas-Boas

12

Tam olarak aynı konuya girdiğime inanıyorum. JSON, JavaScript ve Sunucu ile sayısız saatler süren kavgadan sonra suçlu buldum: Benim durumumda DTO'da bir Date nesnesi vardı, bu Date nesnesi bir String'e dönüştürüldü, böylece biçim: SS: dd.

JSON bilgileri geri gönderilirken, bu Date String nesnesinin tam bir Date Object'e dönüştürülmesi gerekiyordu, bu nedenle DTO'da ayarlamak için bir yönteme de ihtiyacımız var. Büyük AMA, farklı bir parametre türüne (String vs Date) sahip olsalar bile DTO'da aynı ada (Overload) sahip 2 yönteminiz olamaz çünkü bu size 415 Desteklenmeyen Medya türü hatası verecektir.

Bu benim denetleyici yöntemimdi

  @RequestMapping(value = "/alarmdownload/update", produces = "application/json", method = RequestMethod.POST)
  public @ResponseBody
  StatusResponse update(@RequestBody AlarmDownloadDTO[] rowList) {
    System.out.println("hola");
    return new StatusResponse();
  }

Bu benim DTO örneğiydi (id get / set ve preAlarm get yöntemleri kod kısalığı için dahil değildir):

@JsonIgnoreProperties(ignoreUnknown = true)
public class AlarmDownloadDTO implements Serializable {

  private static final SimpleDateFormat formatHHmm = new SimpleDateFormat("HH:mm");

  private String id;
  private Date preAlarm;

  public void setPreAlarm(Date date) { 
    this.preAlarm == date;
  }
  public void setPreAlarm(String date) {    
    try {
      this.preAlarm = formatHHmm.parse(date);
    } catch (ParseException e) {
      this.preAlarm = null;
    } catch (NullPointerException e){
      this.preAlarm = null;
    }
  }
}

Her şeyin çalışması için Date type parametresi ile yöntemi kaldırmanız gerekir. Bu hata çok sinir bozucu. Umarım bu saatlerce hata ayıklama sağlayabilir.


Teşekkürler - ya da ayarlayıcılardan birini yeniden adlandırabilirsiniz. Ben de vardı public void setParameters(List<Parameter> parameters)& public void setParameters(Parameter... parameters)ikincisi değişen bir fasulye yöntemleri addParametersbenim için düzeltilen sorunun.
Conor Svensson

Cesedin this.preAlarm = date yerine this.preAlarm == date olması sorunu değil mi?
Michael, Monica Cellio'yu

12

Benzer bir sorunla karşılaştım ve bu şekilde düzelttim,

Sorun, JSON'dan Java'ya dönüştürme işleminden kaynaklanıyor, dönüşümün doğru bir şekilde gerçekleşmesi için doğru çalışma zamanı jackson kütüphanelerine sahip olmak gerekiyor.

Aşağıdaki kavanozları ekleyin (bağımlılık yoluyla veya sınıfyoluna indirerek ve ekleyerek.

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

Bu, sorunu çözmeli.

Kodun Tamamı:

function() {
  $.ajax({
    type: "POST",
    url: "saveUserDetails.do",
    data: JSON.stringify({
      name: "Gerry",
      ity: "Sydney"
    }),
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    success: function(data) {
      if (data.status == 'OK')
        alert('Person has been added');
      else
        alert('Failed adding person: ' + data.status + ', ' + data.errorMessage);
}

ve denetleyici imzası şöyle görünür:

@RequestMapping(value = "/saveUserDetails.do", method = RequestMethod.POST)
public @ResponseBody Person addPerson( @RequestBody final  Person person) {

Bu yardımcı olur umarım


Sadece jackson-databindgerekli.
Alex78191

8

Spring Boot'u Spring Mvc ile entegre ettiğimde bu sorunla karşılaştım. Sadece bu bağımlılıkları ekleyerek çözdüm.

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

5

Küçük bir yan not - bir web uygulaması geliştirirken aynı hatayı tökezledi. Firefox Poster ile servis yaparak oynayarak bulduğumuz hata, Json'daki alanların ve değerlerin çift tırnaklarla çevrilmesi gerektiğiydi. Örneğin..

[ {"idProductCategory" : "1" , "description":"Descrizione1"}, 
  {"idProductCategory" : "2" , "description":"Descrizione2"} ]

Bizim durumumuzda, json'u javascript ile doldurduk, bu da duyduğumdan tek / çift tırnaklarla uğraşırken biraz kafa karıştırıcı olabilir.

Bu yazıda ve 'Kabul Et' ve 'İçerik Türü' başlıklarını dahil etmek gibi diğer yayınlarda daha önce söylenenler de geçerlidir.

Umarım yardımcı olur.


3

Nasıl çalışacağını öğrendim. Yanılıyorsam söyle bana. Serileştirmek / serileştirmek için yalnızca bir yol kullandım: Bu ( @JSONSerializeve @JSONDeserialize) ile ilgili tüm ek açıklamaları kaldırdım ve CustomObjectMappersınıftaki Serileştiriciler ve Deserializerler'i kaydettim . Bu davranışı açıklayan bir makale bulamadım ama bu şekilde çözdüm. Umarım faydalıdır.


Bana da aynısını yapıyor! Neden olduğuna dair bir açıklama var mı?
Kaprisli

Lütfen yönteminizi ayrıntılı olarak açıklayabilir misiniz?
Dipanshu Verma

1

Ben de aynı problemi yaşadım. Sorunu çözmek için şu adımları izlemem gerekti:

1. Aşağıdaki bağımlılıklara sahip olduğunuzdan emin olun:

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>${jackson-version}</version> // 2.4.3
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson-version}</version> // 2.4.3
    </dependency>

2. Aşağıdaki filtreyi oluşturun:

    public class CORSFilter extends OncePerRequestFilter {

        @Override
        protected void doFilterInternal(HttpServletRequest request,
                                        HttpServletResponse response, FilterChain filterChain)
                throws ServletException, IOException {

            String origin = request.getHeader("origin");
            origin = (origin == null || origin.equals("")) ? "null" : origin;
            response.addHeader("Access-Control-Allow-Origin", origin);
            response.addHeader("Access-Control-Allow-Methods", "POST, GET, PUT, UPDATE, DELETE, OPTIONS");
            response.addHeader("Access-Control-Allow-Credentials", "true");
            response.addHeader("Access-Control-Allow-Headers",
                    "Authorization, origin, content-type, accept, x-requested-with");

            filterChain.doFilter(request, response);
        }
    }

3. web.xml dosyasındaki istekler için yukarıdaki filtreyi uygulayın

    <filter>
        <filter-name>corsFilter</filter-name>
        <filter-class>com.your.package.CORSFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>corsFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

Umarım bu birisi için faydalıdır.


jackson-coreBir olan bağımlılık arasında jackson-databind, yani doğrudan eklemeye gerek.
Alex78191

1
CORS filtresini neden eklemek gerekiyor?
Alex78191

1

Spring Boot + Bahar MVN

sorunla

@PostMapping("/addDonation")
public String addDonation(@RequestBody DonatorDTO donatorDTO) {

çözüm ile

@RequestMapping(value = "/addDonation", method = RequestMethod.POST)
@ResponseBody
public GenericResponse addDonation(final DonatorDTO donatorDTO, final HttpServletRequest request){

0

Pom'ma jackson-json veri bağlama ekleyerek bu sorunu çözdüm.

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

0

Model Sınıfınıza bir json özelliği ek açıklaması ekleyin, ayrıca varsayılan bir yapıcıya sahip olun

@JsonProperty("user_name")
private String userName;

@JsonProperty("first_name")
private String firstName;

@JsonProperty("last_name")
private String lastName;

0

Aynı sorunu yaşadım. ekleme

<mvc:annotation-driven />
<mvc:default-servlet-handler />

ilkbahar-xml çözüldü


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.