2015-01-12 2 views
2

Я пытаюсь написать метод для красивой печати JSON Strings, используя MOXy. Так что я хочу, чтобы иметь метод, как этотUnmarshal JSON String к некоторому «объекту» с использованием MOXy

public String formatJson(String input) { ... } 

Я думаю, что путь, чтобы разобрать строку в общий объект (Что-то вроде SAX-документа, или вид), а затем маршалом это Верните объект в JSON, используя некоторые свойства форматирования (что не является проблемой :-)).

Проблема заключается в том, что при чтении JSON-String-Input у меня нет класса для его отмены (поскольку я хочу, чтобы метод был как можно более общим).

[отредактировано] Примеры GSON и Jackson удалены, так как вопрос только MOXy.

Я попытался это:

public static String toFormattedJson(final String jsonString) { 
    String formatted; 
    try { 
     JAXBContext jaxbContext = JAXBContextFactory.createContext(new Class[] { JAXBElement.class }, null); 
     Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); 
     unmarshaller.setProperty(MEDIA_TYPE, MediaType.APPLICATION_JSON); 
     unmarshaller.setProperty(JSON_INCLUDE_ROOT, true); 
     StringReader reader = new StringReader(jsonString); 
     Object element = unmarshaller.unmarshal(reader); // Exception is thrown here 
     formatted = toFormattedJson(element); 
    } catch (final JAXBException e) { 
     formatted = jsonString; 
    } 
    return formatted; 
} 

, но я получаю это исключение

javax.xml.bind.UnmarshalException - со связанным исключением: [java.lang.ClassCastException: org.eclipse. persistence.internal.oxm.record.SAXUnmarshallerHandler не может быть передан в org.eclipse.persistence.internal.oxm.record.UnmarshalRecord]

Итак, как я могу прочитать произвольную строку JSON для Java-объекта, если я не знаю, T есть ли какой-либо класс для этой конкретной строки?

Update: Это метод, используемый для форматирования объекта в JSON строки:

private static String toFormattedJson(Object obj) { 
    String result; 
    try (StringWriter writer = new StringWriter()) { 
     final JAXBContext jaxbContext = JAXBContextFactory.createContext(new Class[] { obj.getClass() }, null); 
     final Marshaller marshaller = jaxbContext.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.setProperty(JAXBContextProperties.MEDIA_TYPE, MediaType.APPLICATION_JSON); 
     marshaller.setProperty(MarshallerProperties.JSON_REDUCE_ANY_ARRAYS, false); 
     marshaller.setProperty(MarshallerProperties.JSON_MARSHAL_EMPTY_COLLECTIONS, false); 
     marshaller.setProperty(JAXBContextProperties.JSON_WRAPPER_AS_ARRAY_NAME, false); 
     marshaller.setProperty(JAXBContextProperties.JSON_INCLUDE_ROOT, true); 
     marshaller.marshal(obj, writer); 
     writer.flush(); 
     result = writer.toString(); 
    } catch (JAXBException | IOException e) { 
     result = obj.toString(); 
    } 
    return result; 
} 

И используя теперь код снизу (Martin Войтек), когда я пытаюсь форматировать

String jsonString = "{\"p\" : [ 1, 2, 3]}"; 

я получаю:

{ 
    "p" : "1" 
} 
+0

Кто-нибудь? Нет идей? – Asturio

ответ

2

Y ou может указывать строку в качестве цели немаршаля:

public static void main(String[] args) { 
     System.out.println(toFormattedJson("[{\"test\":true}, \"ok\", [\"inner\",1]]")); 
} 

public static String toFormattedJson(final String jsonString) { 
    String formatted; 
    try { 
     JAXBContext jaxbContext = JAXBContextFactory.createContext(new Class[] { JAXBElement.class }, null); 
     System.out.println("jaxbContext="+jaxbContext); 
     Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); 
     unmarshaller.setProperty(JAXBContextProperties.MEDIA_TYPE, MediaType.APPLICATION_JSON); 
     unmarshaller.setProperty(JAXBContextProperties.JSON_INCLUDE_ROOT, true); 
     StringReader reader = new StringReader(jsonString); 
     Object element = unmarshaller.unmarshal(new StreamSource(reader), String.class); 
     formatted = toFormattedJsonElement(element); 
    } catch (final JAXBException e) { 
     e.printStackTrace(); 
     formatted = jsonString; 
    } 
    return formatted; 
} 

private static String toFormattedJsonElement(Object element) { 
    return "formatted: " + element; 
} 
+0

Теперь код работает лучше для меня. У меня все еще есть проблемы с массивами Integer, которые неправильно отображаются. Просто, чтобы быть уверенным: классы JAXBConext, JAXBContextFactory и Unmarshaller должны быть из какого пакета? javax.xml.bind или org.eclipse.persistenca.jaxb? – Asturio

+1

import org.eclipse.persistence.jaxb.JAXBContextFactory; import org.eclipse.persistence.jaxb.JAXBContextProperties; import org.eclipse.persistence.oxm.MediaType; импорт javax.xml.bind.JAXBContext; импорт javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; импорт javax.xml.bind.Unmarshaller; импорт javax.xml.transform.stream.StreamSource; import java.io.StringReader; –

+1

Я вижу unmarshal следующей строки «{\" p \ ": [1, 2, 3]}" как ошибка и зарегистрированная ошибка https://bugs.eclipse.org/bugs/show_bug.cgi?id=460630 , С другой стороны, я не думаю, что это лучшая идея для нас MOXy для такого рода вещей. Вы должны использовать, например. Обработка JSON https://jsonp.java.net/download.html –