2014-02-14 64 views

回答

1

我沒有找到任何的例子,但你可以嘗試創建像發電機:

StringWriter stringJson = new StringWriter(); 
JsonGenerator generator = new JsonFactory().createGenerator(stringJson); 

,你可以得到一個SerializerProvider實例與

new ObjectMapper().getSerializerProvider(); 
2

我找到了一種方法來單元測試Deserializers,是相當麻煩弄清楚。看看我的回購https://bitbucket.org/arbeitsgruppedenktmit/de.denktmit.rest.hal

單元測試類是在這裏: de.denktmit.rest.hal/src目錄/測試/ JAVA /德/ denktmit/REST/HAL /傑克遜/ RelationDeserializerTest.java

集成測試,在測試範圍內的解串器可以在這裏找到: de.denktmit.rest.hal/src目錄/測試/ JAVA /德/ denktmit/REST/HAL/OrderResourceIntegrationTest.java

編輯因發表評論 基類設置簡易單元測試映射器

public abstract class AbstractJackson2MarshallingTest { 

    protected ObjectMapper mapper; 

    @Before 
    public void setUp() { 
     mapper = new ObjectMapper(); 
     mapper.enable(SerializationFeature.INDENT_OUTPUT); 
    } 

    protected String write(Object object) throws Exception { 
     Writer writer = new StringWriter(); 
     mapper.writeValue(writer, object); 
     return writer.toString(); 
    } 

    protected <T> T read(String source, Class<T> targetType) throws Exception { 
     return mapper.readValue(source, targetType); 
    } 

    protected String getPackagePath() { 
     return "/" + this.getClass().getPackage().getName().replace('.', '/'); 
    } 
} 

含有單元測試類測試

public class RelationDeserializerTest extends AbstractJackson2MarshallingIntegrationTest { 

    @Rule public ResourceFile resourceFile = new ResourceFile(getPackagePath() + "/single_valued_relation.json"); 
    @Rule public ResourceFile resourceFile2 = new ResourceFile(getPackagePath() + "/multi_valued_relation.json"); 

    private RelationDeserializer deserializer = new RelationDeserializer(); 

    @Test 
    public void testDeserializeSingleValuedRelation() throws IOException { 
     resourceFile = new ResourceFile(getPackagePath() + "/single_valued_relation.json"); 
     JsonParser parser = mapper.getFactory().createParser(resourceFile.getContent()); 
     DeserializationContext ctxt = mapper.getDeserializationContext(); 
     SingleValuedRelation rel = (SingleValuedRelation) deserializer.deserialize(parser, ctxt); 
     assertEquals(rel.getName(), "invoiceAddress"); 
     assertEquals("invoiceAddressURL", rel.getLink().getHref()); 
     assertEquals("linkName", rel.getLink().getName()); 
     assertEquals("de", rel.getLink().getHreflang()); 
     assertNull(parser.nextToken()); 
    } 

    @Test 
    public void testDeserializeMultiValuedRelation() throws IOException { 
     resourceFile = new ResourceFile(getPackagePath() + "/multi_valued_relation.json"); 
     JsonParser parser = mapper.getFactory().createParser(resourceFile.getContent()); 
     DeserializationContext ctxt = mapper.getDeserializationContext(); 
     MultiValuedRelation rel = (MultiValuedRelation) deserializer.deserialize(parser, ctxt); 
     assertEquals(rel.getName(), "images"); 
     Iterator<Link> linkIterator = rel.getLinks().iterator(); 
     Link link = linkIterator.next(); 
     assertEquals("imageUrl1", link.getHref()); 
     link = linkIterator.next(); 
     assertEquals("imageUrl2", link.getHref()); 
     assertNull(parser.nextToken()); 
    } 

} 

類被測

public class RelationDeserializer extends StdDeserializer<Relation> { 

    public RelationDeserializer() { 
     super(Relation.class); 
    } 

    @Override 
    public Relation deserialize(JsonParser p, DeserializationContext ctxt) 
      throws IOException, JsonProcessingException { 
     if (p.getCurrentToken() == null && p.nextToken() == null) { 
      String msg = getClass().getCanonicalName() 
        + ": Can not deserialize without token"; 
      throw new IOException(msg); 
     } 
     if (p.getCurrentToken() != JsonToken.START_OBJECT 
       && p.getCurrentToken() != JsonToken.START_ARRAY) { 
      String msg = getClass().getCanonicalName() 
        + ": Expected data to start with an Relation object or an array of Relation objects"; 
      throw new IOException(msg); 
     } 
     if (p.nextToken() != JsonToken.FIELD_NAME) { 
      String msg = getClass().getCanonicalName() 
        + ": Expected relation to be started by a field name"; 
      throw new IOException(msg); 
     } 
     String relationName = p.getText(); 
     JsonToken tok = p.nextToken(); 
     Relation rel; 
     switch (tok) { 
     case START_ARRAY: 
      rel = createMultiValuedRelation(relationName, p); 
      break; 
     case START_OBJECT: 
      rel = createSingleValuedRelation(relationName, p); 
      break; 
     default: 
      String msg = getClass().getCanonicalName() + "Expected relation content is a single link or array of links"; 
      throw new IOException(msg); 
     } 
     p.nextToken(); 
     return rel; 
    } 

