Servlet就是运行在服务器端的程序,用来处理客户端的请求并且响应数据给回浏览器的动态web资源技术
Servlet相对于普通Java类程序:
普通Java类需要main方法才能调用运行,而Servlet是由Tomcat服务器调用,不需要main方法
Servlet可以接受用户的请求数据和响应数据给浏览器传输数据
Servlet3.0相较于Servlet2.5优化了在web.xml文件作配置的繁琐步骤,只需在Servlet实现类上加上注解@WebServlet即可配置
@WebServlet 的两个参数:
name:别名,可以省略
url-pattern:servlet的访问路径
@WebServlet(name = "TestServlet", urlPatterns = "/test")
public class testServlet implements Servlet {
public void init(ServletConfig servletConfig) throws ServletException {
}
public ServletConfig getServletConfig() {
return null;
}
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}
public String getServletInfo() {
return null;
}
public void destroy() {
}
}
Servlet的生命周期:
init():初始化方法
service():处理请求和响应数据的主方法
destory():销毁当前Servlet方法
Servlet的设计采用的是单例设计模式,servlet对象在内存中只有一个对象
浏览器第一次向此路径的Servlet发送请求时,服务器会调用1次构造方法
然后执行1次init()初始化Servlet的方法
再执行一次service()方法,传入request,response对象,执行完将response对象返回给浏览器
下次再次访问此Servlet路径时,只会调用n次service()方法,无需再初始化
最后关闭服务器时,会调用1次destory()销毁创建的Servlet对象
Servlet接口有一个子类GenericServlet类
该类简化了Servlet的初始化与销毁等方法,所以继承此类的Servlet仅需重写service()方法即可
弊处:此方法和Servlet接口一样,都会将get方法和post方法统一使用service来处理
所以有了GenericServlet的子类HttpServlet类
该类相较于父类的优点,再次优化了service()方法,分为doGet()和doPost()方法
让浏览器中使用不同的提交方式,也能有不同的处理方式
@WebServlet(name = "UserServlet", urlPatterns = "/user")
public class UserServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
一个类实现了Filter并重写init()、doFilter()、destory()方法,且在类上使用@WebFilter注解修饰
@WebFilter(filterName = "Test2Filter")
public class Test2Filter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
}
}
拦截器的处理流程:
拦截器的生命周期:
过滤器部署到服务器后,只要服务器一开启就会执行1次init()初始化方法
浏览器发送n次请求,只要拦截器路径相同,则会调用n次doFilter()拦截方法
当服务器关闭时,就会调用1次destory()销毁拦截器方法
@WebFilter注解其中有2个较重要的属性
urlPatterns:表示需要过滤的路径地址,可以写精确的路径,也可以写/*表示拦截所有资源
dispatcherTypes:表示拦截的方式,可以指定多个值用数组的形式表示
DispatcherType.FORWARD:过滤转发跳转访问的方式
DispatcherType.REQUEST:过滤直接在url地址上访问资源的方式
譬如使用post提交请求中文数据时,会出现乱码,和响应中文数据到浏览器时也会出现乱码
就可以使用拦截器Filter统一设置解码类型解决乱码问题
@WebFilter(filterName = "TestFilter", urlPatterns = "/*", dispatcherTypes = {DispatcherType.FORWARD, DispatcherType.REQUEST})
public class TestFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
//将ServletRequest和ServletResponse对象强转为
// HttpServletRequest和HttpServletResponse 以获得可调用的方法
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
//解决post方式请求的数据出现中文乱码
if ("post".equalsIgnoreCase(request.getMethod().trim())) {
request.setCharacterEncoding("utf-8");
}
//解决response中文数据出现乱码
response.setContentType("text/html;charset=utf-8");
chain.doFilter(request, response);
}
public void init(FilterConfig config) throws ServletException {
}
}
实现ServletContextListener,HttpSessionListener,HttpSessionAttributeListener接口的类,通常称为监听器
顾名思义,监听器是用来监听ServletContext全局共享域对象和Session会话域对象的变化的
接口中就有其中两个方法,用于监听全局共享域的创建与销毁状态
void contextDestroyed(ServletContextEvent sce) 监听servletcontext销毁
void contextInitialized(ServletContextEvent sce) 监听servletcontext创建
由于服务器一启动就会自动创建ServletContext对象,所以有了监听器
可以让服务器启动时调用contextInitialized方法,在关闭服务器时调用contextDestroyed方法
void attributeAdded(ServletContextAttributeEvent scab) 监听属性添加到servletcontext中
void attributeRemoved(ServletContextAttributeEvent scab) 监听属性从servletcontext中移除
void attributeReplaced(ServletContextAttributeEvent scab) 监听属性从servletcontext中被替换
在Added方法中使用参数调用getName()和getValue()方法就能获取存数据进全局域时候的数据
Removed则为删除数据时,Replaced则为替换数据时
void sessionCreated(HttpSessionEvent se )
void sessionDestroyed(HttpSessionEvent se)
则为监听Session对象的创建和删除的方法
实际开发中,常用作监听统计当前在线人数的总数:
当前session会话被创建,当前在线用户+1
每当session会话被销毁,当前在线用户-1。