tomcat 7以上的版本都支持Servlet 3.0
示例代码片:
修饰过滤器Filter:
@WebFilter(
filterName="log",
urlPatterns={"/*"},
initParams={
@WebInitParam(name="encoding",value="GBK"),
@WebInitParam(name="loginPage",value="/login.jsp")
})
public class MyFilter implements Filter {
//内容省略......
}
修饰servlet:
@WebServlet(name="test",
urlPatterns={"/basic.do"},
initParams={
@WebInitParam(name="userName",value="peter"),
@WebInitParam(name="age",value="100")
})
public class TestServlet extends HttpServlet{
//内容省略....
}
修饰监听器Listener:
@WebListener
public class MyRequestListener implements ServletRequestListener{
//内容省略...
}
制作一个Servlet模块的步骤:
web-fragment.xml说明:
为根元素;
表示模块名称(模块的唯一标识);
定义模块加载顺序的标签,当然可以不设置模块加载顺序;
表示在所有模块前面加载(第一个加载);A
表示在A模块后面加载;
标签指定的模块加载顺序将会覆盖web模块的web-fragment.xml文件中指定的加载顺序。如何用myEclipse打jar包(有些人不知道)
右键你web项目里的编写的servlet(或filter或listener)类——>Export…——>JAR file——>NEXT——>(Browse)填写导出名字和存放位置——>finish
这样就生成了我们需要的jar包了
@WebServlet(name="test",urlPatterns={"/basic.do"})
public class TestServlet extends HttpServlet{
//使用该方法可响应客户端的所有请求
public void service(HttpServletRequest req, HttpServletResponse resp)throws IOException{
System.out.println("进servlet了");
PrintStream out = new PrintStream(resp.getOutputStream());
//向页面输入下面字符串
out.print("1234567890");
}
}
web-fragment.xml代码片
<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>mySerModulename>
<ordering>
<before>
<others/>
before>
ordering>
web-fragment>
在web-fragment.xml里的配置和之前的web.xml里类似,如果是注解实现的servlet的配置,则在web-fragment.xml里就将不再写配置了,如果不是,则还需要写配置。
打成jar包放在一个项目里面启动后,就可通过上面servlet注解配置的/basic.do路径访问上面的servle了。
在以前的servlet中,如果作为控制器的servlet调用了一个较为耗时的业务方法,则servlet必须等到业务执行完后才会生成响应,这使得这次调用成了阻塞式调用,效率比较差
重新开一个线程单独去调用耗时的业务方法。
<servlet>
<servlet-name>test1servlet-name>
<servlet-class>com.zrgk.servlet.AsyncServletservlet-class>
<async-suppored>trueasync-suppored>
servlet>
<servlet-mapping>
<servlet-name>test1servlet-name>
<url-pattern>/basic.dourl-pattern>
servlet-mapping>
java代码:
@WebServlet(name="AsyncServlet",urlPatterns={"/testAsyn.do"},asyncSupported=true)
public class AsyncServlet extends HttpServlet{
public void service(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException{
//解决乱码
request.setCharacterEncoding("GBK");
response.setContentType("text/html;charset=GBK");
//通过request获得AsyncContent对象
AsyncContext actx = request.startAsync(); //重点方法**
//设置异步调用超时时长
actx.setTimeout(30*3000);
//启动异步调用的线程
actx.start(new MyThread(actx));//重点方法**
// 直接输出到页面的内容(不等异步完成就直接给页面)
//但这些内容必须放在标签内,否则会在页面输出错误内容,这儿反正我测试是这样,具体不知对不对??
PrintWriter out = response.getWriter();
out.println("不等异步返回结果就直接返到页面的内容
");
out.flush();
}
}
//异步处理业务的线程类
public class MyThread implements Runnable {
private AsyncContext actx;
//构造
public MyThread(AsyncContext actx){
this.actx = actx;
}
public void run(){
try{
//等待5秒,模拟处理耗时的业务
Thread.sleep(4*1000);
//获得request对象,添加数据给页面
ServletRequest req = actx.getRequest();
req.setAttribute("content","异步获得的数据");
//将请求dispath到index.jsp页面,该页面的session必须设为false
actx.dispatch("/index.jsp");
}catch(Exception e){
e.printStackTrace();
}
}
}
页面代码(页头里session设为false,表时该页面不会再创建session):
<%@ page language="java" import="java.util.*" pageEncoding="utf-8" session="false"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<html>
<body>
<a href="<%=basePath%>/testAsyn.do">测试异步调用a>
异步结果:${content}
body>
html>
异步监听器用来监听异步Servlet的异步处理事件,通过实现AsyncListener接口实现,代码如下:
public class MyAsyncListener implements AsyncListener{
//异步调用完成时触发
@Override
public void onComplete(AsyncEvent event) throws IOException {
// 省略....
}
//异步调用出错时触发
@Override
public void onError(AsyncEvent event) throws IOException {
// 省略....
}
//异步调用开始触发
@Override
public void onStartAsync(AsyncEvent event) throws IOException {
// 省略....
}
//异步调用超时触发
@Override
public void onTimeout(AsyncEvent event) throws IOException {
// 省略....
}
}
还需要在异步Servlet里注册异步监听器,即添加如下代码即可:
actx.addListener(new MyAsyncListener());
Filter异步调用与Servlet一样。
Part getPart(String name)
根据名称获取文件上传域Collection getParts()
获取所有文件上传域@WebServlet(name="uploadServlet",urlPatterns="/upload.do")
@MultipartConfig
public class UploaderServlet extends HttpServlet {
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);
}
}
ServletContext提供了如下方法动态注册Servlet、Filter
addServlet(); 动态注册Servlet
addFilter(); 动态注册Filter
addListener(); 动态注册Listener
setInitParameter(String name ,String value); 为Web应用设置初始化参数。