POST JSON gagal dengan 415 jenis media yang tidak didukung, Spring 3 mvc

171

Saya mencoba mengirim permintaan POST ke servlet. Permintaan dikirim melalui jQuery dengan cara ini:

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

di mana kategori baru

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

dan postJSON adalah

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

Dengan pembakar saya melihat bahwa JSON dikirim dengan benar:

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

Tapi saya mendapatkan 415 jenis media yang tidak didukung. Pengontrol pegas mvc memiliki tanda tangan

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

Beberapa hari yang lalu itu berhasil, sekarang tidak. Saya akan menunjukkan lebih banyak kode jika diperlukan. Terima kasih

gc5
sumber
Apa yang telah Anda ubah sejak beberapa hari yang lalu? Juga, tidakkah var productCategory = { idProductCategory: 1, description: "Descrizione2" };akan lebih ringkas dan lebih mudah dibaca? Apakah Anda perlu memberi tahu Spring untuk menerima application/jsonsecara khusus? Dengan kata lain, apakah itu mengharapkan data datang dalam bentuk?
Dave Newton
Banyak hal sejak saya mengerjakan bagian lain dari proyek ini, dan hari ini saya menemukan regresi ini. Di bagian ini saya tidak mengubah apa pun. Ya, saya harus menggunakan cara ini karena saya mendapat masukan dari formulir.
gc5
Tidak, Anda tidak mendapatkannya dari pos JSON Ajax, yang tidak sama dengan formulir data yang disandikan.
Dave Newton
1
Apakah Anda yakin Jackson masih tersedia di CLASSPATH Anda?
Tomasz Nurkiewicz
1
jika Anda mengirim teks / json alih-alih aplikasi / json u mendapatkan kesalahan yang sama
Blacksonic

Jawaban:

250

Saya pernah mengalami ini sebelumnya dengan Spring @ResponseBody dan itu karena tidak ada tajuk terima yang dikirim dengan permintaan. Terima header dapat menjadi rasa sakit untuk set dengan jQuery, tapi ini bekerja untuk saya sumber

$.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
    });
};

Header Jenis-Konten digunakan oleh @RequestBody untuk menentukan format data yang dikirim dari klien dalam permintaan. Header accept digunakan oleh @ResponseBody untuk menentukan format apa yang mengirim data kembali ke klien dalam respons. Itu sebabnya Anda membutuhkan kedua header.

theon
sumber
1
header: {...} dan JSON.stringify (...) selalu membuat saya tersandung.
Tim Perry
1
Tidak tahu mengapa ini tidak lebih banyak didokumentasikan. Masalah ini membuat saya membuang banyak waktu. Terima kasih banyak!
Hugo Nava Kopp
Saya berharap Spring memang mendukung data formulir secara default, tetapi tidak. Jadi, terima kasih atas solusi (sekarang agak lama).
RiZKiT
Saya menggunakan tukang pos untuk membuat permintaan put, baru saja menambahkan tipe konten: '' application / json ". Terima kasih
Janatbek Sharsheyev
21

menambahkan jenis konten ke dalam permintaan saat application/jsonmenyelesaikan masalah

uiroshan
sumber
18

Saya memiliki masalah yang sama tetapi menemukan masalah adalah bahwa saya telah lalai untuk menyediakan konstruktor default untuk DTO yang dijelaskan dengan @RequestBody.

John Shepherd
sumber
1
hal yang sama terjadi pada saya. Saya punya 2 metode dengan nama yang sama dan mendapatkan 415. Terima kasih!
Daniel Vilas-Boas
12

Saya yakin saya mengalami masalah yang sama persis. Setelah berjam-jam berkelahi dengan JSON, JavaScript dan Server, saya menemukan pelakunya: Dalam kasus saya, saya memiliki objek Date di DTO, objek Date ini dikonversi ke String sehingga kami dapat menampilkannya dalam tampilan dengan format: HH: mm.

Ketika informasi JSON dikirim kembali, objek Date String ini harus dikonversi kembali menjadi Object Date lengkap, oleh karena itu kita juga memerlukan metode untuk mengaturnya di DTO. NAMUN besar adalah Anda tidak dapat memiliki 2 metode dengan nama yang sama (Kelebihan) di DTO bahkan jika mereka memiliki jenis parameter yang berbeda (String vs Tanggal) karena ini akan memberi Anda juga 415 jenis kesalahan Media yang Tidak Didukung.

