`
lwbbupt
  • 浏览: 36029 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

servlet异步处理中遇到一些问题及其分析

阅读更多

刚开始学习servlet,照着书写了写异步处理的一些例子:

 

@WebServlet(urlPatterns="/async", asyncSupported = true)
public class AsyncServlet extends HttpServlet {
	@Override
	public void service(HttpServletRequest request, HttpServletResponse response) 
			throws IOException, ServletException{
		response.setContentType("text/html; charset = utf-8");
		PrintWriter out = response.getWriter();
		out.println("<title>异步调用测试</title>");
		out.println("进入servlet的时间为:" + new Date() + "<br/>");
		out.flush();
		//创建AsyncContext,开始异步调用
		boolean isasync = request.isAsyncSupported();
		AsyncContext actx = request.startAsync();
		actx.setTimeout(20000);
		Runnable run = new Executer(actx);
		actx.start(new Executer(actx));
		out.println("结束servlet的时间为: " + new Date() + "<br/>");
		out.flush();
	}
}

 

public class Executer implements Runnable{
	private AsyncContext actx = null;
	public Executer(AsyncContext actx){
		this.actx = actx;
	}
	public void run(){
		try{
			Thread.sleep(5000);
			ServletRequest request = actx.getRequest();
			List<String> books = new ArrayList<String>();
			books.add("java学习");
			books.add("javaee 学习");
			request.setAttribute("books", books);
			actx.dispatch("/async.jsp");
		}
		catch(Exception e){
			e.printStackTrace();
		}
	}
}

 

 <body>
    <%
    List<String> books = (List<String>)request.getAttribute("books");
    if(books !=null){
    	for(String book: books){
    		out.println(book);
    		out.println("<br/>");
    	}
    }
    out.println("业务调用时间结束:"+ new Date() + "<br/>");
    request.getAsyncContext().complete();
    %>
  </body>

 先是报了一个这样的错误:

 

 

严重: Servlet.service() for servlet [webDemo.AsyncServlet] in context with path [/webDemo] threw exception [javax.servlet.ServletException: java.lang.IllegalStateException: Cannot create a session after the response has been committed] with root cause
java.lang.IllegalStateException: Cannot create a session after the response has been committed
	at org.apache.catalina.connector.Request.doGetSession(Request.java:2924)
	at org.apache.catalina.connector.Request.getSession(Request.java:2300)
	at org.apache.catalina.connector.RequestFacade.getSession(RequestFacade.java:897)
	at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:229)
	at org.apache.catalina.core.ApplicationHttpRequest.getSession(ApplicationHttpRequest.java:569)

 即:不能在响应提交后,再创建session,分析出现这个问题的原因是由于我们的代码中存在以下语句:

 

response.setContentType("text/html; charset = utf-8");

响应向客户端返回来了http的头文件,导致了不能创建sessionid,因为sessionid一般存在于http cookie

的头文件了,所以为了避免以上问题,我们可以在上面的语句加上一句:

 

HttpSession session = request.getSession();

 先创建session,当然也可以不通过response输出头文件。

 

在解决了这个问题之后程序依然报错

严重: Servlet.service() for servlet [webDemo.AsyncServlet] in context with path [/webDemo] threw exception [java.lang.IllegalStateException: Calling [asyncComplete()] is not valid for a request with Async state [DISPATCHED]] with root cause
java.lang.IllegalStateException: Calling [asyncComplete()] is not valid for a request with Async state [DISPATCHED]
	at org.apache.coyote.AsyncStateMachine.asyncComplete(AsyncStateMachine.java:227)
	at org.apache.coyote.http11.Http11AprProcessor.actionInternal(Http11AprProcessor.java:456)
	at org.apache.coyote.http11.AbstractHttp11Processor.action(AbstractHttp11Processor.java:867)
	at org.apache.coyote.Request.action(Request.java:344)
	at org.apache.catalina.core.AsyncContextImpl.complete(AsyncContextImpl.java:91)
	at org.apache.jsp.async_jsp._jspService(async_jsp.java:92)
	at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)

 即:对于处于dispatched异步状态下的request调用asyncComplete()是无效的,分析可知问题出在以下语句:

request.getAsyncContext().complete();

我们删除这条语句,问题解决。

我们在api中关于complete函数找到了以下几句话:

It is legal to call this method any time after a call to ServletRequest.startAsync() or ServletRequest.startAsync(ServletRequest, ServletResponse), and before a call to one of the dispatch methods of this class.

说的很清楚在startAsync之后以及在dispatch方法之前调用是合法的。

在关于dispatch方法的说明中:

There can be at most one asynchronous dispatch operation per asynchronous cycle, which is started by a call to one of the ServletRequest.startAsync() methods. Any attempt to perform an additional asynchronous dispatch operation within the same asynchronous cycle will result in an IllegalStateException. If startAsync is subsequently called on the dispatched request, then any of the dispatch or complete() methods may be called.

在使用了dispatch方法之后只有startAsync方法调用后才能调用complete方法。

 

最后应当注意的是,在使用异步之前最好查看下request是否支持异步操作,即查看boolean isAsyncSupported()

 

Asynchronous operation is disabled for this request if this request is within the scope of a filter or servlet that has not been annotated or flagged in the deployment descriptor as being able to support asynchronous handling.

 

 

 

 

 

1
0
分享到:
评论
2 楼 lwbbupt 2014-05-22  
AsyncContext只是向request添加了books这个属性,然后通过dispatch方法将请求转发到指定的jsp做处理
1 楼 string2020 2014-05-21  
请问,run方法里面的
actx.dispatch("/async.jsp"); 
是什么意思?

既然当前servlet是一直往页面输出的,为何要dispatch一个jsp

相关推荐

    Web on Servlet Stack

    - **Exception Handling**:异步请求中也需要妥善处理异常情况。 - **Async Interceptors**:异步拦截器可以在异步处理的各个阶段执行。 - **Streaming Response**:流式响应适用于大数据传输场景。 - **Server-Sent...

    servlet源码包

    这个“servlet源码包”很可能是包含了Servlet API的源代码,这对于理解Servlet的工作原理、进行J2EE开发或者解决开发过程中遇到的问题非常有帮助。下面,我们将深入探讨Servlet相关的知识点。 1. **Servlet概述** ...

    基于javaweb的商品后台管理系统servlet+jdbc+jsp框架源码

    3. 异常处理:良好的异常处理机制可以确保系统在遇到问题时能优雅地处理并提供有用的错误信息。 4. 前后端分离:尽管这个项目使用了传统的MVC模式,但现代Web开发趋势倾向于前后端分离,可以考虑使用Ajax进行异步...

    Java_Jdbc_Hibernate_Struts2_Android_Web异常及其处理办法

    在Android中,开发者需要在`onCreate()`方法或异步任务中使用`try-catch`块来处理异常,防止应用因异常而崩溃。同时,Android Studio的Lint工具可以帮助发现潜在的异常。 【Web异常处理】 对于Servlet和JSP,异常...

    JSP XMLHttpRequest动态无刷新及其中文乱码处理.docx

    在处理中文字符时,可能会遇到乱码问题。这是因为浏览器、服务器以及应用之间编码不一致导致的。以下是解决中文乱码问题的关键步骤: 1. **设置Servlet响应头**: ```java response.setContentType("text/html;...

    J2EE开发中常见的问题总结

    在J2EE开发中,开发者经常遇到一系列的问题,这些问题不仅涉及技术细节,还关乎架构设计和应用部署。本文将深入探讨这些常见问题,帮助开发者提升开发效率和解决问题的能力。 1. **容器管理与生命周期**: J2EE...

    简单的图书管理系统

    以下将详细阐述Servlet在图书管理系统中的应用及其涉及的关键知识点: 1. **Servlet生命周期**:Servlet在服务器启动时被加载,然后创建一个实例,这个实例可以服务于多个请求。当请求到达时,Servlet容器(如...

    手机号码所属区域查询

    - 错误处理:添加异常处理机制,确保在遇到问题时能够给出友好的错误提示。 总的来说,这个项目展示了如何利用MyEclipse、Tomcat和MySQL构建一个简单的Web应用程序,实现手机号码所属区域的查询功能。通过这个项目...

    过滤器在Java Web开发中的应用研究.pdf

    在深入分析和探讨过滤器在Java Web开发中的应用研究时,首先要了解过滤器的定义及其在Java Web开发中的重要作用。过滤器是一种设计模式,用于拦截请求和响应,以便执行某些预处理或后处理操作。在Java Web开发中,...

    JavaWeb购物商城项目.zip

    下面将详细阐述这些技术在项目中的应用及其重要性。 1. **Java Servlet**: Servlet是Java编程语言中用于扩展服务器功能的接口。在JavaWeb购物商城项目中,Servlet负责处理HTTP请求,如用户登录、商品浏览、购物车...

    tomcat-7.0.5

    1. **Servlet 3.0特性**:Tomcat 7.0.5支持Servlet 3.0,带来了诸如异步处理能力的增强,允许在后台线程中执行耗时的操作,而不会阻塞主线程。这显著提高了Web应用的性能和响应性。此外,还支持注解配置,开发者可以...

    EasyUI filebox空间上传文件操作说明

    本文详细介绍了在使用EasyUI框架中的`filebox`控件进行文件上传时遇到的一些常见问题及其解决办法。特别是针对如何实现文件的异步上传、处理上传文件的逻辑以及如何在保存记录时清除未使用的文件等方面进行了深入的...

    JSP学生资料查询系统

    9. **错误和异常处理**:良好的错误处理和异常捕获机制对于任何系统都是必不可少的,确保在遇到问题时能提供有用的反馈信息。 10. **版本控制工具**:开发过程中,可能会使用Git或其他版本控制工具来协同开发和管理...

    Accp6.0 S2~Y2转换课程(Java方向)(完整课件六)

    异常处理则为程序提供了错误处理机制,确保程序在遇到问题时能正常运行。集合框架是Java中存储和操作数据的关键工具,包括List、Set、Map等接口及其实现类,如ArrayList、HashSet、HashMap等。IO流则用于读写文件和...

    jsp学生选课系统代码及报告

    6. **问题与解决方案**:记录开发过程中遇到的问题及其解决方法。 综上所述,"jsp学生选课系统代码及报告"是一个全面的项目,涵盖了Web开发的多个方面,对于学习JSP和Web应用开发的人员来说,是一个宝贵的实践案例...

    dwr与界面开发(内含树,右键菜单,日期的js组件和帮助文档)

    这个压缩包文件包含了关于DWR使用和界面开发的相关资料,包括配置说明、笔记、技术分析以及开发培训材料,还有关于树形结构、右键菜单和日期控件的JavaScript组件及其帮助文档。 1. **DWR配置说明**: DWR的配置...

    SSH框架面试题.pdf

    在Struts中,用户请求由控制器(ActionServlet)接收,并根据配置文件(struts-config.xml)转发给相应的Action对象处理。Action对象负责调用业务逻辑层执行业务逻辑,并将结果返回给视图层显示。 2. **如何在...

    java项目之网上在线学习平台设计和实现(源码+说明文档+演示视频).zip

    “项目问题说明.docx”可能记录了在开发过程中遇到的问题及其解决方案,这对于其他开发者来说是宝贵的教训和经验,可以避免重复犯错,提高开发效率。 “演示”目录可能包含了一些项目运行截图或者录屏,直观地展示...

Global site tag (gtag.js) - Google Analytics