Servlet学习记录2
读取web.xml参数
上篇文章ImageServlet里只设置了JPG,GIF,DOC类型文件的Content-Type。如果这时候需求变化了,需要增加Excel文件格式的Content-Type,就得修改ImageServlet源代码,重新编译class文件,然后重新部署。一个看起来很微小的改动却带来了大量的工作,很让人心烦。
现在在Java Web开发中,这种常量信息更倾向于写在某个配置文件里。需求变化时只需要修改一下配置文件就可以了,而不会修改源程序,也不会重新编译,维护起来相当方便。web.xml提供了设置初始化参数的功能,可以将这些信息配置在web.xml中。
初始化参数(init-param)
web.xml中配置Servlet的时候,标签<servlet>中可以包含标签<init-param>来配置初始化参数。一个Servlet可以配置0到多个初始化参数。接下来的例子InitParamServlet中配置了3个初始化参数。
<servlet><servlet-name>InitParamServlet</servlet-name><servlet-class>com.helloweenvsfei.servlet.InitParamServlet</servlet-class><init-param><param-name>helloween</param-name><param-value>password</param-value></init-param><init-param><param-name>admin</param-name><param-value>admin</param-value></init-param><init-param><param-name>babyface</param-name><param-value>babyface</param-value></init-param> </servlet>
配置完毕后,Servlet中提供方法getInitParameter(String param)来获取初始化参数值。如果配置了名为param的参数,则返回参数值,否则返回null。在这段配置中,getInitParameter("helloween")将返回password,getInitParameter("Cobain")将返回null。还可以使用getInitParameterNames()方法返回所有的参数名称,返回结果为枚举类型(Enumeration)。
这些初始化的参数也可以由ServletConfig对象取得。Servlet提供getServletConfig()这个ServletConfig对象。由ServletConfig取初始化参数与Servlet直接取方式一样。
看一例子。公司要在网站上颁布一个机密文件notice.html,要求仅有少数几个人能够浏览到。我们来实现这种权限控制。
(1)把notice.html放在/WEB-INF文件夹下面。因为Java Web应用程序的WEB-INF文件夹有这个特性,任何人都不能通过浏览器直接获取下面的文件,即使他知道文件的准确位置及名称。WEB-INF下的文件是受保护的,这样就保证了文件的安全性。如果浏览器中输入http://localhost:8080/servlet/WEB-INF/notice.html,服务器会报404 Error,尽管这个文件地址是对的。
(2)编写一个程序InitParamServlet,提示用户输入用户名密码。如果密码验证通过,则通过程序转到notice.html上。虽然WEB-INF下的文件不能通过浏览器直接获取到,但是仍然可以通过程序读取到。程序如下:
package com.helloweenvsfei.servlet;import java.io.IOException; import java.io.PrintWriter; import java.util.Enumeration;import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;public class InitParamServlet extends HttpServlet {private static final long serialVersionUID = 7298032096933866458L;public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.setCharacterEncoding("UTF-8");request.setCharacterEncoding("UTF-8");response.setContentType("text/html");PrintWriter out = response.getWriter();out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");out.println("<HTML>");out.println(" <HEAD><TITLE>请登录查看 Notice 文件</TITLE></HEAD>");out.println("<style>body, td, div {font-size:12px; }</style>");out.println(" <BODY>");out.println("<form action='" + request.getRequestURI() + "' method='post'>");out.println("帐号:<input type='text' name='username' style='width:200px; '> <br/>");out.println("密码:<input type='password' name='password' style='width:200px; '> <br/><br/>");out.println("<input type='submit' value=' 登录 '>");out.println("</form>");if(true){out.println("<br/><br/><br/><br/><br/><br/><br/>用户名、密码为:<br/>");Enumeration params = this.getInitParameterNames();while(params.hasMoreElements()){String usernameParam = (String)params.nextElement();String passnameParam = this.getInitParameter(usernameParam);out.println("[" + usernameParam + ", " + passnameParam + "], ");}}out.println(" </BODY>");out.println("</HTML>");out.flush();out.close();}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 提交的 username 参数String username = request.getParameter("username");// 提交的 password 参数String password = request.getParameter("password");// 取所有的初始化参数名称Enumeration params = this.getInitParameterNames();while(params.hasMoreElements()){String usernameParam = (String)params.nextElement();// 取参数值String passnameParam = this.getInitParameter(usernameParam);// 如果 username 匹配且 password 匹配. username 大小写不敏感,password大小写敏感if(usernameParam.equalsIgnoreCase(username)&& passnameParam.equals(password)){// 显示文件。/WEB-INF 下的文件不能通过浏览器访问到,因此是安全的request.getRequestDispatcher("/WEB-INF/notice.html").forward(request, response);return;}}// username,password 不匹配,显示登录页面this.doGet(request, response); }}
登陆前后的效果如图3.6所示。Servlet显示/WEB-INF/下的文件。
一个月后,公司要求增加Peter为可以浏览该机密文件的人选,同时禁止babyface的账号。由于没有将这些信息写在源程序里而是写在了web.xml里,因此改动相当简单。在参数配置里添加一个Peter,删掉babyface就可以了。
初始化参数的好处是可以把某些变量拿到web.xml中配置,需要修改时只需要修改web.xml文件并重启服务器即可,而不需要修改Servlet类。
上下文参数(context-param)
由于init-param是配置在<servlet>标签里的,只能由这个Servlet来读取,因此它不是全局的参数,不能被其他的Servlet读取。
如果需要配置一个所有Servlet都能够读取的参数,就需要用到上下文参数(Context-Param),或者叫文档参数。上下文参数使用标签<context-param>配置,代码如下:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" 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-app_2_5.xsd"><context-param><param-name>upload folder</param-name><param-value>attachment</param-value> </context-param> <context-param><param-name>allowed file type</param-name><param-value>.gif,.jpg,.bmp</param-value> </context-param>
获取context-param可以使用ServletContext对象。Servlet中通过getServletConfig().getServletContext()来获取一个ServletContext对象,使用ServletContext的getInitParameter()方法来获取指定名称的参数,通过getInitParameterNames()获取所有的context-param参数名称。下面是一个例子:
package com.helloweenvsfei.servlet;import java.io.IOException; import java.io.PrintWriter;import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;public class ContextParamServlet extends HttpServlet {private static final long serialVersionUID = 3194071196406358461L;public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.setCharacterEncoding("UTF-8");response.setContentType("text/html");PrintWriter out = response.getWriter();out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");out.println("<HTML>");out.println(" <HEAD><TITLE>读取文档参数</TITLE></HEAD>");out.println(" <link rel='stylesheet' type='text/css' href='../css/style.css'>");out.println(" <BODY>");out.println("<div align=center><br/>");out.println("<fieldset style='width:90%'><legend>所有的文档参数</legend><br/>");ServletContext servletContext = this.getServletConfig().getServletContext();String uploadFolder = servletContext.getInitParameter("upload folder");String allowedFileType = servletContext.getInitParameter("allowed file type");out.println("<div class='line'>");out.println(" <div align='left' class='leftDiv'>上传文件夹</div>");out.println(" <div align='left' class='rightDiv'>" + uploadFolder + "</div>");out.println("</div>");out.println("<div class='line'>");out.println(" <div align='left' class='leftDiv'>实际磁盘路径</div>");out.println(" <div align='left' class='rightDiv'>" + servletContext.getRealPath(uploadFolder) + "</div>");out.println("</div>");out.println("<div class='line'>");out.println(" <div align='left' class='leftDiv'>允许上传的类型</div>");out.println(" <div align='left' class='rightDiv'>" + allowedFileType + "</div>");out.println("</div>");out.println("</fieldset></div>");out.println(" </BODY>");out.println("</HTML>");out.flush();out.close();} }
运行效果如图:
初始化参数与上下文参数只能配置简单的字符串类型的参数。如果需要配置更多更灵活的参数,更推荐把参数配置写到xml文件或者properties文件里,然后编写程序读取这些文件。
资源注射(@Resource)
上面的例子都是在Servlet里编写程序代码读取web.xml初始参数。Java EE 5提供了一种新的方案叫做资源注射(Resource Injection),或者叫资源注入。也就是说,不需要Servlet主动去读取资源,Tomcat启动的时候会把web.xml里配置的信息主动“注射”到Servlet里。这个过程是运行时自动完成的,不需要编写任何代码,不需要做任何工作。
资源注射是通过注解(Annotation)完成的。注解是Java 5.0里引入的新特性。注解是一种特殊的接口,以“@”符号为标志。用法如下:
@Resource(name="messageNameInWebXml") private String message;
使用@Resource标注字符串变量message,表示message的值会在Servlet运行时动态注入。然后在web.xml中配置一个名为messageNameInWebXml的参数就可以了。注解以及变量可以写在一行代码中,看起来更简洁一些;
private @Resource(name="messageNameInWebXml") String message;
看一个实例
package com.helloweenvsfei.servlet;import java.io.IOException; import java.io.PrintWriter;import javax.annotation.Resource; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;public class InjectionServlet extends HttpServlet {private static final long serialVersionUID = -8526907492073769090L;// 注入的 字符串private @Resource(name="hello") String hello;// 注入的 整数private @Resource(name="i") int i;// 注入更常见的写法@Resource(name="persons")private String persons;public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.setCharacterEncoding("UTF-8");request.setCharacterEncoding("UTF-8");response.setContentType("text/html");PrintWriter out = response.getWriter();out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");out.println("<HTML>");out.println(" <HEAD><TITLE>资源注入</TITLE></HEAD>");out.println("<style>body {font-size:12px; }</style>");out.println("<b>注入的字符串</b>:<br/> - " + hello + "<br/>");out.println("<b>注入的整数</b>:<br/> - " + i + "<br/>");out.println("<b>注入的字符串数组</b>:<br/>");for(String person : persons.split(",")){out.println(" - " + person + "<br/>");}out.println(" <BODY>");out.println(" </BODY>");out.println("</HTML>");out.flush();out.close();}}
web.xml中使用标签<env-entry>来配置资源。<env-entry>仅能配置java.lang包下的标准类型的变量,如String,Integer,Double等。配置后的代码如下:
<env-entry><env-entry-name>hello</env-entry-name><env-entry-type>java.lang.String</env-entry-type><env-entry-value>Hello, Welcome to the JavaEE Resource Injection.</env-entry-value> </env-entry><env-entry><env-entry-name>i</env-entry-name><env-entry-type>java.lang.Integer</env-entry-type><env-entry-value>30</env-entry-value> </env-entry><env-entry><env-entry-name>persons</env-entry-name><env-entry-type>java.lang.String</env-entry-type><env-entry-value>Helloween, Cobain, Roses, Axl,</env-entry-value> </env-entry>
程序运行效果:
使用JNDI获取资源
资源注射的工作原理是JNDI(Java命名与目录接口,Java Naming and Directory Interface)。InjectionServlet实例中使用<env-entry>配置了名为hello, i, persons的JNDI资源,然后使用@Resource将指定名称的JNDI资源注射到InjectionServlet里。
如果不使用@Resource,通过查找JNDI同样可以获取到这三个资源,代码如下:
Context ctx = new InitialContext(); //实例化一个Context对象 String message = (String)ctx.lookup("message"); //查找资源message Integer i = (Integer)ctx.lookup("i"); //查找资源i String persons = (String)ctx.lookup("persons"); //查找资源persons
注射数据源
Servlet中不仅可以注射String,Integer等类型的变量,还可以注入自定义的Java Bean以及数据源等复杂类型变量。例如,下面的代码将会注射一个数据源。读者只需要在Tomcat中配置好数据源,然后使用下列代码就可以获取到数据源变量。这是相当方便的:
@Resource(name="dataBase") //声明数据源名称,数据源配置在Tomcat中 javax.sql.DataSource dataSource; //注射到dataSource属性上public void getConnection(){ //方法中直接使用dataSourceConnection conn = dataSource.getConnection();return conn; }
注射是利用@注解实现的。JDK5以上支持@注解。资源注射需要服务器的支持,Tomcat 6是支持的,但在某些其它Web服务器或者低版本的Tomcat可能不支持。
转载于:https://www.cnblogs.com/liunianfeiyu/p/10652667.html
Servlet学习记录2相关推荐
- Servlet学习记录3
提交表单信息 Web程序的任务是实现服务器与客户端浏览器之间的信息交互.客户端提交的信息可能来自表单里的文本框,密码框,选择框,单选按钮,复选框以及文件域.这些表单信息被以参数形式提交到了服务器.Se ...
- Servlet学习记录
目录 目录 前言 什么是Servlet Servlet生命周期 Servlet工作原理 Servlet的类层次结构 实现Servlet的三种方式 1) 实现Servlet接口 2) 继承Generic ...
- Android 学习记录(持续更新)
Android 学习记录(持续更新) 1.AndroidManifest.xml 详解: http://www.jb51.net/article/73731.htm (AndroidManifest. ...
- Android 开发学习记录(4)---- httpclient使用(三)
之前在Android 开发学习记录(3)---- httpclient使用(二)中介绍了如何使用httpclient访问需要账户登录的网址,当然首先是要有一个合法的登录账户. 但是现在好多网站在登录时 ...
- 基于Android的学生学习记录与提醒管理系统
末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:采用Vue技术开发 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件 ...
- Pytorch学习记录-torchtext和Pytorch的实例( 使用神经网络训练Seq2Seq代码)
Pytorch学习记录-torchtext和Pytorch的实例1 0. PyTorch Seq2Seq项目介绍 1. 使用神经网络训练Seq2Seq 1.1 简介,对论文中公式的解读 1.2 数据预 ...
- HTML5与CSS3权威指南之CSS3学习记录
title: HTML5与CSS3权威指南之CSS3学习记录 toc: true date: 2018-10-14 00:06:09 学习资料--<HTML5与CSS3权威指南>(第3版) ...
- springboot @cacheable不起作用_Springboot学习记录13 使用缓存:整合redis
本学习记录的代码,部分参考自gitee码云的如下工程.这个工程有详尽的Spingboot1.x教程.鸣谢! https://gitee.com/didispace/SpringBoot-Learnin ...
- 【Cmake】Cmake学习记录
Cmake学习记录 1.1 常例 add_library(gen_reference_infogen_reference_info/gen_reference_info.hgen_reference_ ...
- ASP.NETCore学习记录(一)
ASP.NETCore学习记录(一) asp.net core介绍 Startup.cs ConfigureServices Configure 0. ASP.NETCore 介绍 ASP.N ...
最新文章
- python列表切片口诀-python学习之“切片操作从入门到精通”
- 京瓷打印机几个常见密码
- Spring 是解析配置类过程详解
- Linux加载Linux的引导程序,Linux的引导-引导加载程序:LILO和GRUB
- 视觉标定,再来一波!!更简单粗暴!!!!!!
- diy计算机组装注意事项,自己组装电脑要注意什么?DIY老司机教你装机注意事项...
- VS2015新建项目无法选择framework 4.6.2
- Linux两种方式rd.break和init重置root管理员密码
- 勒索软件好多都使用恶意LNK链接文件欺骗用户 来看趋势科技分析新型LNK-PowerShell攻击...
- swoole异步mysql有什么用_php如何使用SwooleTaskWorker实现异步操作Mysql(代码)
- Hive去重最佳方法
- WebApp与HybridApp
- c语言项目图书馆借书,C语言打造—齐全的图书馆借阅系统
- 几种防鼠光缆的种类及优缺点分析!
- Python中文分词库jieba用法代码示例
- java 支付宝支付 demo_java开发支付宝支付详细流程_demo的运行
- 开发Android应用赚钱
- makefile编译子目录
- 地表最强!北大清华合力打造通用人工智能实验班,朱松纯教授领衔
- 【Mac 教程系列第 10 篇】如何在 Mac 上破解带有密码的 ZIP 压缩文件