programing

Spring Rest POST Json RequestBody 컨텐츠 유형이 지원되지 않습니다.

showcode 2023. 3. 11. 09:40
반응형

Spring Rest POST Json RequestBody 컨텐츠 유형이 지원되지 않습니다.

포스트 방식으로 새로운 오브젝트를 올리려고 할 때.RequestBody에서 contentType을 인식할 수 없습니다.스프링은 이미 설정되어 있어 POST는 다른 오브젝트에서는 동작할 수 있지만 이 오브젝트에서는 동작하지 않습니다.

org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json;charset=UTF-8' not supported

같은 요청을 시도하면 requestbody 객체를 변경합니다.그건 효과가 있다.

해결책을 찾았습니다.이름은 같지만 종류가 다른 세터가 두 대 있었기 때문입니다.

클래스에는 id 속성이 있어 오브젝트를 휴지 상태로 만들 때 Integer로 대체했습니다.

하지만 세터를 떼어내는 것을 잊은 것 같아서, 다음과 같은 일이 있었습니다.

/**
 * @param id
 *            the id to set
 */
public void setId(int id) {
    this.id = id;
}

/**
 * @param id
 *            the id to set
 */
public void setId(Integer id) {
    this.id = id;
}

이 세터를 제거했을 때, rest resquest는 매우 잘 작동합니다.

interad를 사용하면 비마셜링 오류를 발생시키거나 클래스 오류를 반영할 수 있습니다.예외 Http Media Type Not Supported여기 예외는 정말 이상하다.

이 스택 오버플로우가 다른 사람에게 도움이 되었으면 합니다.

사이드 노트

스프링 서버 콘솔에서 다음 오류 메시지를 확인할 수 있습니다.

유형 [simple type, class your.package]에 대한 잭슨 직렬화를 평가하지 못했습니다.ClassName] : com.fasterxml.jackson.databind.Json Mapping Exception:속성 "propertyname"에 대한 setter 정의가 충돌합니다.

그러면 위의 문제를 처리하고 있음을 확인할 수 있습니다.

또한 POST에서 전송되지 않은 파라미터의 속성(컨스트럭터에서 선언되지 않은 경우 이벤트)에 대해 getters 및 setters를 선언한 경우에도 주의해 주십시오.다음은 예를 제시하겠습니다.

@RestController
public class TestController {

    @RequestMapping(value = "/test", method = RequestMethod.POST)
    public String test(@RequestBody BeanTest beanTest) {
        return "Hello " + beanTest.getName();
    }


    public static class BeanTest {

        private Long id;
        private String name;

        public BeanTest() {
        }

        public BeanTest(Long id) {
            this.id = id;
        }

        public Long getId() {
            return id;
        }

