Serlvet3.0 注解 浅析

本文介绍了Servlet3.0的主要特性,包括使用注解简化部署描述、支持异步调用提高响应速度及简化文件上传过程。并通过示例代码详细解释了这些特性的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(1)注解配置

一、Servlet3.0介绍

Servlet3.0是Java EE6规范的一部分,Servlet3.0提供了注解(annotation),使得不再需要在web.xml文件中进行Servlet的部署描述,简化开发流程。

二、开发Servlet3.0程序的所需要的环境

开发Servlet3.0的程序需要一定的环境支持。MyEclipse10和Tomcat7都提供了对Java EE6规范的支持。若用低版本时需要手动配置环境
所以开发Servlet3.0的程序需要以下的开发环境支持:
- IDE:MyEclipse 10+
- JDK:JDK 1.6+
- tomcat:tomcat 7+

import java.io.IOException;  
import javax.servlet.ServletException;  
import javax.servlet.annotation.WebServlet;  
import javax.servlet.http.HttpServlet;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  

/**  
 * 注解WebServlet用来描述一个Servlet  
 * 属性name描述Servlet的名字,可选  
 * 属性urlPatterns定义访问的URL,或者使用属性value定义访问的URL.(定义访问的URL是必选属性)  
 * //注解配置  
@WebServlet(  
displayName = "UserServlet" , //描述  
name = "UserServlet", //servlet名称  
urlPatterns = { "/user" }, //url  
loadOnStartup = 1, //启动项  
initParams = { @WebInitParam(name = "username", value = "张三") }  
)//初始化参数  
 */  
@WebServlet(name="Servlet3Demo",urlPatterns="/Servlet3Demo")  
public class Servlet3Demo extends HttpServlet {  

    public void doGet(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        response.getWriter().write("Hello Servlet3.0");  
    }  

    public void doPost(HttpServletRequest request, HttpServletResponse response)  
            throws ServletException, IOException {  
        this.doGet(request, response);  
    }  
}  

/*  
 * 完成了一个使用注解描述的Servlet程序开发。  
  使用@WebServlet将一个继承于javax.servlet.http.HttpServlet的类定义为Servlet组件。  
  @WebServlet有很多的属性:  
      1、asyncSupported:    声明Servlet是否支持异步操作模式。  
      2、description:      Servlet的描述。  
      3、displayName:       Servlet的显示名称。  
      4、initParams:        Servlet的init参数。  
      5、name:           Servlet的名称。  
      6、urlPatterns:     Servlet的访问URL。  
      7、value:           Servlet的访问URL。  
  Servlet的访问URL是Servlet的必选属性,可以选择使用urlPatterns或者value定义。  
  像上面的Servlet3Demo可以描述成@WebServlet(name="Servlet3Demo",value="/Servlet3Demo")。  
  也定义多个URL访问:  
  如@WebServlet(name="Servlet3Demo",urlPatterns={"/Servlet3Demo","/Servlet3Demo2"})  
  或者@WebServlet(name="AnnotationServlet",value={"/Servlet3Demo","/Servlet3Demo2"})  
 *  
 */  

(2)异步调用

在Servlet3.0中,在Servlet内部支持异步处理。它的逻辑是当我们请求一个Servlet时,我们的Servlet可以先返回一部分内容给客户端。然后在Servlet内部异步处理另外一段逻辑,等到异步处理完成之后,再把异步处理的结果返回给客户端。
注: 异步处理费时的业务

@WebServlet(value="/s3", asyncSupported=true)
public class servlet3 extends HttpServlet{
    @Override
    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //请求
        request.setCharacterEncoding("utf-8");
        //响应
        response.setContentType("text/html;charset=utf-8");
        final PrintWriter out=response.getWriter();
        out.println("<p>异步之前输出的内容。</p>");  
        out.flush();  

        //开始异步调用,获取对应的AsyncContext。  
          final AsyncContext asyncContext = request.startAsync();  
          //设置超时时间,当超时之后程序会尝试重新执行异步任务,即我们新起的线程。  
          asyncContext.setTimeout(10*1000L);  
          //新起线程开始异步调用,start方法不是阻塞式的,它会新起一个线程来启动Runnable接口,之后主程序会继续执行  
          asyncContext.start(new Runnable() {  
             public void run() {  
                try {  
                    Thread.sleep(5*1000L);  
                    out.println("<p style='border:1px solid blue;'>异步调用之后输出的内容。</p>");  
                    out.flush();  
                    //异步调用完成,如果异步调用完成后不调用complete()方法的话,异步调用的结果需要等到设置的超时  
                    //时间过了之后才能返回到客户端。  
                    asyncContext.complete();  
                } catch (Exception e) {  
                    e.printStackTrace();  
                }  
             }  

          });  
          out.println("<p style='border:1px solid red;'>可能在异步调用前输出,也可能在异步调用之后输出,因为异步调用会新起一个线程。</p>");  
          out.flush();  
    }

}

异步调用监听器

   当我们需要对异步调用做一个详细的监听的时候,比如监听它是否超时,我们可以通过给AsyncContext设置对应的监听器AsyncListener来实现这一功能。AsyncListener是一个接口,里面定义了四个方法,分别是针对于异步调用开始、结束、出错和超时的。

(3)文件上传

在Servlet3.0中上传文件变得非常简单。我们只需通过request的getPart(String partName)获取到上传的对应文件对应的Part或者通过getParts()方法获取到所有上传文件对应的Part。之后我们就可以通过part的write(String fileName)方法把对应文件写入到磁盘。或者通过part的getInputStream()方法获取文件对应的输入流,然后再对该输入流进行操作。要使用request的getPart()或getParts()方法对上传的文件进行操作的话,有两个要注意的地方。首先,用于上传文件的form表单的enctype必须为multipart/form-data;其次,对于使用注解声明的Servlet,我们必须在其对应类上使用@MultipartConfig进行标注,而对于在web.xml文件进行配置的Servlet我们也需要指定其multipart-config属性,如:

xml代码:

<servlet>  
   <servlet-name>xxx</servlet-name>  
   <servlet-class>xxx.xxx</servlet-class>  
   <multipart-config></multipart-config>  
</servlet>  
<servlet-mapping>  
   <servlet-name>xxx</servlet-name>  
   <url-pattern>/servlet/xxx</url-pattern>  
</servlet-mapping> 
  file-size-threshold:数字类型,当文件大小超过指定的大小后将写入到硬盘上。默认是0,表示所有大小的文件上传后都会作为一个临时文件写入到硬盘上。

  location:指定上传文件存放的目录。当我们指定了location后,我们在调用Part的write(String fileName)方法把文件写入到硬盘的时候可以,文件名称可以不用带路径,但是如果fileName带了绝对路径,那将以fileName所带路径为准把文件写入磁盘。

  max-file-size:数值类型,表示单个文件的最大大小。默认为-1,表示不限制。当有单个文件的大小超过了max-file-size指定的值时将抛出IllegalStateException异常。

  max-request-size:数值类型,表示一次上传文件的最大大小。默认为-1,表示不限制。当上传时所有文件的大小超过了max-request-size时也将抛出IllegalStateException异常。



上面的属性是针对于web.xml中配置Servlet而言的,其中的每一个属性都对应了multipart-config元素下的一个子元素。对于基于注解配置的Servlet而言,@MultipartConfig的属性是类型的,我们只需把上述对应属性中间的杠去掉,然后把对应字母大写即可,如maxFileSize。 
@WebServlet("/servlet/upload")  
@MultipartConfig  
public class FileUploadServlet extends HttpServlet {  

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

   @Override  
   protected void doPost(HttpServletRequest req, HttpServletResponse resp)  
         throws ServletException, IOException {  
      req.setCharacterEncoding("UTF-8");  
      Part part = req.getPart("upload");  
      //格式如:form-data; name="upload"; filename="YNote.exe"  
      String disposition = part.getHeader("content-disposition");  
      System.out.println(disposition);  
      String fileName = disposition.substring(disposition.lastIndexOf("=")+2, disposition.length()-1);  
      String fileType = part.getContentType();  
      long fileSize = part.getSize();  
      System.out.println("fileName: " + fileName);  
      System.out.println("fileType: " + fileType);  
      System.out.println("fileSize: " + fileSize);  
      String uploadPath = req.getServletContext().getRealPath("/upload");  
      System.out.println("uploadPath" + uploadPath);  
      part.write(uploadPath + File.separator +fileName);  
   }  

}  


       对于Servlet3.0中的文件上传还有一个需要注意的地方,当我们把Part写入到硬盘以后,我们原先的Part(也就是之前的临时文件)可能已经删了,这个时候如果我们再次去访问Part的内容的话,那它就是空的,系统会抛出异常说找不到对应的文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

冰河家园

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值