programing

java.util 인스턴스를 역직렬화할 수 없습니다.ArrayList가 VALUE_STRING을 벗어남

muds 2023. 3. 2. 22:42
반응형

java.util 인스턴스를 역직렬화할 수 없습니다.ArrayList가 VALUE_STRING을 벗어남

Jersey에서 구축한 REST 서비스를 AppEngine에 도입하고 있습니다.REST 서비스는 Version PUT을 구현하고 있습니다.application/json미디어 타입데이터 바인딩은 Jackson에 의해 수행됩니다.

동사는 JSON에서 나타내는 엔터프라이즈 부문 관계를 다음과 같이 소비합니다.

{"name":"myEnterprise", "departments":["HR","IT","SC"]}

클라이언트 측에서는 gson을 사용하여 JSON 표현을 Java 객체로 변환합니다.그런 다음 REST 서비스에 객체를 전달하면 정상적으로 작동합니다.

문제:

JSON 표현에 컬렉션에 항목이 하나만 있는 경우

{"name":"myEnterprise", "departments":["HR"]}

서비스가 개체를 역직렬화할 수 없습니다.

ATTENTION: /enterprise/enterprise: org.codehaus.jackson.map.JsonMappingException: 
Can not deserialize instance of java.util.ArrayList out of VALUE_STRING token at 
[Source: org.mortbay.jetty.HttpParser$Input@5a9c5842; line: 1, column: 2

다른 사용자가 보고한 바와 같이 해결책은 플래그를 추가하는 것입니다.ACCEPT_SINGLE_VALUE_AS_ARRAY(예: Jersey: ArrayList 인스턴스를 문자열에서 역직렬화할없습니다).그럼에도 불구하고, 저는 이 시스템을ObjectMapper서비스 측면에서는 잭슨에 의해 투명하게 제작되기 때문입니다.

질문:.

를 설정하는 방법이 있습니까?ObjectMapper서비스측에서 유효하게 하기 위해서ACCEPT_SINGLE_VALUE_AS_ARRAY주석? web.xml?

코드상세부

Java 객체:

@XmlRootElement
public class Enterprise {
    private String name;
    private List<String> departments;

    public Enterprise() {}

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<String> getDepartments() {
        return departments;
    }
    public void setDepartments(List<String> departments) {
        this.departments = departments;
    }
}

REST 서비스 측면:

    @PUT
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    @Path("/enterprise") 
    public Response putEnterprise(Enterprise enterprise,
            @Context HttpServletRequest req){
         ...
    }

클라이언트 측:

...
String jsonString = "{\"name\":\"myEnterprise\", \"departments\":[\"HR\"]}";
Enterprise enterprise = gson.fromJson(jsonString, Enterprise.class);
System.out.println(gson.toJson(enterprise));
response = webResource              
           .type(MediaType.APPLICATION_JSON)
           .put(ClientResponse.class,enterprise);
if (response.getStatus() >= 400) {
        throw new RuntimeException("Failed : HTTP error code : " + response.getStatus());
}
...

이것이 저의 오래된 질문에 대한 해결책입니다.

나는 내 자신의 것을 구현ContextResolver를 유효하게 하기 위해서DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY특징.

package org.lig.hadas.services.mapper;

import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;

import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;

@Produces(MediaType.APPLICATION_JSON)
@Provider
public class ObjectMapperProvider implements ContextResolver<ObjectMapper>
{
   ObjectMapper mapper;

   public ObjectMapperProvider(){
       mapper = new ObjectMapper();
       mapper.configure(DeserializationConfig.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
   }
   @Override
   public ObjectMapper getContext(Class<?> type) {
       return mapper;
   }
}

그리고 그 안에web.xml패키지를 서블릿 정의에 등록했습니다...

<servlet>
    <servlet-name>...</servlet-name>
    <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>com.sun.jersey.config.property.packages</param-name>
        <param-value>...;org.lig.hadas.services.mapper</param-value>        
    </init-param>
    ...
</servlet>

...나머지들은 모두 저지나 트레이너에 의해 투명하게 처리됩니다.

이 속성을 ObjectMapper 인스턴스로 설정하면 동작합니다.

objectMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);

노력하세요

[{"name":"myEnterprise", "departments":["HR"]}]

각 괄호가 포인트입니다.

Jackson 2.7.x+에서 멤버 변수 자체에 주석을 다는 방법이 있습니다.

 @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
 private List<String> newsletters;

자세한 내용은 이쪽: Jackson @JsonFormat

에러 메시지를 검색하여 이 질문을 찾은 사용자는 에러 메시지를 잘못 입력한 경우에도 이 오류를 볼 수 있습니다.@JsonProperty주석을 달기 위한 주석List단일 값 필드의 이름을 가진 -syslog 속성:

@JsonProperty("someSingleValuedField") // Oops, should have been "someMultiValuedField"
public List<String> getMyField() { // deserialization fails - single value into List
  return myField;
}

언급URL : https://stackoverflow.com/questions/14588727/can-not-deserialize-instance-of-java-util-arraylist-out-of-value-string

반응형