2015-11-15 3 views
1

Я реализовал асинхронный сервлет, которому необходимо проанализировать тело запроса и сохранить результат анализа в кеше. Должен ли я реализовать функцию parseBody() в Servlet или реализовать новый класс, который будет выполнять синтаксический анализ? Какова наилучшая практика?Java Servlet разбор тела запроса многопоточность

Вот мой текущий фрагмент кода:

public class DocFeedServlet extends FeedServlet { 

private static final Logger LOGGER = LoggerFactory.getLogger(DocFeedServlet.class); 
private static final ObjectMapper OBJECTMAPPER = new ObjectMapper(); 


public void init(ServletConfig config) throws ServletException { 
    super.init(config); 
} 

@Override 
protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
    throws ServletException, IOException { 
    resp.setStatus(HttpServletResponse.SC_BAD_REQUEST); 
} 

@Override 
protected void doPost(HttpServletRequest req, HttpServletResponse resp) 
    throws ServletException, IOException { 

    final AsyncContext asyncContext = req.startAsync(); 
    asyncContext.start(new Runnable() { 
     @Override 
     public void run() { 
      String bodyStr = getBody(req); 
      if (bodyStr.isEmpty()) { 
       resp.setStatus(HttpServletResponse.SC_BAD_REQUEST); 
       asyncContext.complete(); 
       return; 
      } 

      int ignoreTime = Integer.parseInt(req.getParameter(Constant.PARAM_IGNORE_TIME)); 

      List<MockDocCacheKeyVal> mockDocCacheKeyVals = new ArrayList<>(); 
      List<String> docUpdateFields = new ArrayList<>(); 
      List<List<String>> docKeepFields = new ArrayList<List<String>>(); 
      List<String> uuidsToRemove = new ArrayList<>(); 

      int parseRet = parseBody(bodyStr, mockDocCacheKeyVals, docUpdateFields, docKeepFields, uuidsToRemove, ignoreTime); 

      if (parseRet != 0) { 
       resp.setStatus(HttpServletResponse.SC_OK); 
      } else { 
       resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 
      } 
      asyncContext.complete(); 
     } 
    }); 
} 

protected int parseBody(String body, List<MockDocCacheKeyVal> mockDocCacheKeyVals, List<String> docUpdateFields, List<List<String>> docKeepFields, List<String> uuidsToRemove, int ignoreTime) { 
    try { 
     ObjectReader reader = OBJECTMAPPER.reader(new TypeReference<List<Document>>() { }); 
     List<Document> documents = reader.readValue(body); 
     for (Document doc : documents) { 
      if (doc.getAction() != null && doc.getAction().equalsIgnoreCase(Constant.DOC_FEED_ACTION_DELETE)) { 
       if (doc.getUuid() != null) { 
        uuidsToRemove.add(doc.getUuid()); 
       } 
       continue; 
      } 
      if (doc.getA() != null) { 

      } else if (doc.getB() != null) { 

      } else { 
       DocumentUtils.pruneWeightSet(doc.getC(), cPruneSize); 
       DocumentUtils.pruneWeightSet(doc.getD(), dPruneSize); 
       DocumentUtils.pruneWeightSet(doc.getE(), ePruneSize); 
      } 
     } 
     return documents.size(); 
    } catch (Exception e) { 
     LOGGER.error(e.getMessage()); 
    } 
    return 0; 
} 
} 

Спасибо.

ответ

0

Асинхронный Тело запроса чтения осуществляется с HttpServletRequest.getInputStream().setReadListener(ReadListener) понятий, введенных в Servlet 3.1

Вы только читать, основанные на событиях из вашей ReadListener, и вы будете только читать достаточно, чтобы не блокировать. (так что нет чтения мегабайтных буферов!).

Этот API - это то, что вы ищете, однако there be land mines here, так что не забудьте полностью понять API, прежде чем завершить его.

Смежные вопросы