`

Servlet3.0新特性使用详解

    博客分类:
  • java
阅读更多
 

 

在infoq上有关于servlet3.0的新特性说明,个人觉得比较全面

 

  • 可插拔的Web框架
    • 几乎所有基于Java的web框架都建立在servlet之上。现今大多数web框架要么通过servlet、要么通过Web.xml插入。利用标注(Annotation)来定义servlet、listener、filter将使之(可插拔)成为可能。程序访问web.xml和动态改变web应用配置是所期望的特性。该JSR将致力于提供把不同web框架无缝地插入到web应用的能力。
  • EOD
    • 标注——利用标注来作为编程的声明风格。
    • web应用零配置是EoD努力方向之一。部署描述符将被用来覆盖配置。
    • 范型(generic)——在API中尽可能利用范型。
    • 使用其它语言增强可能需要改善API可用性的地方。
  • 支持异步和Comet
    • 非阻塞输入——从客户端接收数据,即使数据到达缓慢也不会发生阻塞。
    • 非阻塞输出——发送数据到客户端,即使客户端或网络很慢也不会发生阻塞。
    • 延迟请求处理——Ajax web应用的Comet风格,可以要求一个请求处理被延迟,直到超时或一个事件发生。延迟请求处理对以下情况也很有用:如果远程的/迟缓的资源必须在为该请求服务之前被获得;或者如果访问一个特殊资源,其需要扼杀一些请求以防止太多的并发访问。
    • 延迟响应关闭——Ajax web应用的Comet风格,可以要求响应保持打开,以允许当异步事件产生时发送额外的数据。
    • 阻塞/非阻塞通知——通知阻塞或非阻塞事件。
    • 频道概念——订阅一个频道,以及从该频道获取异步事件的能力。这意味着可以创建、订阅、退订,以及应用一些诸如谁能加入、谁不能加入的安全限制。
  • 安全
    • login/logout能力。
    • 自注册。
  • 结合
    • 结合/需求,来自REST JST JSR(JSR 311 )。
    • 结合/需求,来自JSF 2.0 JSR(JSR 134 )。
  • 其它
    • 支持更好的欢迎文件(welcome file)。
    • ServletContextListener排序。
    • 容器范围内定义init参数。
    • 文件上载——过程侦听——存储中间或最终文件。
    • 澄清线程安全问题。

 

我们下面就看看其中几个特性:

1.可插拔的Web框架,其实就是web.xml中可以又多个子模块的配置文件组成,而各个子模块的配置文件可以放在各个jar包的META-INFO中,这样就实现web应用的模块化。

 类似,可以按照配置的顺序指定了web片段的顺序。通过absolute-ordering进行绝对顺序配置,通过每个fragment的order的after和before标签进行相对顺序配置。

 

Xml代码 复制代码 收藏代码
  1. <?xml version="1.0" encoding="GB18030"?>  
  2. <web-app version="3.0"    
  3.     xmlns="http://java.sun.com/xml/ns/javaee"    
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
  5.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee    
  6.     http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">  
  7.     <absolute-ordering>  
  8.         <name>web-fragment1</name>  
  9.         <name>web-fragment2</name>  
  10.     </absolute-ordering></web-app>  
<?xml version="1.0" encoding="GB18030"?>
<web-app version="3.0" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
	<absolute-ordering>
		<name>web-fragment1</name>
		<name>web-fragment2</name>
	</absolute-ordering></web-app>

 每个fragment1的配置如下:

 

Xml代码 复制代码 收藏代码
  1. <?xml version="1.0" encoding="GB18030"?>  
  2. <web-fragment version="3.0"    
  3.     xmlns="http://java.sun.com/xml/ns/javaee"    
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
  5.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee    
  6.     http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd">  
  7.   
  8.     <name>web-fragment1</name>  
  9.     <ordering><after>web-fragment1</after><before><others/></before></ordering>  
  10.   
  11. </web-fragment>  
<?xml version="1.0" encoding="GB18030"?>
<web-fragment version="3.0" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-fragment_3_0.xsd">

	<name>web-fragment1</name>
	<ordering><after>web-fragment1</after><before><others/></before></ordering>

</web-fragment>
 2. servlet3.0的annotation支持

对于原来在web.xml定义的servlet,filter,listener,InitParam都可以通过annotation来配置了,而不需要在web.xml中定义。

@WebFilter

 

Java代码 复制代码 收藏代码
  1. import java.io.IOException;   
  2.   
  3. import javax.servlet.Filter;   
  4. import javax.servlet.FilterChain;   
  5. import javax.servlet.FilterConfig;   
  6. import javax.servlet.ServletException;   
  7. import javax.servlet.ServletRequest;   
  8. import javax.servlet.ServletResponse;   
  9. import javax.servlet.annotation.WebFilter;   
  10. import javax.servlet.annotation.WebInitParam;   
  11.   
  12. //asyncSupported=true 对应filter也需要定义asyncSupported=true   
  13. @WebFilter(urlPatterns={"/*"}, filterName="my3Filter", asyncSupported=true)   
  14. @WebInitParam(name="a", value="valuea")   
  15. public class My3Filter implements Filter{   
  16.   
  17.     @Override  
  18.     public void destroy() {   
  19.         // TODO Auto-generated method stub   
  20.            
  21.     }   
  22.   
  23.     @Override  
  24.     public void doFilter(ServletRequest arg0, ServletResponse arg1,   
  25.             FilterChain arg2) throws IOException, ServletException {   
  26.         System.out.println("servlet 3 filter");   
  27.         arg2.doFilter(arg0, arg1);   
  28.     }   
  29.   
  30.     @Override  
  31.     public void init(FilterConfig arg0) throws ServletException {   
  32.         System.out.println("servlet 3 filter init");   
  33.     }   
  34.   
  35. }  
import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;

//asyncSupported=true 对应filter也需要定义asyncSupported=true
@WebFilter(urlPatterns={"/*"}, filterName="my3Filter", asyncSupported=true)
@WebInitParam(name="a", value="valuea")
public class My3Filter implements Filter{

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1,
			FilterChain arg2) throws IOException, ServletException {
		System.out.println("servlet 3 filter");
		arg2.doFilter(arg0, arg1);
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		System.out.println("servlet 3 filter init");
	}

}

 @WebServlet

 

Java代码 复制代码 收藏代码
  1. import java.io.IOException;   
  2.   
  3. import javax.servlet.Filter;   
  4. import javax.servlet.FilterChain;   
  5. import javax.servlet.FilterConfig;   
  6. import javax.servlet.ServletException;   
  7. import javax.servlet.ServletRequest;   
  8. import javax.servlet.ServletResponse;   
  9. import javax.servlet.annotation.WebFilter;   
  10. import javax.servlet.annotation.WebInitParam;   
  11.   
  12. //asyncSupported=true 对应filter也需要定义asyncSupported=true   
  13. @WebFilter(urlPatterns={"/*"}, filterName="my3Filter", asyncSupported=true)   
  14. @WebInitParam(name="a", value="valuea")   
  15. public class My3Filter implements Filter{   
  16.   
  17.     @Override  
  18.     public void destroy() {   
  19.         // TODO Auto-generated method stub   
  20.            
  21.     }   
  22.   
  23.     @Override  
  24.     public void doFilter(ServletRequest arg0, ServletResponse arg1,   
  25.             FilterChain arg2) throws IOException, ServletException {   
  26.         System.out.println("servlet 3 filter");   
  27.         arg2.doFilter(arg0, arg1);   
  28.     }   
  29.   
  30.     @Override  
  31.     public void init(FilterConfig arg0) throws ServletException {   
  32.         System.out.println("servlet 3 filter init");   
  33.     }   
  34.   
  35. }  
import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;

//asyncSupported=true 对应filter也需要定义asyncSupported=true
@WebFilter(urlPatterns={"/*"}, filterName="my3Filter", asyncSupported=true)
@WebInitParam(name="a", value="valuea")
public class My3Filter implements Filter{

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void doFilter(ServletRequest arg0, ServletResponse arg1,
			FilterChain arg2) throws IOException, ServletException {
		System.out.println("servlet 3 filter");
		arg2.doFilter(arg0, arg1);
	}

	@Override
	public void init(FilterConfig arg0) throws ServletException {
		System.out.println("servlet 3 filter init");
	}

}
 支持的annotation如下,都可以通过eclipse的提示查到对应的参数配置,


@WebServlet支持的参数有



 3. servlet3.0的异步支持

很多时候Servlet要和其他的资源进行互动,例如访问数据库,调用web service。在和这些资源互动的时候,Servlet不得不等待数据返回,然后才能够继续执行。这使得Servlet调用这些资源的时候阻塞。Servlet3.0通过引入异步处理解决了这个问题。异步处理允许线程调用资源的时候不被阻塞,而是直接返回。AsyncContext负责管理从资源来的回应。AsyncContext决定该回应是应该被原来的线程处理还是应该分发给容器中其他的资源。AsyncContext有一些方法如start,dispatch和complete来执行异步处理。 
要想使用Servlet3.0的异步处理,我们需要设置@Webservlet和@WebFilter注解的asyncSupport属性。这个属性是布尔值,缺省值是false。

所以,可以在servlet阻塞处理网络,数据库查询等时,可以暂时释放线程资源,处理更多请求,当请求处理完之后重新唤醒线程继续处理原来的请求,达到NIO的效果。

我们看下一个示例

AsyncContext 可以添加监听器作为异步处理过程中状态的跟踪等

 

Java代码 复制代码 收藏代码
  1. import java.io.IOException;   
  2. import java.util.Date;   
  3.   
  4. import javax.servlet.AsyncContext;   
  5. import javax.servlet.AsyncEvent;   
  6. import javax.servlet.AsyncListener;   
  7. import javax.servlet.ServletConfig;   
  8. import javax.servlet.ServletException;   
  9. import javax.servlet.ServletRequest;   
  10. import javax.servlet.annotation.WebServlet;   
  11. import javax.servlet.http.HttpServlet;   
  12. import javax.servlet.http.HttpServletRequest;   
  13. import javax.servlet.http.HttpServletResponse;   
  14.   
  15. @WebServlet(asyncSupported=true,name="asyncServlet", urlPatterns="/async")   
  16. public class AsyncServlet extends HttpServlet{   
  17.   
  18.     /**  
  19.      *   
  20.      */  
  21.     private static final long serialVersionUID = 3903580630389463919L;   
  22.   
  23.     @Override  
  24.     protected void doGet(HttpServletRequest req, HttpServletResponse resp)   
  25.             throws ServletException, IOException {   
  26.         resp.getWriter().write("hello, async test");   
  27.         resp.getWriter().println("start:"+new Date()+".<br/>");    
  28.         resp.getWriter().flush();   
  29.         final AsyncContext async = req.startAsync(req,resp);   
  30.         async.setTimeout(3000);   
  31.         async.start(new Runnable() {   
  32.             @Override  
  33.             public void run() {   
  34.                 ServletRequest request = async.getRequest();   
  35.                 try {   
  36.                     Thread.sleep(2000);   
  37.                     async.getResponse().getWriter().write("aync thread processing");   
  38.                     async.getResponse().getWriter().flush();   
  39.                     async.getResponse().getWriter().println("async end:"+new Date()+".<br/>");    
  40.                     async.getResponse().getWriter().flush();   
  41.                 } catch (InterruptedException e) {   
  42.                     // TODO Auto-generated catch block   
  43.                     e.printStackTrace();   
  44.                 } catch (IOException e) {   
  45.                     // TODO Auto-generated catch block   
  46.                     e.printStackTrace();   
  47.                 }   
  48.             }   
  49.         });   
  50.         async.addListener(new AsyncListener() {   
  51.                
  52.             @Override  
  53.             public void onTimeout(AsyncEvent arg0) throws IOException {   
  54.                 // TODO Auto-generated method stub   
  55.                    
  56.             }   
  57.                
  58.             @Override  
  59.             public void onStartAsync(AsyncEvent arg0) throws IOException {   
  60.                 // TODO Auto-generated method stub   
  61.                    
  62.             }   
  63.                
  64.             @Override  
  65.             public void onError(AsyncEvent arg0) throws IOException {   
  66.                 // TODO Auto-generated method stub   
  67.                    
  68.             }   
  69.                
  70.             @Override  
  71.             public void onComplete(AsyncEvent arg0) throws IOException {   
  72.                 // TODO Auto-generated method stub   
  73.                    
  74.             }   
  75.         });   
  76.         resp.getWriter().println("end:"+new Date()+".<br/>");    
  77.         resp.getWriter().flush();   
  78.             
  79.     }   
  80.   
  81. }  
import java.io.IOException;
import java.util.Date;

import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(asyncSupported=true,name="asyncServlet", urlPatterns="/async")
public class AsyncServlet extends HttpServlet{

	/**
	 * 
	 */
	private static final long serialVersionUID = 3903580630389463919L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		resp.getWriter().write("hello, async test");
		resp.getWriter().println("start:"+new Date()+".<br/>"); 
		resp.getWriter().flush();
		final AsyncContext async = req.startAsync(req,resp);
		async.setTimeout(3000);
		async.start(new Runnable() {
			@Override
			public void run() {
				ServletRequest request = async.getRequest();
				try {
					Thread.sleep(2000);
					async.getResponse().getWriter().write("aync thread processing");
					async.getResponse().getWriter().flush();
					async.getResponse().getWriter().println("async end:"+new Date()+".<br/>"); 
					async.getResponse().getWriter().flush();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
		async.addListener(new AsyncListener() {
			
			@Override
			public void onTimeout(AsyncEvent arg0) throws IOException {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void onStartAsync(AsyncEvent arg0) throws IOException {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void onError(AsyncEvent arg0) throws IOException {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void onComplete(AsyncEvent arg0) throws IOException {
				// TODO Auto-generated method stub
				
			}
		});
		resp.getWriter().println("end:"+new Date()+".<br/>"); 
		resp.getWriter().flush();
		 
	}

}

 输出如下: 这里先对线程后面的println先输出,最后在处理输出异步线程输出的内容。

 

Java代码 复制代码 收藏代码
  1. hello, async teststart?Mon Dec 10 20:23:35 CST 2012.   
  2. end?Mon Dec 10 20:23:35 CST 2012.   
  3. aync thread processingasync end?Mon Dec 10 20:23:37 CST 2012.  
hello, async teststart?Mon Dec 10 20:23:35 CST 2012.
end?Mon Dec 10 20:23:35 CST 2012.
aync thread processingasync end?Mon Dec 10 20:23:37 CST 2012.
 


这里有个主意点,对于servlet配置了asyncSupported=true,那么对于所有异步经过的filter也需要配置这个参数,否则这里会报错,不支持异步处理。

 

 

4.@MultipartConfig 文件上传的支持,以前servlet要处理上传文件一般会使用common file upload组件,现在servlet3.0原生支持了文件上传的处理

 location参数指定临时文件存放目录,

 

Java代码 复制代码 收藏代码
  1. import java.io.IOException;   
  2.   
  3. import javax.servlet.ServletException;   
  4. import javax.servlet.annotation.MultipartConfig;   
  5. import javax.servlet.annotation.WebServlet;   
  6. import javax.servlet.http.HttpServlet;   
  7. import javax.servlet.http.HttpServletRequest;   
  8. import javax.servlet.http.HttpServletResponse;   
  9. import javax.servlet.http.Part;   
  10.   
  11.   
  12. @WebServlet(asyncSupported=true,name="upload", urlPatterns="/upload")   
  13. @MultipartConfig(fileSizeThreshold = 10000, maxFileSize = 1000000, maxRequestSize = 1000000, location="E:/logs")   
  14. public class MultiPartServlet3 extends HttpServlet {   
  15.   
  16.     /**  
  17.      *   
  18.      */  
  19.     private static final long serialVersionUID = 7306582588845300635L;   
  20.   
  21.     @Override  
  22.     protected void doPost(HttpServletRequest req, HttpServletResponse resp)   
  23.             throws ServletException, IOException {   
  24.         Part part = req.getPart("file");   
  25.         String value = part.getHeader("content-disposition");   
  26.         System.out.println(value);   
  27.         String filename = value.substring(value.lastIndexOf("=") + 2,value.length() - 1);   
  28.         System.out.println(filename);   
  29.         System.out.println(part.getInputStream().toString());   
  30.     }   
  31.   
  32. }  
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;


@WebServlet(asyncSupported=true,name="upload", urlPatterns="/upload")
@MultipartConfig(fileSizeThreshold = 10000, maxFileSize = 1000000, maxRequestSize = 1000000, location="E:/logs")
public class MultiPartServlet3 extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 7306582588845300635L;

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		Part part = req.getPart("file");
		String value = part.getHeader("content-disposition");
		System.out.println(value);
		String filename = value.substring(value.lastIndexOf("=") + 2,value.length() - 1);
		System.out.println(filename);
		System.out.println(part.getInputStream().toString());
	}

}

 我们写一个文件上传的页面

 

Java代码 复制代码 收藏代码
  1. <form action="upload" method="post" enctype="multipart/form-data">   
  2.     <input type="file" name="file"><br> <input type="submit"  
  3.         value="submit">   
  4. </form>  
<form action="upload" method="post" enctype="multipart/form-data">
	<input type="file" name="file"><br> <input type="submit"
		value="submit">
</form>

 随便上传一个文件,我这边的输出为:

 

Java代码 复制代码 收藏代码
  1. form-data; name="file"; filename="22.log"  
  2. 22.log   
  3. java.io.ByteArrayInputStream@1bdce67  
form-data; name="file"; filename="22.log"
22.log
java.io.ByteArrayInputStream@1bdce67

 5.已有API改进,特别是支持动态加载servlet,热部署功能

 

Java代码 复制代码 收藏代码
  1. HttpServletRequest    
  2. To support the multipart/form-data MIME type, the following methods have been added to the HttpServletRequest interface:    
  3. 为了支持multipart/form-data MIME类型,在HttpServletRequest接口中添加了项目的方法:    
  4.     * Iterable<Part> getParts()    
  5.     * Part getPart(String name)    
  6. Cookies    
  7. 为了避免一些跨站点攻击,Servlet3.0支持HttpOnly的cookie。HttpOnly cookie不想客户端暴露script代码。Servlet3.0在Cookie类中添加了如下的方法来支持HttpOnly cookie:    
  8.     * void setHttpOnly(boolean isHttpOnly)    
  9.     * boolean isHttpOnly()    
  10. ServletContext    
  11. 通过在ServletContext中添加下面的方法,Servlet3.0允许Servlet或filter被编程的加入到context中:    
  12.     * addServlet(String servletName, String className)    
  13.     * addServlet(String servletName, Servlet servlet)    
  14.     * addServlet(String servletName, Class<? extends Servlet> servletClass)    
  15.     * addFilter(String filterName, String className)    
  16.     * addFilter(String filterName, Filter filter)    
  17.     * addFilter(String filterName, Class<? extends Filter>filterClass)    
  18.     * setInitParameter (String name, String Value)  
HttpServletRequest 
To support the multipart/form-data MIME type, the following methods have been added to the HttpServletRequest interface: 
为了支持multipart/form-data MIME类型,在HttpServletRequest接口中添加了项目的方法: 
    * Iterable<Part> getParts() 
    * Part getPart(String name) 
Cookies 
为了避免一些跨站点攻击,Servlet3.0支持HttpOnly的cookie。HttpOnly cookie不想客户端暴露script代码。Servlet3.0在Cookie类中添加了如下的方法来支持HttpOnly cookie: 
    * void setHttpOnly(boolean isHttpOnly) 
    * boolean isHttpOnly() 
ServletContext 
通过在ServletContext中添加下面的方法,Servlet3.0允许Servlet或filter被编程的加入到context中: 
    * addServlet(String servletName, String className) 
    * addServlet(String servletName, Servlet servlet) 
    * addServlet(String servletName, Class<? extends Servlet> servletClass) 
    * addFilter(String filterName, String className) 
    * addFilter(String filterName, Filter filter) 
    * addFilter(String filterName, Class<? extends Filter>filterClass) 
    * setInitParameter (String name, String Value)
 


下面这篇文章还是比较全面的解析

 

http://www.ibm.com/developerworks/cn/java/j-lo-servlet30/index.html

http://www.infoq.com/cn/news/2007/06/servlet3

分享到:
评论

相关推荐

    Servlet3.0新特性解析

    Servlet3.0新特性解析_03_Servlet3.0监听器、过滤器实现方式详解及Servlet的动态注册剖析

    servlet 3.0新增功能详解

    Servlet 是 Java EE 规范体系的重要组成部分,也是 Java 开发人员必须具备的基础...本文主要介绍了 Servlet 3.0 引入的若干重要新特性,包括异步处理、新增的注解支持、可插性支持等等,为读者顺利向新版本过渡扫清障碍

    Servlet3.0新特性解析01

    Servlet3.0新特性解析_01_Servlet3.0新特性深度解析、Servlet注解详解

    Servlet3.0特性详解

    非常好的学习Servlet3.0资料。特此共享。

    Servlet3.0_新特性

    Servlet3.0_新特性详解

    Servlet3.0

    Servlet3.0新特性解析_02_Servlet3.0的异步支持与反向Ajax深入详解Servlet3.0新特性解析_02_Servlet3.0的异步支持与反向Ajax深入详解

    基于Servlet3.0+IBatis+BootStrip技术构建简单会议管理系统

    第03课 servlet3.0新特性之@WebServlet_@WebInitParam详解 第04课 servlet3.0新特性之@WebFilter_@WebListener 第05课 JQuery AJAX 注册验证+二级菜单(JSON) 第06课 mybatis 框架搭建 第07课 mybatis 增删改查 第...

    详解Servlet3.0新特性(从注解配置到websocket编程)

    Servlet3.0的出现是servlet史上最大的变革,其中的许多新特性大大的简化了web应用的开发,为广大劳苦的程序员减轻了压力,提高了web开发的效率。

    Java Web开发详解:XML+DTD+XML Schema+XSLT+Servlet3.0+JSP2.2深入剖析与实例应用/孙鑫编著

    《Java Web开发详解——XML+DTD+XML Schema+XSLT+Servlet3.0+JSP2.2深入剖析与实例应用》内容全面,涵盖了从事Java Web开发所应掌握的所有知识,同时还讲解了最新的Servlet 3.0和JSP 2.2规范新增的特性。在知识的...

    J2EE应用开发详解

    172 10.5 小结 177 第11章 EJB 179 11.1 EJB简介 179 11.1.1 EJB的特点 179 11.1.2 EJB类型与组成 180 11.1.3 EJB 3.0的新特性 181 11.2 元数据注释和部署描述符 181 11.2.1 元数据注释 181 11.2.2 部署描述符 182 ...

    Spring.3.x企业应用开发实战(完整版).part2

     Spring3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架、REST风格的Web编程模型等。这些新功能实用性强、易用性高,可大幅降低Java应用,特别是JavaWeb应用开发的难度,同时有效提升...

    Spring3.x企业应用开发实战(完整版) part1

     Spring3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架、REST风格的Web编程模型等。这些新功能实用性强、易用性高,可大幅降低Java应用,特别是JavaWeb应用开发的难度,同时有效提升...

Global site tag (gtag.js) - Google Analytics