POST JSON이 415 지원되지 않는 미디어 유형, Spring 3 mvc로 실패


171

POST 요청을 서블릿에 보내려고합니다. 요청은 다음과 같은 방식으로 jQuery를 통해 전송됩니다.

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

newCategory는 어디에

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

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를 사용하면 JSON이 올바르게 전송됩니다.

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

그러나 415 개의 지원되지 않는 미디어 유형이 표시됩니다. Spring MVC 컨트롤러에는 서명이 있습니다

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

며칠 전에 작동했지만 지금은 그렇지 않습니다. 필요한 경우 더 많은 코드를 보여줄 것입니다. 감사


며칠 전부터 무엇이 바뀌 었습니까? 또한 var productCategory = { idProductCategory: 1, description: "Descrizione2" };더 간결하고 읽기 쉽지 않습니까? Spring에 application/json구체적 으로 동의 하도록 지시해야 합니까? 즉, 데이터가 형식으로 제공 될 것으로 예상됩니까?
Dave Newton

이 프로젝트의 다른 부분에서 작업 한 이후 많은 것들이 있었으며 오늘 저는이 회귀를 발견했습니다. 이 부분에서 나는 아무것도 바꾸지 않았다. 예, 양식에서 입력을 받기 때문에이 방법을 사용해야합니다.
gc5

아니요, 양식 인코딩 데이터와 동일하지 않은 JSON Ajax 게시물에서 가져 오는 것은 아닙니다.
Dave Newton

1
CLASSPATH에서 Jackson을 계속 사용할 수 있습니까?
Tomasz Nurkiewicz

1
응용 프로그램 / json 대신 텍스트 / json을 보내면 동일한 오류가 발생합니다.
Blacksonic

답변:


249

Spring @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는 Content-Type 헤더를 사용하여 요청에서 클라이언트로부터 전송되는 데이터의 형식을 결정합니다. @ResponseBody는 accept 헤더를 사용하여 응답에서 클라이언트로 데이터를 다시 보낼 형식을 결정합니다. 이것이 두 헤더가 모두 필요한 이유입니다.


1
헤더 : {...} 및 JSON.stringify (...)는 항상 저를 트립합니다.
Tim Perry 1

1
왜 이것이 더 문서화되어 있지 않은지 모르겠습니다. 이 문제로 인해 많은 시간을 낭비하게되었습니다. 대단히 감사합니다!
Hugo Nava Kopp

Spring은 기본적으로 양식 데이터를 지원하지만 예상하지는 않습니다. 따라서 (현재는 오래된) 솔루션에 감사드립니다.
RiZKiT

. ''응용 프로그램 / JSON을 "감사 : 나는 풋 요청, 방금 추가 콘텐츠 형식을 만들기 위해 우체부를 사용했다
Janatbek Sharsheyev

21

application/json문제가 해결 된 대로 요청에 컨텐츠 유형 추가


18

비슷한 문제가 있었지만 문제는 @RequestBody로 주석이 달린 DTO에 대한 기본 생성자를 제공하지 않았 음을 발견했습니다.


나에게도 같은 일이 일어났다. 나는 같은 이름을 가진 두 가지 방법을 가지고 있었고 415를 얻었습니다. 감사합니다!
Daniel Vilas-Boas

12

나는 똑같은 문제에 부딪쳤다 고 생각합니다. JSON, JavaScript 및 서버와 수없이 많은 시간을 보낸 후에 범인을 발견했습니다. 제 경우에는 DTO에 Date 객체가 있었 으므로이 Date 객체는 String으로 변환되어 형식 : HH : mm.

JSON 정보가 다시 전송 될 때이 Date String 개체를 전체 날짜 개체로 다시 변환해야했기 때문에 DTO에서이를 설정하는 방법도 필요합니다. 큰 BUT는 다른 유형의 매개 변수 (문자열 대 날짜)가 있더라도 DTO에서 동일한 이름 (과부하)을 가진 두 가지 메소드를 가질 수 없다는 것입니다.

이것은 내 컨트롤러 방법이었습니다

  @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 메소드는 코드 부족에 포함되지 않음).

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

모든 것이 작동하게하려면 Date type 매개 변수를 사용하여 메소드를 제거해야합니다. 이 오류는 매우 실망 스럽습니다. 이것이 누군가의 디버깅 시간을 절약 할 수 있기를 바랍니다.


고마워-또는 세터 중 하나의 이름을 바꿀 수 있습니다. 나는 콩에 public void setParameters(List<Parameter> parameters)& public void setParameters(Parameter... parameters)메소드를 모두 가지고 있었고 , 후자를 변경하여 addParameters나를 위해 문제 를 해결했습니다.
코너 스벤손

본문이 this.preAlarm = date이 아니라 this.preAlarm == date 문제입니까?
마이클 복원 모니카 Cellio

12

나는 비슷한 문제에 직면했고 이것이 내가 고친 방법입니다.

문제는 JSON에서 Java 로의 변환 프로세스로 인해 변환이 올바르게 수행 되려면 올바른 런타임 잭슨 라이브러리가 필요하다는 것입니다.

종속성을 통해 또는 클래스 경로에 다운로드하여 추가하여 다음 jar을 추가하십시오.

<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필요합니다.
Alex78191

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

작은 참고 사항-웹 응용 프로그램을 개발하는 동안 이와 동일한 오류가 발생했습니다. 우리가 발견 한 실수는 Firefox Poster로 서비스를 통해 Json의 필드와 값을 큰 따옴표로 묶어야한다는 것입니다. 예를 들어 ..

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

우리의 경우에 우리는 자바 스크립트를 통해 json을 채웠다. 이것은 내가 들었던 것으로부터 작은 / 큰 따옴표를 다룰 때 약간 혼란 스러울 수있다.

'Accept'및 'Content-Type'헤더를 포함하여이 게시물 및 기타 게시물에서 이전에 언급 한 내용도 적용됩니다.

희망 t'helps.


3

나는 그것을 작동시키는 방법을 관리했다. 내가 틀렸다면 말해줘. 직렬화 / 직렬화 해제하는 한 가지 방법 만 사용했습니다.이 ( @JSONSerialize@JSONDeserialize) 에 관한 모든 주석을 제거 하고 CustomObjectMapper클래스에 직렬화 기 및 직렬화기를 등록했습니다 . 이 동작을 설명하는 기사를 찾지 못했지만 이런 식으로 해결되었습니다. 유용하기를 바랍니다.


나에게도 똑같다! 왜 그런 일이 발생했는지 설명해 주시겠습니까?
Whimusical

방법을 자세히 설명해 주시겠습니까?
Dipanshu Verma 2016

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-coreA는 종속jackson-databind, 그래서 바로 추가 할 필요가.
Alex78191

1
CORS 필터를 추가해야하는 이유는 무엇입니까?
Alex78191

1

스프링 부트 + 스프링 MTN

문제가있는

@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

내 pom에 jackson-json 데이터 바인딩을 추가 하여이 문제를 해결했습니다.

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

spring-xml에 해결했습니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.