Как написать программу-сервлет, которая использует как XML, так и JSON?

#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. Спасибо, сэр, это сработало