学习内容:学习JavaWeb(Day38)
1、Servlet
2、Filter过滤器
3、Listener监听器
1、Servlet
(1)servlet的生命周期:实例化、初始化、服务、销毁。
1.容器会创建servlet的实例,调用init()方法进行初始化
2.容器调用service()方法接收请求,判断是get请求还是post请求,如果是get请求,转发到doGet()方法,如果是post请求,转发到doPost()方法
3.调用doGet()或doPost()方法处理请求
4.响应给客户端浏览器
5.如果服务关闭,会调用destroy()方法销毁servlet实例
init()、service()、destroy()这三个方法称为生命周期方法,init()、destroy()只在第一次请求时执行,service()每次请求都会执行。
(2)容器创建servlet的实例后,调用service()方法接收请求,每次请求容器都会分配一个线程,因此service()方法内并发的线程如果访问了同一个资源的话,就有可能引发线程安全问题。
(3)B/S:浏览器/服务器架构
C/S:客户端/服务器架构
(4)servlet2.5基于配置文件实现
servlet3以上基于注解实现
(5)url:统一资源定位符 http://locahost:8080/newssystem/images/banner.jpg
uri:资源路径 /images/banner.jpg
(6)url重写
http://locahost:8080/newssystem/index.jsp?id=1
重写后url变为http://locahost:8080/newssystem/1.jsp
(7)除了欢迎页的所有jsp页面都要放在WEB-INF目录下,访问jsp都要经过servlet。
(8)重定向和请求转发都是get请求,只有表单提交是显示声明method为post的才是post请求,其它都是get请求。
(10)在Web.xml中配置Servlet,servlet-name必须相同。
<servlet>
<servlet-name>AppSerlvet</servlet-name>
<servlet-class>com.xixingit.web.AppSerlvet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>AppSerlvet</servlet-name>
<url-pattern>/home</url-pattern>
</servlet-mapping>
(11)标签<load-on-startup>,容器启动时就加载这个servlet,值越小优先级越高,如果值为负数或没有设置,则容器在servlet被请求时再加载
<servlet>
//值是正整数,值越小就越先创建
<load-on-startup>1</load-on-startup>
</servlet>
(12)标签<init-param>,配置初始化参数
<servlet>
<init-param>
<param-name>main</param-name>
<param-value>jean@xixingit.com</param-value>
</init-param>
</servlet>
(13)标签<session-config>,设置session过期时间
<!--设置session过期时间-->
<session-config>
<session-timeout>20</session-timeout>
</session-config>
(14)通过ServletConfig获取Servlet的初始化参数
ServletConfig config = getServletConfig();
String mail = config.getInitParameter("main");
//获取servlet节点中所有的init-param中的param-name节点值
Enumeration<String> e = config.getInitParameterNames();
while(e.hasMoreElements()) {
String key = e.nextElement();
String value = config.getInitParameter(key);
System.out.println(key + " : " + value);
}
(15)MVC模型指的是模型-视图-控制器(Model-View-Controller)。
MVC模型有助于将应用程序分割为三个组件,使得程序设计更加容易,并使各个组件之间的耦合度降到最低。
MVC中三个组件分别为:模型(Model)、视图(View)和控制器(Controller)
(16)Servlet容器默认是采用单实例多线程的方式处理多个请求的,如果存在成员变量,可能发生多线程同时访问该资源时,都来操作它,照成数据的不一致,因此产生线程安全问题。
成员变量改成局部变量,那么所有的线程都会有一份,不会造成线程安全。
可以使用synchronized在单例对象servlet上面加锁。
2、Filter过滤器
(1)每次请求都需要经过过滤器,Filter过滤器是双向过滤,请求和响应都要经过过滤方法。多个过滤器可以组成过滤器链。
(3)实现页面用户验证
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>com.hisoft.news.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
//@WebFilter(urlPatterns = "/*") 注解,如果配置了web.xml就不需要注解
public class LoginFilter implements Filter {
//容器启动时执行
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.err.println("fiterConfig....");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
HttpSession session = request.getSession();
NewsUser currUser = (NewsUser) session.getAttribute("user");
String uri = request.getRequestURI();//获取当前请求的uri
if(uri.equals("/newssystem/") || uri.equals("/newssystem/index.html") || uri.equals("/newssystem/login.html") || uri.startsWith("/newssystem/images") || uri.startsWith("/newssystem/css") || uri.startsWith("/newssystem/js")){
chain.doFilter(servletRequest,servletResponse); //放行
}else{
// chain.doFilter(servletRequest,servletResponse);
if(currUser != null){
chain.doFilter(servletRequest,servletResponse);
}else{
//response.sendRedirect("404");
//response.sendError(404,"页面失踪了");
response.sendRedirect(request.getContextPath() + "/index.html");
}
}
}
//容器关闭时执行
@Override
public void destroy() {
System.err.println("destroy.....");
}
}
(4)实现改变所有页面编码格式
<filter>
<filter-name>encoding</filter-name>
<filter-class>com.hisoft.news.filter.EncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
/*@WebFilter(urlPatterns = "/*",initParams = {
@WebInitParam(
name = "encoding",
value = "utf-8"
)
})*/
public class EncodingFilter implements Filter {
private String enCoding = "UTF-8";
@Override
public void init(FilterConfig filterConfig) throws ServletException {//获取 Filter 程序在 web.xml 文件中的配置信息的接口
String encoding = filterConfig.getInitParameter("encoding");
if (encoding != null) {
this.enCoding = encoding;
}
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
request.setCharacterEncoding(enCoding);
chain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}
3、Listener监听器
(1)Listener监听器有三大域:ServletContext、HttpSession、ServletRequest。每个域都有自己的生命周期监听方法和属性监听方法。
<!--监听器-->
<listener>
<listener-class>com.hisoft.news.listener.MyListener</listener-class>
</listener>
@WebListener
public class MyListener implements ServletContextListener {
//生命周期监听
//ServletContext中:
@Override public void contextInitialized(ServletContextEvent sce) {
//容器启动时会执行该方法
}
@Override public void contextDestroyed(ServletContextEvent sce) {
//容器关闭时会执行该方法 //发送邮件
}
//HttpSession中:
@Override
public void sessionCreated(HttpSessionEvent se) {
//session 创建时会执行该方法
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
//session 失效时会执行这个方法
}
//ServletRequest中:
void requestInitialized(ServletRequestEvent sre) {
//request 创建时执行
}
void requestDestroyed(ServletRequestEvent sre) {
//request 失效时执行
}
//属性监听
//ServletContext中:
void attributeAdded(ServletContextAttributeEvent event){}//添加属性时;
void attributeReplaced(ServletContextAttributeEvent event){}//替换属性时;
void attributeRemoved(ServletContextAttributeEvent event){}//移除属性时;
//HttpSession中:
void attributeAdded(HttpSessionBindingEvent event){}//添加属性时;
void attributeReplaced(HttpSessionBindingEvent event){}//替换属性时
void attributeRemoved(HttpSessionBindingEvent event){}//移除属性时
//ServletRequest中:
void attributeAdded(ServletRequestAttributeEvent srae){}//添加属性时
void attributeReplaced(ServletRequestAttributeEvent srae){}//替换属性时
void attributeRemoved(ServletRequestAttributeEvent srae){}//移除属性时
}