web.xml总结
参考资料
一、web.xml文件详解
context-param,它用于向 ServletContext 提供键值对,即应用程序上下文信息。我们的 listener, filter 等在初始化时会用到这些上下文中的信息,那么 context-param 配置节是不是应该写在 listener 配置节前呢?实际上 context-param 配置节可写在任意位置,因此真正的加载顺序为:context-param -> listener -> filter -> servlet
对于某类配置节而言,与它们出现的顺序是有关的。以 filter 为例,web.xml 中当然可以定义多个 filter,与 filter 相关的一个配置节是 filter-mapping,这里一定要注意,对于拥有相同 filter-name 的 filter 和 filter-mapping 配置节而言,filter-mapping 必须出现在 filter 之后,否则当解析到 filter-mapping 时,它所对应的 filter-name 还未定义。web 容器启动时初始化每个 filter 时,是按照 filter 配置节出现的顺序来初始化的,当请求资源匹配多个 filter-mapping 时,filter 拦截资源是按照 filter-mapping 配置节出现的顺序来依次调用 doFilter() 方法的。 servlet 同 filter 类似,此处不再赘述。
由此,可以看出,web.xml 的加载顺序是:context-param -> listener -> filter -> servlet ,而同个类型之间的实际程序调用的时候的顺序是根据对应的 mapping 的顺序进行调用的。
XML 元素不仅是大小写敏感的,而且它们还对出现在其他元素中的次序敏感。例如,XML 头必须是文件中的第一项,DOCTYPE 声明必须是第二项,而 web-app 元素必须是第三项。在web-app 元素内,元素的次序也很重要。服务器不一定强制要求这种次序,但它们允许(实际上有些服务器就是这样做的)完全拒绝执行含有次序不正确的元素的 Web 应用。这表示使用非标准元素次序的 web.xml文件是不可移植的! 所以正确的顺序是非常必要的。
Web.xml常用元素(按正确的顺序排列)
<web-app>
<icon></icon>
// icon元素指出 IDE 和 GUI 工具用来表示 Web 应用的一个和两个图像文件的位置
<display-name></display-name>
// 定义了WEB应用的名字
<description></description>
// 声明WEB应用的描述信息
<context-param></context-param>
// context-param元素声明应用范围内的初始数。
<filter></filter>
// 过滤器元素将一个名字与一个实现javax.servlet.Filter接口的类联
<filter-mapping></filter-mapping>
// 一旦命名了一个过滤器,就要利用filter-mapping元素把它与一个或多个servlet或JSP页面相关联。
<listener></listener>
// servlet API的版本2.3增加了对事件监听程序的支持,事件监听程序在建立、修改和删除会话或servlet环境时得到通知。 Listener元素指出事件监听程序类。
<servlet></servlet>
// 在向servlet或JSP页面制定初始化参数或定制URL时,必须首先命名servlet或JSP页面。Servlet元素就是用来完成此项任务的。
<servlet-mapping></servlet-mapping>
// 服务器一般为servlet提供一个缺省的URL:http://host/webAppPrefix/servlet/ServletName。但是,常常会更改这个URL,以便servlet可以访问初始化参数或更容易地处理相对URL。在更改缺省URL时,使用servlet-mapping元素。
<session-config></session-config>
// 如果某个会话在一定时间内未被访问,服务器可以抛弃它以节省内存。可通过使用HttpSession的setMaxInactiveInterval方法明确设置单个会话对象的超时值,或者可利用session-config元素制定缺省超时值。
<mime-mapping></mime-mapping>
// 如果Web应用具有想到特殊的文件,希望能保证给他们分配特定的MIME类型,则mime-mapping元素提供这种保证。
<welcome-file-list></welcome-file-list>
// 指示服务器在收到引用一个目录名而不是文件名的URL时,使用哪个文件。
<error-page></error-page>
// 在返回特定HTTP状态代码时,或者特定类型的异常被抛出时,能够制定将要显示的页面。
<taglib></taglib>
// 对标记库描述符文件(Tag Libraryu Descriptor file)指定别名。此功能使你能够更改TLD文件的位置,而不用编辑使用这些文件的JSP页面。
<resource-env-ref></resource-env-ref>
// 声明与资源相关的一个管理对象。
<resource-ref></resource-ref>
// 声明一个资源工厂使用的外部资源。
<security-constraint></security-constraint>
// 制定应该保护的URL。它与login-config元素联合使用
<login-config></login-config>
// 指定服务器应该怎样给试图访问受保护页面的用户授权。它与sercurity-constraint元素联合使用。
<security-role></security-role>
// 给出安全角色的一个列表,这些角色将出现在servlet元素内的security-role-ref元素的role-name子元素中。分别地声明角色可使高级IDE处理安全信息更为容易。
<env-entry></env-entry>
// 声明Web应用的环境项。
<ejb-ref></ejb-ref>
// 声明一个EJB的主目录的引用。
<ejb-local-ref></ejb-local-ref>
// 声明一个EJB的本地主目录的应用。
</web-app>
二、context-param应用程序上下文信息
<!-- 加载spring的配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml,/WEB-INF/action-servlet.xml,/WEB-
INF/jason-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--又如: --->自定义context-param,且自定义listener来获取这些信息
<context-param>
<param-name>urlrewrite</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>cluster</param-name>
<param-value>false</param-value>
</context-param>
<context-param>
<param-name>servletmapping</param-name>
<param-value>*.bbscs</param-value>
</context-param>
<context-param>
<param-name>poststoragemode</param-name>
<param-value>1</param-value>
</context-param>
<listener>
<listener-class>com.laoer.bbscs.web.servlet.SysListener</listener-class>
</listener>
三、Listener-监听器
3.1示例 session监听器 例如统计在线人数
1.配置web.xml
<!-- session监听器 例如统计在线人数 HttpSessionListener implements javax.servlet.http.HttpSessionListener-->
<listener>
<description>session监听器</description>
<listener-class>com.wds.demo.portal.service.HttpSessionListener</listener-class>
</listener>
2. 实现功能HttpSessionListener
import javax.servlet.http.HttpSessionEvent;
import org.springframework.stereotype.Service;
/** 访问人数HttpSessionListener */
@Service
public class HttpSessionListener implements javax.servlet.http.HttpSessionListener {
private static int count = 0;
@Override
public void sessionCreated(HttpSessionEvent se) {
count++;
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
if (count>0) {
count--;
}
}
public static int getCount() {
return count;
}
}
3.2监听器(listrner)的作用和原理
监听器是web容器内的一个组件
在这几类范围模型的生命周期中,会发生许多事件,作出对应处理,如:web应用完成加载后建立与外部资源的连接等。
web应用的事件监听器为各类事件提供了丰富的接口,我们只需要实现接口并在web.xml中配置即可
<listener>
<listener-class><!--完整类名--></listener-class>
</listener>
web应用程序的监听器是对web生命周期的3种事件的监听
1.Request事件监听器接口ServletRequestListener:
2.Session事件监听器接口HttpSessionListener:
3.Application事件监听器接口ServletContextListener:
四、Filter-过滤器
4.1 Filter实现示例
1.配置web.xml
<filter>
<filter-name>threadFilter</filter-name>
<filter-class>com.wds.demo.support.filter.ThreadFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>threadFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2. 实现自定义filter功能-线程数据库连接Filter
/** 线程数据库连接Filter */
public class ThreadFilter implements Filter {
protected final Log logger = LogFactory.getLog(getClass());
public void init(FilterConfig config) throws ServletException {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
// 如果资源可以被处理,则直接处理
if (doFilter(req, res)) {
return;
}
try {
chain.doFilter(request, response);
} finally {
LogicClassUtil.destroyLogicClass();
ParseContextManager.clearAll();
ThreadLocalManager.clearAll();
ReportManager.clear();
}
}
/**
* 处理资源
* @return
*/
private boolean doFilter(final HttpServletRequest req, final HttpServletResponse res) {
List<Object> resList = demoCallbackManager.execCallback(
IUrlFilterCallback.class, new demoCallbackAdapter() {
@Override
public void execCallback(Object cls, demoCallbackResult result) {
result.setData(((IUrlFilterCallback) cls).doFilter(req, res));
if (Boolean.parseBoolean(result.getData().toString())) {
result.exit();
}
}
});
if (resList.size() == 0)
return false;
else
return Boolean.parseBoolean(resList.get(resList.size() - 1) .toString());
}
}
4.2过滤器(Filter)的作用和原理
过滤器是web容器内的一个组件
过滤器是对请求信息和响应信息进行过滤的组件,请求和响应都会经过过滤器
Filter实现示例:需要实现javax.servlet 方法
doFilter(ServletRequest req,ServletResponse resp, FilterChain chain){
chain.doFilter(req, resp);
}
web.xml中配置过滤器
五、Servelet-示例-生命周期
5.1示例
1.Web.xml文件配置
<servlet>
<servlet-name>helloWorldServlet</servlet-name>
<servlet-class>com.java1234.web.HelloWorldServlet</servlet-class>//匹配对应的后台处理
</servlet>
<servlet-mapping>
<servlet-name>helloWorldServlet</servlet-name>
<url-pattern>/helloWorld</url-pattern>//请求helloworld页面
</servlet-mapping>
2.实现-继承HttpServlet
public class HelloWorldServlet extends HttpServlet{
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
......
}
}
5.2Servlet生命周期(只能在web容器中存活)
1 web应用目录结构(部署到tomcat中的war包):
当用户向web容器发送http请求时,web容器会根据地址(http://<域名或ip>/<应用名>/<资源地址>)然后通过
2 Servlet必须实现javax.servlet.Servlet接口的所有方法,实际开发中是通过实现avax.servlet.http.HttpServlet来创建的,可以为开发者提供所有抽象方法默认的实现,而且区别不同的请求方法(GET/POST)
- 加载:加载到虚拟机中,实例化。
默认第一次请求时被加载,但可以通过</>设置web容器启动时加载 如果servlet类没有public的无参构造方法,加载失败 - init():web容器初始化servlet时调用init()
一般初始化代码在这,如打开数据源
为servlet配置初始化参数(获取web.xml配置的初始化参数init-param) - service():指当有http请求指向servlet时,调用service()方法,该方法体包含业务逻辑,
如果继承自httpServlet,则根据请求类型不同,业务逻辑写在doget/dopost中 - destroy():重新部署,关闭容器时调用
所以一般释放资源(关闭数据源等)的代码会放在该方法中
六、Servlet与Web容器+JSP+EL
6.1.web应用目录结构(部署到tomcat中的war包):
当用户向web容器发送http请求时,web容器会根据地址(http://<域名或ip>/<应用名>/<资源地址>)然后通过
- 1.将项目部署(在tomcat服务器)好后
- 2.在浏览器中输入http://localhost:8081/TestServletProject/TestServlet
- 3.tomcat服务器就会加载TestServletProject工程下的web.xml
- 4.根据请求的映射路径/TestServlet,映射/TestServlet找到Servlet处理类
- 5.根据类名 反射执行这个类的doGet方法
6.2.如何在servlet中获取请求参数的值
请求:
- get:获取资源,参数追加到url中;
- post:向服务器提交,参数放在请求体中
web容器把每一次请求看做servletRequest对待,到达service()方法前,容器会创建一个实现servletRequest接口的对象(request),并作为service()的参数传入,然后提供给具体的servlet类处理 在servlet中就可以通过servletRequest的getParameter()或者getParameterValues()取到
6.3.Forward和Redirect
用户向服务器发出的一次请求可能会经过多个信息资源处理以后才能返回客户端,多个信息资源户用请求转发机制互相转发请求:直接请求转发(Forward)和间接请求转发(Redirect)
区别: 观察客户端浏览器的地址是否发生变化
- 间接请求转发(Redirect):又叫重定向,用于避免用户非正常访问,servlet可以将http请求重定向到指定的url,跳转到指定的页面,然后再交由新的servlet处理请求,实际上是两次url请求, 两个request对象,对应HttpServletRequest的sendRedirect()方法 response.sendRedirect(“资源的url”)
- 直接请求转发(Forward):一般来说应用程序会有一个控制器,,由控制器来控制转发给哪个信息资源,还可能再转发给其他的信息资源,处理完返回,这个过程也就是经典的MVC模式, 一个url请求,两个信息资源共用一个request对象,对应RequestDispatcher类的forward()方法
6.4.JSP的运行机制
jsp文件(网页文件中嵌入java代码)会在用户第一次请求时,被web容器编译成servlet,所以jsp的本质是servlet,存在的必要性是因为比起servlet的拼接字符串的处理静态内容,jsp能很好的实现静态和动态内容的分离
6.5.JSP的内置对象对象和作用
ps:pageContext:代表jsp页面上下文,也是一个运行环境,提供访问其他内置对象的入口
如:PageContext.getRequest()
6.6.pageContext和request的作用范围区别:
在jsp中进行请求转发:
6.7.JSP+JavaBean(可重用组件)的开发模式
javaBean规范:
- 1.public class
- 2.public 无参 构造方法
- 3.public getXXX、setXXX方法
- 4.实现java.io.Serializable接口(可序列化是非必须的,但是当服务器集群且javabean保存在session中时,在网络中拷贝JavaBean就需要序列化)
JSP中使用JavaBean:
1). 纯JSP实现,使用纯粹的java代码来创建和使用javabean对象
2). JSP动作标签访问JavaBean
6.8.EL+JSTL
1). jstl的【
使用示例:
2).JSTL逻辑判断标签:
使用示例:
6.9.MVC
1)JSP+JavaBean模式开发
2)不用框架,(JSP+JavaBean+Servlet)原生实现mvc模式的web开发
3)Structs如何体现mvc?,开发思路是?,Structs提供哪几类actions?
4)ORM? Hibernate的基本使用思想? Hibernate的实体存在几种状态?HQL?Hibernate分页?get() 和 load() 区别? 如何映射一对一关系?一对多?多对多?继承关系策略?
6.10.Spring
1)依赖注入方式(通过setter方法,通过构造方法注入):
依赖注入(Dependency Injection)是用于实现控制反转(Inversion of Control)的最常见方式之一, IOC容器的核心是Spring提供的Bean工厂(BeanFactory),—单例模式产生对象
2)Spring声明式事务:
Spring把事务作为一种中间件的形式提供给开发者,通过配置来使用事务,也叫声明式事务
AOP(Aspect Oriented Programming)面向切面编程: 简单来说,AOP就是一个功能强大的拦截器,代码到达真正目的之前,AOP拦截,然后提供通用发中间件的服务( 加上事务服务,记录日志等 )
Spring的声明式事务就是基于AOP实现的
Spring的声明式事务为普通java类封装事务控制,底层用动态代理技术实现( 特征是针对接口 ),所以要在DAO层对象前面抽象出一个接口,才能让Spring通过动态代理接管事务 声明式事务的显著有点,业务对象不需要依赖事务基础,即看不到任何JDBC关于事务的代码
配置Spring事务:
3)整合Structs,Hobernate,Spring: