一、servlet3.0 新特性
想要使用 servlet3.0 新特性必须使用 Tomcat7 及以上版本。
Servlet3.0 新增特性:
(1)注解支持;Servlet、Filter、Listener 无需在 web.xml 中进行配置,可以通过对应注解进行配置;
(2)支持 Web 模块;
(3)Servlet 异步处理;
(4)文件上传 API 简化;
Servlet3.0 的注解:
(1)@WebServlet :修饰 Servlet 类,用于部署该 Servlet 类;
(2)@WebFilter:修饰 Filter 类,用于部署该 Filter 类;
(3)@WebInitParam:与@WebServlet 或@WebFilter 注解连用,为它们配置参数;
(4)@MultipartConfig:修饰 Servlet 类,指定该 Servlet 类负责处理 multipart/form-data 类型的请求(主要用于处理上传文件);
(5)@ServletSecurity:修饰 Servlet 类,与 JAAS(Java 验证和授权 API)有关的注解;
(6)@HttpConstrait:与@ServletSecurity 连用;
(7)@HttpMethodConstrait:与@ServletSecurity 连用;
ServletContext 提供了如下方法动态注册 Servlet、Filter
addServlet(); 动态注册 Servlet
addFilter(); 动态注册 Filter
addListener(); 动态注册 Listener
setInitParameter(String name ,String value); 为 Web 应用设置初始化参数。
二、@WebServlet
@WebServlet 用于将一个类声明为 Servlet,该标注将会在部署时被容器处理,容器将根据具体的属性配置将相应的类部署为 Servlet。
@WebServlet(name = "servlet3annotation", urlPatterns = {"/servlet3"},
description = "servletinfo", displayName = "abc", asyncSupported = true, loadOnStartup = -1,
initParams = {@WebInitParam(name = "username", value = "YangYuqin")})
public class Servlet3Annotation extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取ServletConfig的实例
ServletConfig config = this.getServletConfig();
//获取指定参数名称的值
String name = config.getInitParameter("username");
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.println("<html>");
out.println("<head><title>Servlet3应用实例</title></head>");
out.println("<body>");
out.print("获取InitParamServlet的初始化参数\"username\"的字符串值:" + name);
out.println("</body>");
out.println("</html>");
}
@Override
public void destroy() {
//空
}
@Override
public void init() throws ServletException {
//空
}
}
三、@WebFilter
@WebFilter 用于将一个类声明为过滤器,该标注将会在部署时被容器处理。以下属性均为可选属性,但是 value、urlPatterns、servletNames 三者必需至少包含一个,且 value 和 urlPattern 不能共存,如果同时指定,通常忽略 value 的取值。
![](https://files.mdnice.com/user/27110/3f193385-aa04-471c-afc8-d209d3cbbd55.png)
示例:
@WebFilter(servletNames = {"servlet3filterannotation"}, filterName = "characterFilter",
initParams = {@WebInitParam(name = "encoding", value = "UTF-8")})
public class Servlet3FilterAnnotation implements Filter {
private FilterConfig filterConfig = null;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//获取此Filter的初始参数的值
String encoding = filterConfig.getInitParameter("encoding");
System.out.println(encoding);
//设置请求数据的编码方式
servletRequest.setCharacterEncoding(encoding);
//把请求和响应对象传给过滤链中的下一个要调用的过滤器或Servlet
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
//空
}
}
四、@WebListener
该标注用于将类声明为监听器。
![](https://files.mdnice.com/user/27110/a688a76a-ebec-4e73-860b-1efa7fe521d2.png)
示例:
//监听项目的启动和停止
@WebListener
public class MyListener implements ServletContextListener {
//监听ServletContext启动初始化
@Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext servletContext = sce.getServletContext();
System.out.println("MyListener...contextInitialized...");
}
//监听ServletContext销毁
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("MyListener...contextDestroyed...");
}
}
五、@WebInitParam
@WebInitParam 标注通常不单独使用,而是配合@WebServlet 或者@WebFilter 使用。它的作业是为 Servlet 或者过滤器指定初始化参数,这等价于 web.xml 中<servlet>
和<filter>
的<init-param>
子标签。
![](https://files.mdnice.com/user/27110/b74aa94b-68ef-4bba-b356-49d85320e50f.png)
六、@MultipartConfig
该标注主要是为了辅助 Servlet3.0 中 HttpServletRequest 提供的对上传文件的支持。该标注标注在 Servlet 上,表示该 Servlet 希望处理的请求的 MIME 类型是 multipart/form-data
。
相应 servlet 的 HttpServletRequest 对象必须通过 getParts 和 getPart 方法使 mime 附件可用来遍历各种 mime 附件,多用于表单上传。
![](https://files.mdnice.com/user/27110/2b7ba2ca-af10-4fb0-afdd-9054d63d9a9f.png)
- 改进内容
(1)HttpServletRequest 增加了对上传文件的支持
(2)ServletContext 允许通过编程的方式动态注册 Servlet、Filter
- HttpServletRequest 提供了如下两个方法处理文件的上传
Part getPart(String name) 根据名称获取文件上传域
Collection getParts() 获取所有文件上传域
3、上传文件时一定要为表单域设置 enctype 属性,它表示表单数据的编码方式,有如下三个值:
(1)application/x-www-form-urlencoded
(默认),它只处理表单里的 value 属性值,它会将 value 值处理成 URL 编码方式。如果此时表单域里有上传文件的域(type=”file”),则只会获取该文件在上传者电脑里的绝对路径串,该串没什么实际意义;
(2)multipart/form-data
此处编码方式会以二制流的方式来处理表单数据,此时会将文件内容也封装到请求参数里;
(3)texst/plain
当表单的 action 属性为mailto:URL的形式时比较方便,主要适用于直接通过表单发送邮件的方式上传文件的Servlet需要加上@MultipartConfig
注解通过request获取的Part对象就可以操作文件域了;
4、上传文件的 Servlet 需要加上 @MultipartConfig
注解
5、通过 request 获取的 Part 对象就可以操作文件域了
示例:
@WebServlet(name="uploadServlet",urlPatterns="/upload")
@MultipartConfig
public class UploaderServlet extends HttpServlet {
@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
//获得Par对象(每个Part对象对应一个文件域)
Part part = request.getPart("file");
long size = part.getSize(); //获取上传文件大小
String info = part.getHeader("content-disposition");//获得包含原始文件名的字符串
//获取原始文件名
String fileName = info.substring(info.indexOf("filename=\"")+10,info.length()-1);
//将文件上传到某个位置
part.write(getServletContext().getRealPath("/uploadFiles")+"/"+fileName);
}
}