Ini adalah metode pengontrol saya

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

Ini adalah contoh DTO saya (id get / set dan Metode preAlarm get tidak termasuk untuk kekurangan kode):

@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;
    }
  }
}

Untuk membuat semuanya berfungsi, Anda perlu menghapus metode dengan parameter tipe tanggal. Kesalahan ini sangat membuat frustrasi. Semoga ini bisa menghemat waktu berjam-jam dari seseorang.

will824
sumber
Terima kasih - atau Anda bisa mengganti nama salah satu setter. Saya memiliki keduanya public void setParameters(List<Parameter> parameters)& public void setParameters(Parameter... parameters)metode dalam kacang, mengubah yang terakhir untuk addParametersmenyelesaikan masalah bagi saya.
Conor Svensson
Bukankah masalah bahwa tubuh adalah this.preAlarm == date daripada this.preAlarm = date?
Michael mengembalikan Monica Cellio
12

Saya menghadapi masalah yang sama dan ini adalah bagaimana saya memperbaikinya,

Masalahnya adalah karena proses konversi dari JSON ke Jawa, orang perlu memiliki perpustakaan jackson waktu berjalan yang tepat agar konversi terjadi dengan benar.

Tambahkan toples berikut (melalui dependensi atau dengan mengunduh dan menambahkan ke classpath.

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

Ini harus memperbaiki masalah.

Kode Lengkap:

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);
}

dan tanda tangan controller terlihat seperti ini:

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

Semoga ini membantu

vinSan
sumber
Hanya jackson-databinddiperlukan.
Alex78191
8

Saya menghadapi masalah ini ketika saya mengintegrasikan spring boot dengan spring mvc. Saya menyelesaikannya dengan hanya menambahkan dependensi ini.

<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>
dalam
sumber
5

Catatan kecil - menemukan kesalahan yang sama saat mengembangkan aplikasi web. Kesalahan yang kami temukan, dengan bermain-main dengan layanan dengan Poster Firefox, adalah bahwa kedua bidang dan nilai di Json harus dikelilingi oleh tanda kutip ganda. Misalnya..

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

Dalam kasus kami, kami mengisi json melalui javascript, yang bisa sedikit membingungkan ketika berurusan dengan penawaran tunggal / ganda, dari apa yang saya dengar.

Apa yang dikatakan sebelumnya dalam posting ini dan lainnya, seperti termasuk header 'Terima' dan 'Tipe-Konten', juga berlaku.

Semoga tidak.

Carlos Romero
sumber
3

Saya berhasil membuatnya bekerja. Katakan kalau-kalau saya salah. Saya hanya menggunakan satu cara untuk membuat cerita bersambung / deserialize: Saya menghapus semua anotasi mengenai hal ini ( @JSONSerializedan @JSONDeserialize) dan mendaftarkan Serializers dan Deserializer di CustomObjectMapperkelas. Saya tidak menemukan artikel yang menjelaskan perilaku ini tetapi saya memutuskan dengan cara ini. Semoga bermanfaat.

gc5
sumber
Terjadi sama bagi saya! Adakah penjelasan mengapa itu terjadi?
Whimusical
Bisakah Anda jelaskan metode Anda secara terperinci ??
Dipanshu Verma
1

Saya memiliki masalah yang sama. Saya harus mengikuti langkah-langkah ini untuk menyelesaikan masalah:

1. Pastikan Anda memiliki dependensi berikut:

    <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. Buat filter berikut:

    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. Terapkan filter di atas untuk permintaan di web.xml

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

Saya harap ini bermanfaat bagi seseorang.

Manoj Shrestha
sumber
jackson-coreadalah ketergantungan dari jackson-databind, jadi tidak perlu menambahkannya langsung.
Alex78191
1
Mengapa perlu menambahkan filter CORS?
Alex78191
1

Spring boot + spring mvn

dengan masalah

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

dengan solusi

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

Saya mengatasi masalah ini dengan menambahkan data jackson-json mengikat ke pom saya.

<dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.6.3</version>
</dependency>
Lingasamy Bagavathi
sumber
0

Di Kelas Model Anda menambahkan anotasi properti json, juga memiliki konstruktor default

@JsonProperty("user_name")
private String userName;

@JsonProperty("first_name")
private String firstName;

@JsonProperty("last_name")
private String lastName;
deko
sumber
0

Saya memiliki masalah yang sama. menambahkan

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

ke pegas-xml menyelesaikannya

OhadR
sumber