web.xml 文件为java web程序的一个基础性描述文件,主要用于描述URL与Servlet如何进行映射,以及映射时候的一些附加信息,例如认证、错误跳转等等
之前对web.xml的配置一直没有太多的重视 仔细学习了一下 发现里面的东西还是需要值得注意的 记录学习的脚步
下面的web.xml文件 是我此文进行测试的最后内容 先贴出来 每一个标签 需要的话 都加了必要的解释了 如下
对于上面的内容 来看看 servlet、filter、listener、资源访问等等的实例 分别如下
1.Listener的实例 在上面的web.xml文件中 有一段监听器的配置
<listener> <!-- The listener-class element declares a class in the application must be registered as a web application listener bean. The value is the fully qualified classname of the listener class. --> <listener-class>com.undergrowth.maven.ServletContextListenerImp</listener-class> </listener>
此监听器的实现文件 ServletContextListenerImp.java 如下
package com.undergrowth.maven; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class ServletContextListenerImp implements ServletContextListener { private Logger logger=LogManager.getLogger(ServletContextListenerImp.class); public void contextDestroyed(ServletContextEvent arg0) { // TODO Auto-generated method stub } public void contextInitialized(ServletContextEvent servletContextEvent) { // TODO Auto-generated method stub logger.info("初始化监听器:"+ServletContextListenerImp.class.getSimpleName()); //获取在web.xml中 配置的context-param中的值 String initName=servletContextEvent.getServletContext().getInitParameter("initName"); logger.info("初始化ServletContext的值:"+initName); } }
在tomcat启动的时候 打印如下信息 会看到Listener在web项目启动的时候加载监听器
2 Filter 实例 看到上面的图片中 有一行信息 获取过滤的编码:utf-8 即为过滤器的初始化信息
A filter is a class that acts on a request like a servlet, but may allow the handling of the request to continue with other filters or servlets.在web.xml中 filter的配置如下<!-- 使用过滤器设置request和response的编码 --> <filter> <filter-name>charsetEncodingFilter</filter-name> <!-- The fully qualified classname of the filter. --> <filter-class>com.undergrowth.maven.CharsetEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>charsetEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
过滤器 CharsetEncodingFilter.java 如下package com.undergrowth.maven; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class CharsetEncodingFilter implements Filter { private Logger logger=LogManager.getLogger(CharsetEncodingFilter.class); private String encoding="utf-8"; public void destroy() { // TODO Auto-generated method stub } public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { // TODO Auto-generated method stub logger.info("修改request和response的编码"); request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); filterChain.doFilter(request, response); } public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub encoding=filterConfig.getInitParameter("encoding"); logger.info("获取过滤的编码:"+encoding); } }
通过上面的示例 发现 在项目启动的时候 回先实例 Listerer 然后是 Filter
3 Servlet的映射实例
上面的web.xml文件中
<servlet> <servlet-name>ServletMapping</servlet-name> <!-- The servlet-class element contains the fully qualified class name of the servlet. --> <servlet-class>com.undergrowth.maven.ServletMapping</servlet-class> <!-- The init-param element contains a name/value pair as an initialization param of a servlet filter --> <init-param> <param-name>name</param-name> <param-value>张三</param-value> </init-param> <init-param> <param-name>age</param-name> <param-value>22</param-value> </init-param> <!-- The load-on-startup element indicates that this servlet should be loaded (instantiated and have its init() called) on the startup of the web application. The optional contents of these element must be an integer indicating the order in which the servlet should be loaded. If the value is a negative integer, or the element is not present, the container is free to load the servlet whenever it chooses. If the value is a positive integer or 0, the container must load and initialize the servlet as the application is deployed. The container must guarantee that servlets marked with lower integers are loaded before servlets marked with higher integers. The container may choose the order of loading of servlets with the same load-on-start-up value. --> <!-- <load-on-startup>1</load-on-startup> --> </servlet> <!-- The <servlet-mapping> element specifies a URL pattern and the name of a declared servlet to use for requests whose URL matches the pattern. The URL pattern can use an asterisk (*) at the beginning or end of the pattern to indicate zero or more of any character. (The standard does not support wildcards in the middle of a string, and does not allow multiple wildcards in one pattern.) The pattern matches the full path of the URL, starting with and including the forward slash (/) following the domain name. --> <servlet-mapping> <servlet-name>ServletMapping</servlet-name> <url-pattern>/ServletMapping</url-pattern> </servlet-mapping>
Servlet的实现类ServletMapping.javapackage com.undergrowth.maven; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class ServletMapping extends HttpServlet { /** * */ private static final long serialVersionUID = 1L; private static Logger logger=LogManager.getLogger(ServletMapping.class); /** * Constructor of the object. */ public ServletMapping() { super(); } /** * Destruction of the servlet. <br> */ public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } /** * The doGet method of the servlet. <br> * * This method is called when a form has its tag value method equals to get. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { logger.info("request的编码:"+request.getCharacterEncoding()); // response.setContentType("text/html;charset=utf-8"); logger.info(ServletMapping.class.getName()+"的doGet方法调用"); String name=getServletConfig().getInitParameter("name"); String age=getServletConfig().getInitParameter("age"); logger.info("初始化的参数name:"+name+"\tage:"+age); response.getWriter().write("初始化的参数name:"+name+"\tage:"+age+"\tcharset:"+response.getCharacterEncoding()); response.getWriter().close(); } /** * The doPost method of the servlet. <br> * * This method is called when a form has its tag value method equals to post. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { logger.info(ServletMapping.class.getName()+"的doPost方法调用"); this.doGet(request, response); } /** * Initialization of the servlet. <br> * * @throws ServletException if an error occurs */ public void init() throws ServletException { // Put your code here // logger.info("初始化"+ServletMapping.class.getName()); logger.info("初始化servlet:"+ServletMapping.class.getSimpleName()); } }
当访问此servlet的时候 信息如下
后台信息如下
通过后台信息 看到 访问此servlet的时候 先调用此servlet的init方法 然后调用上面的过滤器 对request和response设置其编码 最后调用此servlet的doGet方法
4 错误页面配置 上面的web.xml如下
<!-- Note: At present, you cannot configure custom error handlers for some error conditions. Specifically, you cannot customize the 404 response page when no servlet mapping is defined for a URL, the 403 quota error page, or the 500 server error page that appears after an App Engine internal error. --> <error-page> <error-code>404</error-code> <!-- The location element contains the location of the resource in the web application relative to the root of the web application. The value of the location must have a leading `/'. --> <location>/index.jsp</location> </error-page> <error-page> <!-- 当出现下面的异常的时候 跳转到runtime.jsp界面 --> <exception-type>com.undergrowth.maven.RuntimeExceptionTest</exception-type> <location>/runtime.jsp</location> </error-page>
上面的RuntimeExceptionTest.java 如下package com.undergrowth.maven; public class RuntimeExceptionTest extends RuntimeException { /** * */ private static final long serialVersionUID = 1L; @Override public String toString() { // TODO Auto-generated method stub return super.toString(); } }
然后再配置一个servlet用于测试此错误页面配置<servlet> <servlet-name>RuntimeServlet</servlet-name> <servlet-class>com.undergrowth.maven.RuntimeServlet</servlet-class> </servlet><servlet-mapping> <servlet-name>RuntimeServlet</servlet-name> <url-pattern>/RuntimeServlet</url-pattern> </servlet-mapping>
RuntimeServlet.javapackage com.undergrowth.maven; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class RuntimeServlet extends HttpServlet { /** * Constructor of the object. */ public RuntimeServlet() { super(); } /** * Destruction of the servlet. <br> */ public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } /** * The doGet method of the servlet. <br> * * This method is called when a form has its tag value method equals to get. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { throw new RuntimeExceptionTest(); } /** * The doPost method of the servlet. <br> * * This method is called when a form has its tag value method equals to post. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } /** * Initialization of the servlet. <br> * * @throws ServletException if an error occurs */ public void init() throws ServletException { // Put your code here } }
上面的runtime.jsp 如下
测试如下
5 限制资源的访问
<!-- 限制web资源的访问 --> <security-constraint> <web-resource-collection> <web-resource-name>textInfos</web-resource-name> <!-- 在/resources目录下的资源都需要访问权限 --> <url-pattern>/resources/*</url-pattern> <http-method>GET</http-method> <http-method>POST</http-method> </web-resource-collection> <auth-constraint> <!-- 访问的角色只能是manager-gui,才能访问 --> <role-name>manager-gui</role-name> </auth-constraint> <!-- The development web server does not support HTTPS connections. It ignores the transport guarantee, so paths intended for use with HTTPS can be tested using regular HTTP connections to the development web server. --> <!-- <user-data-constraint> <transport-guarantee>CONFIDENTIAL</transport-guarantee> </user-data-constraint> --> </security-constraint> <!-- 表示访问限制的web资源时 采用的认证方式最简单 输入属于manager-gui角色下的用户名与密码 即可 --> <login-config> <auth-method>BASIC</auth-method> </login-config> <!-- 表示可以访问web限制资源的角色 此处的角色名称需要与 tomcat的conf目录下的tomcat-users.xml里面配置的角色名匹配 例如我的 在tomcat-users.xml里面 经过上面的和tomcat的配置后 admin用户即可访问web的限制资源 <role rolename="manager-gui"/> <role rolename="pc"/> <user username="admin" password="admin" roles="manager-gui"/> <user username="under" password="under" roles="pc"/> --> <security-role> <role-name>manager-gui</role-name> </security-role>
tomcat目录下 conf/tomcat-users.xml 配置
测试访问先使用under登陆
资源受限
admin登陆
资源成功访问
6 mime-type 资源类型设置
<!-- 以res的后缀的文件的mime类型为text/plain 如果使用maven依赖的tomcat mime-type的类型不会变 所以将webconfiguration.war改为单独的tomcat 中运行 即可看到输出的类型变化 --> <mime-mapping> <extension>res</extension> <!-- window下有很多mime HKEY_LOCAL_MACHINE\SOFTWARE\Classes\MIME\Database\Content Type 常见的例如: text/html text/plain text/css text/xml image/gif image/jpeg image/bmp image/png audio/x-midi audio/mpeg audio/m4p audio/midi video/mpeg video/avi video/x-flv video/3gpp application/x-tar application/rtf application/msword application/msaccess application/vnd.ms-excel--> <mime-type>text/html</mime-type> </mime-mapping>
resText.res文件内容
<h1>好好学习</h1>
默认情况下 访问资源resText.res的mime-type为text/plain 那么 资源中的html标签就不会被解析出来 所以使用上面的配置 改变res后缀的资源 使用的mime-type为text/html测试如下
7 jsp映射servlet
<!-- 给jsp映射成servlet取名 测试 --> <servlet> <servlet-name>jspServlet</servlet-name> <jsp-file>/jspServ.jsp</jsp-file> </servlet><servlet-mapping> <servlet-name>jspServlet</servlet-name> <url-pattern>/jspServlet.ser</url-pattern> </servlet-mapping>
上面的jspServ.jsp代码
实例测试 如下
8 附上 log4j2.xml的配置
文档结构图
pom.xml 如下
上面的代码 编写使用的是maven 3.2.1 但是因为mime-type和资源访问 只有在单独的tomcat容器中才能看到效果 但是测试的和使用的tomcat都是tomcat7
记录学习的脚步 继续努力