Java Servlet解析请求体多线程

Java Servlet解析请求体多线程,java,multithreading,servlets,jetty,Java,Multithreading,Servlets,Jetty,我实现了一个异步Servlet,它需要解析请求体并将解析结果存储在缓存中。我应该在Servlet中实现parseBody()函数还是实现一个新的类来进行解析?最佳做法是什么 以下是我当前的代码片段: public class DocFeedServlet extends FeedServlet { private static final Logger LOGGER = LoggerFactory.getLogger(DocFeedServlet.class); private static

我实现了一个异步Servlet,它需要解析请求体并将解析结果存储在缓存中。我应该在Servlet中实现
parseBody()
函数还是实现一个新的类来进行解析?最佳做法是什么

以下是我当前的代码片段:

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;
}
}
公共类DocFeedServlet扩展了FeedServlet{
私有静态最终记录器Logger=LoggerFactory.getLogger(DocFeedServlet.class);
私有静态最终ObjectMapper ObjectMapper=新ObjectMapper();
public void init(ServletConfig config)抛出ServletException{
super.init(config);
}
@凌驾
受保护的无效数据集(HttpServletRequest-req、HttpServletResponse-resp)
抛出ServletException、IOException{
resp.setStatus(HttpServletResponse.SC_BAD_请求);
}
@凌驾
受保护的void doPost(HttpServletRequest-req、HttpServletResponse-resp)
抛出ServletException、IOException{
final AsyncContext AsyncContext=req.startAsync();
asyncContext.start(新的Runnable(){
@凌驾
公开募捐{
字符串bodyStr=getBody(req);
if(bodyStr.isEmpty()){
resp.setStatus(HttpServletResponse.SC_BAD_请求);
asyncContext.complete();
返回;
}
int ignoreTime=Integer.parseInt(req.getParameter(Constant.PARAM_IGNORE_TIME));
List mockDocCacheKeyVals=new ArrayList();
List docUpdateFields=new ArrayList();
List DockepFields=new ArrayList();
List uuidsToRemove=new ArrayList();
int parseRet=parseBody(bodyStr、mockDocCacheKeyVals、docUpdateFields、dockepfields、uuidsToRemove、ignoreTime);
如果(parseRet!=0){
分别设置状态(HttpServletResponse.SC_OK);
}否则{
响应设置状态(HttpServletResponse.SC_内部_服务器_错误);
}
asyncContext.complete();
}
});
}
受保护的int-parseBody(字符串体、列表mockDocCacheKeyVals、列表docUpdateFields、列表DockepFields、列表uuidsToRemove、int-ignoreTime){
试一试{
ObjectReader=OBJECTMAPPER.reader(新类型引用(){});
列表文档=reader.readValue(body);
用于(文档:文档){
if(doc.getAction()!=null&&doc.getAction().equalsIgnoreCase(常量.doc\u FEED\u ACTION\u DELETE)){
如果(doc.getUuid()!=null){
uuidsToRemove.add(doc.getUuid());
}
继续;
}
如果(doc.getA()!=null){
}else if(doc.getB()!=null){
}否则{
DocumentUtils.pruneWeightSet(doc.getC(),cPruneSize);
DocumentUtils.prunewightset(doc.getD(),dPruneSize);
DocumentUtils.prunewightset(doc.getE(),ePruneSize);
}
}
返回文档。大小();
}捕获(例外e){
LOGGER.error(例如getMessage());
}
返回0;
}
}

谢谢。

异步请求正文读取是通过Servlet 3.1中引入的概念完成的

您将仅根据
ReadListener
中的事件进行读取,并且您将只读取足够的内容而不会阻塞。(因此不需要读取多兆字节缓冲区!)


然而,这个API正是您要寻找的,所以在完成它之前,请确保您完全理解该API。

异步请求正文读取是通过Servlet 3.1中引入的概念完成的

您将仅根据
ReadListener
中的事件进行读取,并且您将只读取足够的内容而不会阻塞。(因此不需要读取多兆字节缓冲区!)

然而,这个API是您正在寻找的,所以在完成它之前,请确保您完全理解该API