#java #json #xml #servlets
Вопрос:
Я пишу программу-сервлет, которая предназначена для приема как xml, так и json, мой запрос в json таков,
{"Symbol":["OLM","ASC"]}
и это хорошо работает.
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
Connection connection = null;
BufferedReader reader1 = request.getReader();
StringBuffer jb = new StringBuffer();
String line = null;
while ((line = reader1.readLine()) != null) {
jb.append(line);
}
String str = jb.toString();
JSONObject obj2 = null;
try {
obj2 = new JSONObject(str);
} catch (JSONException e1) {
e1.printStackTrace();
}
JSONArray array = null;
try {
array = (JSONArray) obj2.get("Symbol");
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Я знаю, что он работает для json, потому что я передаю полученную строку(в моем случае str) в JSONObject, но если я также хочу принять XML и получить из него символ, как изменить этот код?
Заранее спасибо
Я обновляю свой вопрос,
ObjectMapper objectMapper = new ObjectMapper();
if(request.getHeader("content-type")=="application/json") {
System.out.println("json ");
Symbol symbolContainerFromJson = objectMapper.readValue(request.getReader(), Symbol.class);
System.out.println(symbolContainerFromJson.getSymbolName());
}
else if (request.getHeader("content-type")=="application/xml") {
System.out.println("xml");
Symbol symbolContainerFromXml = new XmlMapper().readValue(request.getReader(), Symbol.class);
System.out.println(symbolContainerFromXml.getSymbolName());
}
Но это не входит в оба цикла, пожалуйста, помогите
Комментарии:
1. Вероятно, вам следует использовать заголовки согласования содержимого html (Тип содержимого) в веб-запросе и передать его назначенному обработчику.
2. Спасибо за ваш ответ, на самом деле можно отправить xml, но на стороне сервера, как повторно отправить XML-запрос в форме символа? JSON в порядке, потому что я могу напрямую изменить полученную строку на JSONObject, как это obj2 = новый JSONObject(str); но для того, чтобы принять xml, также как изменить код на сервере? @NicoVanBelle
Ответ №1:
Самый надежный способ десериализации-это создать структуру данных в фоновом режиме и позволить такой структуре, как Джексон, выполнять тяжелую работу.
Поэтому мы сначала создаем наше представление объекта, которое мы ожидаем, либо в XML, либо в JSON. Никакой магии, это просто шутка. Я добавляю аннотацию JsonProperty, потому что вы ожидаете, что символ будет прописным, а я ненавижу поля верхнего регистра в Java.
public class SymbolContainer {
@JsonProperty("Symbol")
private List<String> symbol;
public List<String> getSymbol() {
return symbol;
}
}
Затем я использую сопоставитель объектов/Xml Джексона для преобразования содержимого из тела запроса в объект в памяти.
if(contentTypeIsJson(request.getHeader("content-type"))) {
SymbolContainer symbolContainerFromJson = new ObjectMapper().readValue("{"Symbol":["OLM","ASC"]}", SymbolContainer.class);
System.out.println(symbolContainerFromJson.getSymbol()); // [OLM, ASC]
} else if (contentTypeIsXml(request.getHeader("content-type"))) {
SymbolContainer symbolContainerFromXml = new XmlMapper().readValue("<root>n"
" <Symbol>n"
" <element>OLM</element>n"
" <element>ASC</element>n"
" </Symbol>n"
"</root>", SymbolContainer.class);
System.out.println(symbolContainerFromXml.getSymbol()); // [OLM, ASC]
}
Это с использованием только этих трех зависимостей Джексона
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.9.5</version>
</dependency>
Обратите внимание, что эти объекты могут быть настроены. Если вас интересует только часть запроса (например, символ), и вы хотите игнорировать остальную часть переданного объекта, лучше всего настроить свой ObjectMapper таким образом, чтобы он позволял игнорировать несопоставленные поля.
new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
Комментарии:
1. Большое вам спасибо, сэр, я новичок, и ваш ответ очень помог мне понять концепцию, а также найти ответ @NicoVanBelle
2. Здравствуйте, сэр, я обновил свой код , как вы предлагаете, но он не входит в оба цикла, почему? пожалуйста, помогите мне @NicoVanBelle
3. @сэм 1. Используйте
equals
для сравнения строк. 2. Убедитесь, что request.getHeader(«тип содержимого») не равен нулю, потому что заголовок может быть чувствителен к регистру 3. Возможно, также лучше использовать contains вместо equals, напримерrequest.getHeader("Content-Type").contains("xml")
, потому что заголовок может бытьapplication/xml
, но такжеtext/xml
4. Спасибо, сэр, это сработало