        public void setId(Long id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}

다음 구조가 {"id":"1"}인 게시 요청은 작동하지 않습니다. 이름 get 및 설정을 삭제해야 합니다.

lombok을 사용하는 경우 @JsonDeserialize의 이름을 잘못 지정하면 다음과 같은 오류가 발생할 수 있습니다.

@Value
@Builder(toBuilder = true)
@JsonDeserialize(builder = SomeClass.SomeOtherClassBuilder.class)
public class SomeClass {
    ...
    public static class SomeOtherClassBuilder {
        ...
    }
}

다음 중 하나여야 합니다.

@Value
@Builder(toBuilder = true)
@JsonDeserialize(builder = SomeClass.SomeClassBuilder.class)
public class SomeClass {
    ...
    public static class SomeClassBuilder {
        ...
    }
}

클래스 이름을 리팩터링하고 빌더를 잊으면 매우 쉽게 그렇게 할 수 있습니다.그 후, 에러의 원인을 검색하면서, 지극히 도움이 되지 않는 예외 메세지만 표시해 두면, 몇시간이고 기뻐할 수 있습니다.

정말! 4시간 동안 미친 디버깅을 한 후 com.fasterxml.jackson.databind.deser에서 매우 이상한 코드를 발견했습니다.디시리얼라이저 캐시

if (deser == null) {
    try {
        deser = _createAndCacheValueDeserializer(ctxt, factory, type);
    } catch (Exception e) {
        return false;
    }
}

그래, 문제는 더블 세터였어.

Enum과 String이 있는 세터 2개를 사용했을 때도 같은 문제가 있었습니다.나는 잭슨에게 시리얼라이제이션 중에 어떤 세터 방식을 사용해야 하는지 알려주는 @JsonSetter 주석을 사용해야만 했다.이것으로 내 문제는 해결되었다.

게시된 값을 스스로 역직렬화함으로써 해결한 것과 같은 문제를 만났습니다.

@RequestMapping(value = "/arduinos/commands/{idArduino}", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public String sendCommandesJson(@PathVariable("idArduino") String idArduino, HttpServletRequest request) throws IOException {
    // getting the posted value
    String body = CharStreams.toString(request.getReader());
    List<ArduinoCommand> commandes = new ObjectMapper().readValue(body, new TypeReference<List<ArduinoCommand>>() {
    });

gradle 의존관계를 설정합니다.

  compile('org.springframework.boot:spring-boot-starter-web')
  compile('com.google.guava:guava:16.0.1')

제 경우 Constructor가 두 개 있었는데 같은 오류가 발생했습니다.그 중 하나를 방금 삭제했는데 문제가 해결되었습니다!

그래서 저도 비슷한 문제가 있었습니다. 어떤 건설업자가 과부하 상태였거든요.이 콩에는 옵션 속성도 있습니다.

이 문제를 해결하기 위해 과부하된 컨스트럭터를 제거했더니 작동했습니다.

예:

public class Bean{

Optional<String> string;
Optional<AnotherClass> object;

public Bean(Optional<String> str, Optional<AnotherClass> obj){
string = str;
object = obj;
}

///The problem was below constructor

public Bean(Optional<String> str){
string = str;
object = Optional.empty();
}



}

}

오래된 실처럼 보이지만, 누군가 여전히 힘들어할 경우를 대비해서 티바우 말대로 해결했어요.

2개의 세터 POJO 클래스는 피하세요.특정 속성을 위해 2개의 세터를 가지고 있었습니다.첫 번째 세터는 일반 세터에 있었고, 다른 하나는 컨스트럭터에서 1개를 제거한 후 언더 컨스트럭터에 있었습니다.

다음과 같이 엔티티 클래스 컨스트럭터에서 @JsonProperty를 지정합니다.

......
......
......

 @JsonCreator
 public Location(@JsonProperty("sl_no") Long sl_no, 
          @JsonProperty("location")String location,
          @JsonProperty("location_type") String 
          location_type,@JsonProperty("store_sl_no")Long store_sl_no) {
  this.sl_no = sl_no;
  this.location = location;
  this.location_type = location_type;
  this.store_sl_no = store_sl_no;
 } 
.......
.......
.......

이것을 외국 열쇠로 사용했을 때도 같은 문제가 있었습니다.

@JsonBackReference
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.DETACH},fetch = FetchType.EAGER)
@JoinColumn(name = "user_id")
private User user;

그리고 나는 제거했다.@JsonBackReference주석입니다.그 후, 상기의 문제는 수정되었습니다.

같은 속성에 2개의 getter가 있는 경우 디시리얼라이저는 실패합니다Refer Link

잭슨 의존 관계를 추가하려고 하다

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

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.9.3</version>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.3</version>
        <exclusions>
            <exclusion>
                <artifactId>jackson-annotations</artifactId>
                <groupId>com.fasterxml.jackson.core</groupId>
            </exclusion>
        </exclusions>
    </dependency>

저도 같은 문제가 있었어요.기본 생성자가 없는 사용자 지정 역직렬화기를 사용한 것이 근본 원인입니다.

java 9+ 모듈을 사용할 때 이 문제가 있었습니다.어쩔 수 없이open를 위한 모듈com.fasterxml.jackson.databind반사된 물체에 접근할 수 있습니다.또는 모델이 있는 경우에만 패키지를 열 수 있습니다.

컨트롤러의 기능에는 다음과 같은 주석이 붙어 있습니다.

 @PatchMapping(path = "/{machineGroupName}", consumes = "application/json-patch+json")

"Consumes" 파라미터를 삭제하면 동작합니다.

요청 헤더 추가 중

콘텐츠 유형: 응용 프로그램/json

날 위해 일했어

언급URL : https://stackoverflow.com/questions/19444855/spring-rest-post-json-requestbody-content-type-not-supported

반응형