POST JSON 415 असमर्थित मीडिया प्रकार, स्प्रिंग 3 mvc के साथ विफल हो जाता है


171

मैं एक सर्वलेट के लिए एक पोस्ट अनुरोध भेजने की कोशिश कर रहा हूं। अनुरोध इस तरह से jQuery के माध्यम से भेजा जाता है:

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

जहाँ नया श्रेणी है

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

और पोस्टजन्स है

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

फायरबग के साथ मैं देख रहा हूं कि JSON को सही तरीके से भेजा गया है:

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

लेकिन मुझे 415 असमर्थित मीडिया प्रकार मिलते हैं। स्प्रिंग mvc नियंत्रक पर हस्ताक्षर हैं

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

कुछ दिन पहले यह काम किया था, अब यह नहीं है। जरूरत पड़ने पर और कोड दिखाऊंगा। धन्यवाद


कुछ दिनों पहले आपने क्या बदला है? इसके अलावा, var productCategory = { idProductCategory: 1, description: "Descrizione2" };अधिक संक्षिप्त और पढ़ने में आसान नहीं होगा ? क्या आपको application/jsonविशेष रूप से स्वीकार करने के लिए स्प्रिंग को बताने की आवश्यकता है ? दूसरे शब्दों में, क्या यह डेटा को एक रूप में आने की उम्मीद कर रहा है?
डेव न्यूटन

जब से मैं इस परियोजना के अन्य भाग पर काम कर रहा था, और आज मुझे यह प्रतिगमन मिला है। इस हिस्से में मैंने कुछ भी नहीं बदला। हां, मुझे इस तरह से उपयोग करना होगा क्योंकि मुझे एक फॉर्म से इनपुट मिल रहा है।
gc5

नहीं, आप ऐसा नहीं कर रहे हैं, आप इसे JSON Ajax पोस्ट से प्राप्त कर रहे हैं, जो डेटा एन्कोडेड डेटा के समान नहीं है।
डेव न्यूटन

1
क्या आप सुनिश्चित हैं कि जैक्सन अभी भी आपके CLASSPATH पर उपलब्ध है?
टॉमाज़ नर्कविक्ज़ जूल 15'12

1
अगर u एप्लिकेशन / json के बजाय टेक्स्ट / json भेजें तो वही त्रुटि मिलती है
Blacksonic

जवाबों:


249

मैंने स्प्रिंग @ResponseBody के साथ ऐसा पहले भी किया है और यह इसलिए था क्योंकि अनुरोध के साथ कोई हेडर नहीं भेजा गया था। हेडर स्वीकार करें jQuery के साथ सेट करने के लिए एक दर्द हो सकता है, लेकिन यह मेरे लिए स्रोत का काम करता है

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

अनुरोध में क्लाइंट से भेजा जा रहा डेटा किस प्रारूप में है, यह निर्धारित करने के लिए @RequestBody द्वारा सामग्री-प्रकार हेडर का उपयोग किया जाता है। प्रतिक्रिया में क्लाइंट के लिए डेटा को किस प्रारूप में भेजा जाए, यह निर्धारित करने के लिए @ResponseBody द्वारा स्वीकार शीर्षक का उपयोग किया जाता है। इसलिए आपको दोनों शीर्षकों की आवश्यकता है।


1
हेडर: {...} और JSON.stringify (...) हमेशा मुझे यात्रा करते हैं।
टिम पेरी

1
पता नहीं क्यों यह अधिक प्रलेखित नहीं है। इस समस्या ने मुझे इतना समय बर्बाद कर दिया। आपका बहुत बहुत धन्यवाद!
ह्यूगो नवा कोप्प

मुझे उम्मीद है कि स्प्रिंग डिफ़ॉल्ट रूप से डेटा का समर्थन करता है, लेकिन यह नहीं करता है। तो, (अब पुराने) समाधान के लिए धन्यवाद।
RiZKiT

मैं एक पुट लगाने के लिए एक पोस्टमैन का उपयोग कर रहा था, बस कंटेंट-टाइप जोड़ा: '' एप्लीकेशन /
जसन

21

application/jsonसमस्या को हल करने के रूप में अनुरोध में सामग्री प्रकार जोड़ना


18

मुझे भी इसी तरह की समस्या थी लेकिन यह मुद्दा मिला कि मैंने डीटीओ के लिए एक डिफ़ॉल्ट कंस्ट्रक्टर प्रदान करने की उपेक्षा की थी जिसे @RequestBody के साथ एनोटेट किया गया था।


वही चीज़ मेरे साथ हुई। मेरे पास एक ही नाम की 2 विधियाँ थीं और 415 मिल रही थीं। धन्यवाद!
डैनियल विलास-बोस

12

मेरा मानना ​​है कि मैं ठीक इसी मुद्दे पर भाग गया। JSON, जावास्क्रिप्ट और सर्वर के साथ लड़ने के अनगिनत घंटों के बाद, मुझे दोषी पाया गया: मेरे मामले में मुझे DTO में एक दिनांक ऑब्जेक्ट मिला था, यह दिनांक ऑब्जेक्ट स्ट्रिंग में परिवर्तित हो गया था, इसलिए हम इसे दृश्य में दिखा सकते हैं प्रारूप: एचएच: मिमी।

जब JSON की जानकारी वापस भेजी जा रही थी, तो इस Date String ऑब्जेक्ट को पूरी Date Object में वापस बदलना पड़ा, इसलिए हमें इसे DTO में सेट करने के लिए एक विधि की भी आवश्यकता है। बड़ी बात यह है कि डीटीओ में एक ही नाम (अधिभार) के साथ आपके पास 2 विधियाँ नहीं हो सकती हैं, भले ही उनके पास अलग-अलग प्रकार के पैरामीटर (स्ट्रिंग बनाम तिथि) हो क्योंकि इससे आपको 415 असमर्थित मीडिया प्रकार की त्रुटि भी मिलेगी।

