Servlet 2.2
Servlet 2.3
Servlet 2.4
Servlet 2.5
Servlet 3.0
Servlet 4.0(草案阶段)
将Tomcat的minThreads, maxThreads, acceptCount都设置为1然后测试。
@WebServlet(urlPatterns="/login") public class Login extends HttpServlet{ private static final long serialVersionUID = 2394188843772629040L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Calendar cleaner = Calendar.getInstance(); SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println("Thread Name:"+Thread.currentThread().getName() +" Time:"+formatter.format(cleaner.getTime())); resp.getWriter().write("Thread Name:"+Thread.currentThread().getName()); resp.getWriter().write("\n"); resp.getWriter().write("Class Name:"+this); resp.getWriter().write("\n"); resp.getWriter().write("Start time:"+formatter.format(cleaner.getTime())); resp.getWriter().write("\n"); try { /*模拟业务阻塞*/ Thread.sleep(1000*5); } catch (InterruptedException e) { e.printStackTrace(); } cleaner = Calendar.getInstance(); resp.getWriter().write("End time:"+formatter.format(cleaner.getTime())); resp.getWriter().write("\n"); resp.setHeader("Content-Type", "text/text"); } }
public class Test implements Runnable{ public void run(){ CloseableHttpClient httpclient = null; CloseableHttpResponse response = null; Calendar calendar = null; calendar = Calendar.getInstance(); SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); System.out.println(Thread.currentThread().getName()+"开始 :"+formatter.format(calendar.getTime())); try { httpclient = HttpClients.createDefault(); HttpGet httpget = new HttpGet("http://127.0.0.1:8080/login"); response = httpclient.execute(httpget); StatusLine statusLine = response.getStatusLine(); System.out.println(statusLine); HttpEntity resEntity = response.getEntity(); InputStream content = resEntity.getContent(); InputStreamReader reader = new InputStreamReader(content); BufferedReader bufferedReader = new BufferedReader(reader); String lineTxt = null; while((lineTxt = bufferedReader.readLine()) != null){ System.out.println(lineTxt); } httpget.abort(); } catch (ClientProtocolException e) { System.out.println(Thread.currentThread().getName()+" ERROR:"+e.getMessage()); } catch (IOException e) { System.out.println(Thread.currentThread().getName()+" ERROR:"+e.getMessage()); } finally { try { response.close(); httpclient.close(); } catch (Exception e) { System.out.println(Thread.currentThread().getName()+" ERROR:"+e.getMessage()); } } calendar = Calendar.getInstance(); System.out.println(Thread.currentThread().getName()+"结束 :"+formatter.format(calendar.getTime())); } public static void main(String[] args) { for (int i = 0; i < 5; i++) { Thread thread = new Thread(new Test()); thread.setName("TestThread-"+(i+1)); thread.start(); } } }
并发请求下Thread Name不同,Class Name相同证实servlet是单实例多线程的特性,WEB容器处理
能力由开启的线程数决定我们在编写代码时通过将阻塞的业务操作放到自己创建的线程里的方式,来减
轻WEB容器的线程压力。提高WEB线程的利用率(在Servlet 3.0中已经提供了异步处理支持)。
1.创建Servlet实例,由WEB容器进行。
2.初始化 Servlet,调用 Servlet 的 init 的方法。
3.响应客户请求阶段,调用service()方法。
4.终止阶段调用destroy()方法。
out | 转译后对应JspWriter对象,其内部关联一个PringWriter对象 |
request | 转译后对应HttpServletRequest/ServletRequest对象 |
response | 转译后对应HttpServletRespons/ServletResponse对象 |
config | 转译后对应ServletConfig对象 |
application | 转译后对应ServletContext对象 |
session | 转译后对应HttpSession对象 |
pageContext | 转译后对应PageContext对象,它提供了JSP页面资源的封装,并可设置页面范围属性 |
exception | 转译后对应Throwable对象,代表由其他JSP页面抛出的异常对象,只会出现于JSP错误页面(isErrorPage设置为true的JSP页面) |
page | 转译后对应this |
1.新增注解支持:从这个版本开始 web.xml 不再是必有的了。
2.异步处理支持:减少服务器资源占用,提高并发处理速度。
3.可插性支持:通过插件的方式扩充已有 Web 应用的功能,而不需要修改原有的应用。
4.运行时动态部署Servlet、过滤器、监听器。
5.对文件上传的支持。
@WebServlet:声明类是servlet,主要属性urlPattems定义访问url。
@WebFilter:声明类是过滤器,主要属性urlPattems定义访问url,dispatcherTypes指定转发模式。
@WebListener:声明类是监听器。
@MultipartConfig:表示该 Servlet 希望处理的请求的 MIME 类型是 multipart/form-data。
@WebInitParam:为 Servlet 或者过滤器指定初始化参数。
public class AsyncDemoServlet extends HttpServlet { @Override public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException { resp.setContentType("text/html;charset=UTF-8"); PrintWriter out = resp.getWriter(); out.println("进入Servlet的时间:" + new Date() + "."); out.flush(); //在子线程中执行业务调用,并由其负责输出响应,主线程退出 AsyncContext ctx = req.startAsync(); //使用AsyncListener 接口监听异步线程 TaskListener taskListener = new TaskListener(); ctx.addListener(TaskListener); new Thread(new Executor(ctx)).start(); out.println("结束Servlet的时间:" + new Date() + "."); out.flush(); } }
public class Executor implements Runnable { private AsyncContext ctx = null; public Executor(AsyncContext ctx){ this.ctx = ctx; } public void run(){ try { //等待十秒钟,以模拟业务方法的执行 Thread.sleep(10000); PrintWriter out = ctx.getResponse().getWriter(); out.println("业务处理完毕的时间:" + new Date() + "."); out.flush(); ctx.complete(); } catch (Exception e) { e.printStackTrace(); } } }
public class TaskListener implements AsyncListener{ public void onComplete(AsyncEvent event) throws IOException { //执行完毕时 } public void onError(AsyncEvent event) throws IOException { //出错 } public void onStartAsync(AsyncEvent event) throws IOException { //开始 } public void onTimeout(AsyncEvent event) throws IOException { //执行超时 } }
Tomcat 从7.0的版本开始支持Servlet 3.0。