    private Relation createMultiValuedRelation(String relationName, JsonParser p) 
      throws JsonParseException, IOException { 
     List<Link> links = new ArrayList<Link>(); 
     if (p.nextToken() == JsonToken.START_OBJECT) { 
      Iterator<DefaultLink> linkIterator = p.readValuesAs(DefaultLink.class); 
      while (linkIterator.hasNext()) { 
       links.add(linkIterator.next()); 
      } 
     } 
     if (p.getCurrentToken() != JsonToken.END_ARRAY) { 
      String msg = getClass().getCanonicalName() + "Expected relation content is a single link or (possibly empty) array of links"; 
      throw new IOException(msg); 
     } 
     return RelationFactory.createRelation(relationName, links); 
    } 

    private Relation createSingleValuedRelation(String relationName, 
      JsonParser p) throws JsonParseException, IOException { 
     return RelationFactory.createRelation(relationName, p.readValueAs(DefaultLink.class)); 
    } 


} 

希望幫助和問候

+0

的@rule資源文件只是一個幫手,輕鬆地從測試/資源 –

21

JsonSerializer

該示例正在序列化一個LocalDateTime,但可以用所需的類型替換。

@Test 
public void serialises_LocalDateTime() throws JsonProcessingException, IOException { 
    Writer jsonWriter = new StringWriter(); 
    JsonGenerator jsonGenerator = new JsonFactory().createGenerator(jsonWriter); 
    SerializerProvider serializerProvider = new ObjectMapper().getSerializerProvider(); 
    new LocalDateTimeJsonSerializer().serialize(LocalDateTime.of(2000, Month.JANUARY, 1, 0, 0), jsonGenerator, serializerProvider); 
    jsonGenerator.flush(); 
    assertThat(jsonWriter.toString(), is(equalTo("\"2000-01-01T00:00:00\""))); 
} 

JsonDeserializer

這個例子是一個deserialising Number但是這可以通過所需的類型取代。

private ObjectMapper mapper; 
    private CustomerNumberDeserialiser deserializer; 

    @Before 
    public void setup() { 
     mapper = new ObjectMapper(); 
     deserializer = new CustomerNumberDeserialiser(); 
    } 

    @Test 
    public void floating_point_string_deserialises_to_Double_value() { 
     String json = String.format("{\"value\":%s}", "\"1.1\""); 
     Number deserialisedNumber = deserialiseNumber(json); 
     assertThat(deserialisedNumber, instanceOf(Double.class)); 
     assertThat(deserialisedNumber, is(equalTo(1.1d))); 
    } 

    @SneakyThrows({JsonParseException.class, IOException.class}) 
    private Number deserialiseNumber(String json) { 
     InputStream stream = new ByteArrayInputStream(json.getBytes(StandardCharsets.UTF_8)); 
     JsonParser parser = mapper.getFactory().createParser(stream); 
     DeserializationContext ctxt = mapper.getDeserializationContext(); 
     parser.nextToken(); 
     parser.nextToken(); 
     parser.nextToken(); 
     return deserializer.deserialize(parser, ctxt); 
    } 

UPDATE

當升級到傑克遜2.9.3我isEnabled(MapperFeature feature) deserialising字符串時的數字,因爲new ObjectMapper()初始化_confignullDeserializationContext收到NullPointerException

要解決這個問題,我用this SO回答窺視DeserializationContextfinal類:

DeserializationContext ctxt = spy(mapper.getDeserializationContext()); 
doReturn(true).when(ctxt).isEnabled(any(MapperFeature.class)); 

我覺得必須有一個更好的辦法,所以請評論,如果你有一個。

+1

文件中讀取JSON對於那些誰喜歡我不知道什麼是'解析器.nextToken'在這裏重複了三次 - 這意味着我們試圖將解析器從json {{value:1.1}'移動到值'1.1'。 'parser.nextToken'需要三次,因爲順序是START_OBJECT,FIELD_NAME,VALUE_STRING,我們希望在示例 – nilesh

+0

@nilesh中達到VALUE_STRING:有沒有辦法避免parser.nextToken重複3次?我有類似的要求,但不想使用parser.nextToken 3次 – kedar

+0

我看了[JsonParser API](http://fasterxml.github.io/jackson-core/javadoc/2.1.0/com/fasterxml/jackson/ core/JsonParser.html?is-external = true)和[JsonParser source](https://github.com/FasterXML/jackson-core/blob/master/src/main/java/com/fasterxml/jackson/core/ JsonParser.java),我不相信有。 –

1

解串器進行單元測試是這樣的:

public class CustomFooDeserializerTest { 

    private Foo foo; 

    @Before 
    public void setUp() { 
    ObjectMapper objectMapper = new ObjectMapper(); 
    SimpleModule module = new SimpleModule(); 
    module.addDeserializer(Foo.class, new CustomFooDeserializer()); 
    objectMapper.registerModule(module); 
    foo = objectMapper.readValue(new File("path/to/file"), Foo.class); 
    } 

    @Test 
    public void shouldSetSomeProperty() { 
    assertThat(foo.getSomeProperty(), is("valueOfSomeProperty")); 
    } 

}  
+0

分號前有一個缺失括號):assertThat(foo.getSomeProperty(),is(「valueOfSomeProperty」);我無法編輯因爲它只有1個字符:-)。 –

相關問題