यह मेरी नियंत्रक विधि थी

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

यह मेरा DTO उदाहरण था (id get / set और preAlarm get Methods कोड की कमी के लिए शामिल नहीं हैं):

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

सब कुछ काम करने के लिए आपको तिथि प्रकार पैरामीटर के साथ विधि को निकालने की आवश्यकता है। यह त्रुटि बहुत निराशाजनक है। आशा है कि यह डिबगिंग के किसी भी घंटे को बचा सकता है।


धन्यवाद - या आप बसने वालों में से एक का नाम बदल सकते हैं। मेरे पास एक सेम में दोनों public void setParameters(List<Parameter> parameters)और public void setParameters(Parameter... parameters)विधियां थीं, addParametersमेरे लिए इस मुद्दे को हल करने के लिए बाद को बदल दिया।
कॉनर स्वेन्सन

क्या समस्या यह नहीं है कि शरीर यह है। एपरल == दिनांक इसके बजाय। एपरम = तिथि?
माइकल ने मोनिका सेलियो

12

मुझे एक समान समस्या का सामना करना पड़ा और मैंने इसे कैसे तय किया,

समस्या JSON से जावा में रूपांतरण प्रक्रिया के कारण है, किसी को रूपांतरण सही ढंग से होने के लिए सही रन टाइम जैकसन लाइब्रेरी की आवश्यकता है।

निम्न जार जोड़ें (निर्भरता के माध्यम से या डाउनलोड करने और क्लासपाथ में जोड़कर।

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

इससे समस्या हल हो जानी चाहिए।

पूरा कोड:

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

और नियंत्रक हस्ताक्षर इस तरह दिखता है:

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

उम्मीद है की यह मदद करेगा


केवल jackson-databindआवश्यकता है।
एलेक्स78191

8

जब मैंने स्प्रिंग mvc के साथ स्प्रिंग बूट को एकीकृत किया तो मुझे इस मुद्दे का सामना करना पड़ा। मैंने केवल इन निर्भरताओं को जोड़कर इसे हल किया।

<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

एक छोटा सा पक्ष नोट - एक वेब अनुप्रयोग विकसित करते समय इसी त्रुटि पर ठोकर खाई। फ़ायरफ़ॉक्स पोस्टर के साथ सेवा करके, जो गलती हमें मिली, वह यह थी कि जोंस के क्षेत्र और मूल्य दोनों को दोहरे उद्धरण चिह्नों से घिरा होना चाहिए। उदाहरण के लिए..

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

हमारे मामले में हमने जावास्क्रिप्ट को जावास्क्रिप्ट के माध्यम से भर दिया, जो कि मैंने जो सुना है, उससे सिंगल / डबल कोट्स के साथ व्यवहार करने पर थोड़ा भ्रमित हो सकता है।

इससे पहले जो कुछ कहा गया है, वह 'स्वीकार' और 'सामग्री-प्रकार' शीर्षकों सहित अन्य पदों पर भी लागू होता है।

आशा है कि t'helps


3

मैंने यह प्रबंधित किया कि यह कैसे काम करता है। मुझे बताएं कि मैं गलत हूं। मैंने धारावाहिक / वर्णन करने के लिए केवल एक ही तरीके का उपयोग किया: मैंने इस ( @JSONSerializeऔर @JSONDeserialize) के बारे में सभी एनोटेशन को हटा दिया और CustomObjectMapperवर्ग में सीरियल और डिसेरिएलाइज़र पंजीकृत किए । मुझे इस व्यवहार की व्याख्या करने वाला कोई लेख नहीं मिला लेकिन मैंने इस तरह से हल किया। आशा है कि यह उपयोगी है।


मेरे लिए वही होता है! कोई स्पष्टीकरण क्यों ऐसा होता है?
मूलांक

क्या आप कृपया अपनी विधि के बारे में विस्तार से बता सकते हैं ??
दीपांशु वर्मा

1

मुझे भी यही समस्या थी। मुझे समस्या को हल करने के लिए इन चरणों का पालन करना था:

1. सुनिश्चित करें कि आपके पास निम्नलिखित निर्भरताएँ हैं:

    <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. निम्नलिखित फ़िल्टर बनाएं:

    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 में अनुरोधों के लिए उपरोक्त फ़िल्टर लागू करें

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

मुझे उम्मीद है कि यह किसी के लिए उपयोगी है।


jackson-coreकी निर्भरता है jackson-databind, इसलिए इसे सीधे जोड़ने की आवश्यकता नहीं है।
एलेक्स78 191 जुआन

1
कॉर्स फ़िल्टर को जोड़ना क्यों आवश्यक है?
एलेक्स। Alex१

1

वसंत बूट + वसंत mvn

मुद्दे के साथ

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

समाधान के साथ

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

0

मैंने जैकसन-जोंस डेटा बाइंडिंग को अपने पोम से जोड़कर इस मुद्दे को हल किया।

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

0

अपने मॉडल वर्ग में एक json गुण एनोटेशन जोड़ें, जिसमें एक डिफ़ॉल्ट निर्माता भी है

@JsonProperty("user_name")
private String userName;

@JsonProperty("first_name")
private String firstName;

@JsonProperty("last_name")
private String lastName;

0

मेरी भी यही समस्या थी। जोड़ने

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

वसंत-एक्सएमएल ने इसे हल किया


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.