6

この JSON を取得しました: {"success":false}

これをこの POJO にデシリアライズしたい:

class Message {
    private Map<String, String> dataset = new HashMap<String, String>();

    @JsonProperty("success")
    public boolean isSuccess() {
        return Boolean.valueOf(dataset.get("success"));
    }

    @JsonProperty("success")
    public void setSuccess(boolean success) {
        dataset.put("success", String.valueOf(success));
    }
}

フィールドの成功なしで、この JSON をクラスに逆シリアル化することは可能ですか? これまでのところ、私は常に「UnrecognizedPropertyException: 認識されていないフィールド「成功」」を取得しています。

ご協力いただきありがとうございます!

4

3 に答える 3

6

@JsonAnySetterメソッドを実装して、次のように注釈を付けることができます。

@JsonAnySetter
public void handleUnknownProperties(String key, Object value) {
    // this will be invoked when property isn't known
}

別の可能性は、この失敗を次のようにオフにすることです。

objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);

これにより、プロパティが見つからない場合に失敗することなくJSONを逆シリアル化できます。

テスト


public static class Message {
    private final Map<String, String> dataset = new HashMap<String, String>();

    @Override
    public String toString() {
        return "Message [dataset=" + dataset + "]";
    }

}

@Test
public void testJackson() throws JsonParseException, JsonMappingException, IOException {
    String json = "{\"success\":false}";
    ObjectMapper om = new ObjectMapper().configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    System.out.println(om.readValue(json, Message.class));
}
于 2012-07-03T16:48:45.797 に答える
0

注: 私はEclipseLink JAXB (MOXy)のリーダーであり、JAXB (JSR-222)エキスパート グループのメンバーです。

Jackson で動作しない場合は、MOXy でこのユース ケースをサポートする方法を以下に示します。

メッセージ

Messageクラスに注釈は必要ありません。デフォルトでは、プロパティ アクセスが使用されます。を使用してフィールド アクセスを指定できます。 http://blog.bdoughan.com/2011/06/using-jaxbs-xmlaccessortype-to.html@XmlAccessorType(XmlAccessType.FIELD)を参照 してください。

package forum11315389;

import java.util.*;

class Message {
    private Map<String, String> dataset = new HashMap<String, String>();

    public boolean isSuccess() {
        return Boolean.valueOf(dataset.get("success"));
    }

    public void setSuccess(boolean success) {
        dataset.put("success", String.valueOf(success));
    }
}

jaxb.properties

MOXy を JAXB プロバイダーとして指定するにはjaxb.properties、次のエントリを使用して、ドメイン モデルと同じパッケージで呼び出されるファイルを含める必要があります。

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

デモ

package forum11315389;

import java.io.StringReader;
import java.util.*;
import javax.xml.bind.*;
import javax.xml.transform.stream.StreamSource;
import org.eclipse.persistence.jaxb.JAXBContextProperties;

public class Demo {

    public static void main(String[] args) throws Exception {
        Map<String,Object> properties = new HashMap<String,Object>(1);
        properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");
        properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);
        JAXBContext jc = JAXBContext.newInstance(new Class[] {Message.class}, properties);

        StreamSource json = new StreamSource(new StringReader("{\"success\":false}"));
        Unmarshaller unmarshaller = jc.createUnmarshaller();
        Message message = unmarshaller.unmarshal(json, Message.class).getValue();

        Marshaller marshaller = jc.createMarshaller();
        marshaller.marshal(message, System.out);
    }

}

入出力

{"success":false}
于 2012-07-03T20:39:51.837 に答える
0

質問がわかりません。Jackson は、元の質問で定義したメッセージ POJO の現在のバージョンとの間で (デ) シリアライズします。エラーも特別な構成もありません (@JsonProperty アノテーションを除く)。現在のメッセージ POJO には、success という名前のフィールドはありませんが、 success という名前のプロパティが定義されています。これが、Jackson が追加構成なしで JSON の例を喜んでマップする理由です。@JsonProperty アノテーションを削除しますか?

その場合は、そうすることができます.Jacksonは、他の構成を必要とせずに、同じサンプルJSONを使用してメッセージPOJOとの間で(逆)シリアル化を行います. JSON の要素名と一致する success という名前のプロパティ。

次の例は、これらの点を示しています。

元の質問で定義されているとおりのメッセージ POJO を使用した例 1:

import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonFoo
{
  public static void main(String[] args) throws Exception
  {
    // input: {"success":false}
    String inputJson = "{\"success\":false}";

    ObjectMapper mapper = new ObjectMapper();
    Message message = mapper.readValue(inputJson, Message.class);
    System.out.println(mapper.writeValueAsString(message));
    // output: {"success":false}
  }
}

class Message
{
  private Map<String, String> dataset = new HashMap<String, String>();

  @JsonProperty("success")
  public boolean isSuccess()
  {
    return Boolean.valueOf(dataset.get("success"));
  }

  @JsonProperty("success")
  public void setSuccess(boolean success)
  {
    dataset.put("success", String.valueOf(success));
  }
}

@JsonProperty アノテーションを削除するように Message POJO を変更した例 2。

import java.util.HashMap;
import java.util.Map;

import com.fasterxml.jackson.databind.ObjectMapper;

public class JacksonFoo
{
  public static void main(String[] args) throws Exception
  {
    // input: {"success":false}
    String inputJson = "{\"success\":false}";

    ObjectMapper mapper = new ObjectMapper();
    Message message = mapper.readValue(inputJson, Message.class);
    System.out.println(mapper.writeValueAsString(message));
    // output: {"success":false}
  }
}

class Message
{
  private Map<String, String> dataset = new HashMap<String, String>();

  public boolean isSuccess()
  {
    return Boolean.valueOf(dataset.get("success"));
  }

  public void setSuccess(boolean success)
  {
    dataset.put("success", String.valueOf(success));
  }
}

MessageWrapper の例:

public class JacksonFoo
{
  public static void main(String[] args) throws Exception
  {
    // input: {"success":false}
    String inputJson = "{\"success\":true}";

    ObjectMapper mapper = new ObjectMapper();
    MessageWrapper wrappedMessage = mapper.readValue(inputJson, MessageWrapper.class);
    System.out.println(mapper.writeValueAsString(wrappedMessage));
    // output: {"success":true}
  }
}

class MessageWrapper
{
  @JsonUnwrapped
  @JsonProperty // exposes non-public field for Jackson use
  Message message;
}
于 2012-07-04T01:06:36.780 に答える