一、Servlet简介
Servlet是sun公司提供的一门用于开发动态web资源的技术。
Sun公司在其API中提供了一个Servlet接口,用户如果相开发一个动态的web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤:
编写一个Java类,实现Servlet接口。
把开发好的Java类部署到web服务器中。
二、示例
HelloServlet.java
package cn.servlet; 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; @SuppressWarnings("serial") public class HelloServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().println("Hello Servlet!"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>day09</display-name> <!-- 配置Servlet信息 --> <servlet> <!-- 配置Servlet名称,名称必须唯一 --> <servlet-name>HelloServlet</servlet-name> <!-- 配置Servlet的完全路径(包名+类名) --> <servlet-class>cn.servlet.HelloServlet</servlet-class> </servlet> <!-- 配置Servlet的一你射(访问路径) --> <servlet-mapping> <!-- 配置Servlet名称,和上面的名称必须相同 --> <servlet-name>HelloServlet</servlet-name> <!-- 配置访问路径 --> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app>
在浏览器中输入:http://localhost:8080/day09/hello
三、Servlet的运行过程
Servlet程序是由web服务器调用,web服务器接收客户端的Servlet请求后:
1)web服务器首先检查是否已经装载并创建了该Servlet的实例对象。如果是,则直接执行第4)步,否则,执行第2)步。
2)装载并创建该Servlet的一个实例对象。
3)调用Servlet实例对象的init()方法。
4)创建一个用于封装HTTP请求消息的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和响应对象作为参数传递进去。
5)WEB应用程序被停止或重新启动之前,Servlet引擎将卸载Servlet,并在卸载之前调用Servlet的destory()方法。
四、Servlet接口定义了Servlet的生命周期
init()方法:服务器调用此方法初始化Servlet。
service()方法:初始化完毕,服务器调用该方法响应客户的请求。
destory()方法:服务器调用该方法消灭Servlet对象。
其中,init()方法只在Servlet第一次被请求加载的时候被调用一次,当有客户再请求Servlet服务的时候,Web服务器将启动一个新的线程,在该线程中,调用service()方法响应客户的请求。
五、Servlet的自动加载
默认情况下,Servlet是在用户第一次访问的时候才创建的。
如果在<servlet>元素中配置了一个<load-on-startup>的元素,那么web应用程序在启动的时候,就会装载并创建Servlet的实例对象以及调用Servlet实例对象的init()方法。
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>day09</display-name> <!-- 配置Servlet信息 --> <servlet> <!-- 配置Servlet名称,名称必须唯一 --> <servlet-name>HelloServlet</servlet-name> <!-- 配置Servlet的完全路径(包名+类名) --> <servlet-class>cn.servlet.HelloServlet</servlet-class> <!-- 服务器启动并加载Servlet --> <load-on-startup>1</load-on-startup> </servlet> <!-- 配置Servlet的一你射(访问路径) --> <servlet-mapping> <!-- 配置Servlet名称,和上面的名称必须相同 --> <servlet-name>HelloServlet</servlet-name> <!-- 配置访问路径 --> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app>
<load-on-startup>中的值越小,优先级越高。
六、配置Servlet的虚拟路径(访问路径)
完全路径匹配
以/开头 /demo5 /servlet/demo5
访问:http://localhost:8080/day09/demo5
目录匹配
以/开头 /*
访问:http://localhost:8080/day09/demo/demo5
扩展名匹配
不能以/开头 *.do *.action
访问:http://localhost:8080/day09/aa/bbb/a.action
优先级:完全路径匹配>目录匹配>扩展名匹配
七、web开发中的路径问题
1.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h2>1.html</h2> </body> </html>
2.html
<!DOCTYPE html> <html> <head> <title>2.html</title> <meta name="keywords" content="keyword1,keyword2,keyword3"> <meta name="description" content="this is my page"> <meta name="content-type" content="text/html; charset=UTF-8"> <!--<link rel="stylesheet" type="text/css" href="./styles.css">--> </head> <body> <h2>2.html</h2> </body> </html>
HelloServlet
package cn.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @SuppressWarnings("serial") public class HelloServlet extends HttpServlet { @Override public void init() throws ServletException { System.out.println("init方法"); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("utf-8"); response.getWriter().println("哇 这是Servlet"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
对应的web.xml文件
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>day09</display-name> <!-- 配置Servlet信息 --> <servlet> <!-- 配置Servlet名称,名称必须唯一 --> <servlet-name>HelloServlet</servlet-name> <!-- 配置Servlet的完全路径(包名+类名) --> <servlet-class>cn.servlet.HelloServlet</servlet-class> <!-- 服务器启动并加载Servlet --> <load-on-startup>1</load-on-startup> </servlet> <!-- 配置Servlet的一你射(访问路径) --> <servlet-mapping> <!-- 配置Servlet名称,和上面的名称必须相同 --> <servlet-name>HelloServlet</servlet-name> <!-- 配置访问路径 --> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app>
目录结构图
相对路径:
一个文件相对于另一个文件的位置的关系
不能以/开头 写法: ./hello hello
访问1.html: http://localhost:8080/day09/1.html
访问HelloServlet: http://localhost:8080/day09/hello
访问2.html http://localhost:8080/day09/html/2.html
所以,在1.html中访问HelloServlet
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h2>1.html</h2> <a href="./hello">HelloServlet</a> <a href="hello">HelloServlet</a> </body> </html>
同理,在2.html中访问HelloServlet
<!DOCTYPE html> <html> <head> <title>2.html</title> <meta name="keywords" content="keyword1,keyword2,keyword3"> <meta name="description" content="this is my page"> <meta name="content-type" content="text/html; charset=UTF-8"> <!--<link rel="stylesheet" type="text/css" href="./styles.css">--> </head> <body> <h2>2.html</h2> <a href="../hello">Servlet</a> <a href=".././hello">Servlet</a> </body> </html>
绝对路径:以/开头 然后截取项目名后面的
访问Servlet:http://localhost:8080/day09/hello
在1.html使用绝对路径访问Servlet:http://localhost:8080/day09/hello
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <h2>相对路径</h2> <a href="./hello">HelloServlet</a> <a href="hello">HelloServlet</a> <h2>绝对路径</h2> <a href="http://localhost:8080/day09/hello">HelloServlet</a> <a href="/day09/hello">HelloServlet</a> </body> </html>
客户端绝对路径:/day09/hello 需要写项目名
服务器端绝对路径:/hello 不需要写项目名
客户端绝对路径和服务器端绝对路径的理解:设想这样一个场景,小A和小B是1班级的同学,小C是2班级的,有一天小C要找小A,那么小C先要去1班,然后再找小A;但是如果小B要找小A,此时就不要去1班级了,因为小A和小B本来就是1班级的,所以只需要直接找小A就可以了。
客户端关于路径问题的编程结论:
*.html,*.jsp内部使用绝对路径
*.css内部使用相对路径
*.js中使用绝对路径
总之:推荐使用绝对路径
八、ServletConfig对象和配置文件相关
public String getServletName() 获取配置文件中的servlet的名称 public String getInitPaarameter(String name) 获取初始化参数 public Enumeration getInitParameterNames() 获取初始化参数的名称s
如何获取ServletConfig对象,方法一:是在init(ServletConfig config)方法中
package cn.servlet; import java.io.IOException; import java.util.Enumeration; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @SuppressWarnings("serial") public class HelloServlet extends HttpServlet { @Override public void init(ServletConfig config) throws ServletException { System.out.println("Servlet的名称:"+config.getServletName()); Enumeration<String> initParameterNames = config.getInitParameterNames(); while(initParameterNames.hasMoreElements()){ String parameterName = initParameterNames.nextElement(); String parameterValue = config.getInitParameter(parameterName); System.out.println("初始化参数名称:"+parameterName+",初始化参数值"+parameterValue); } } @Override public void init() throws ServletException { System.out.println("init方法"); } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("utf-8"); response.getWriter().println("哇 这是Servlet"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>day09</display-name> <!-- 配置Servlet信息 --> <servlet> <!-- 配置Servlet名称,名称必须唯一 --> <servlet-name>HelloServlet</servlet-name> <!-- 配置Servlet的完全路径(包名+类名) --> <servlet-class>cn.servlet.HelloServlet</servlet-class> <!-- 配置初始化参数 --> <init-param> <param-name>你是谁</param-name> <param-value>我不知道我是谁</param-value> </init-param> <!-- 服务器启动并加载Servlet --> <load-on-startup>1</load-on-startup> </servlet> <!-- 配置Servlet的一你射(访问路径) --> <servlet-mapping> <!-- 配置Servlet名称,和上面的名称必须相同 --> <servlet-name>HelloServlet</servlet-name> <!-- 配置访问路径 --> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app>
另一种方法时:Servlet接口中就有获取ServletConfig对象的方法
public abstract ServletConfig getServletConfig();
package cn.servlet; import java.io.IOException; import java.util.Enumeration; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @SuppressWarnings("serial") public class HelloServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("utf-8"); response.getWriter().println("哇 这是Servlet"); ServletConfig config = this.getServletConfig(); System.out.println("Servlet的名称:"+config.getServletName()); Enumeration<String> initParameterNames = config.getInitParameterNames(); while(initParameterNames.hasMoreElements()){ String parameterName = initParameterNames.nextElement(); String parameterValue = config.getInitParameter(parameterName); System.out.println("初始化参数名称:"+parameterName+",初始化参数值"+parameterValue); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>day09</display-name> <!-- 配置Servlet信息 --> <servlet> <!-- 配置Servlet名称,名称必须唯一 --> <servlet-name>HelloServlet</servlet-name> <!-- 配置Servlet的完全路径(包名+类名) --> <servlet-class>cn.servlet.HelloServlet</servlet-class> <!-- 配置初始化参数 --> <init-param> <param-name>你是谁</param-name> <param-value>我不知道我是谁</param-value> </init-param> <!-- 服务器启动并加载Servlet --> <load-on-startup>1</load-on-startup> </servlet> <!-- 配置Servlet的一你射(访问路径) --> <servlet-mapping> <!-- 配置Servlet名称,和上面的名称必须相同 --> <servlet-name>HelloServlet</servlet-name> <!-- 配置访问路径 --> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app>
九、ServletContext对象(非常重要)
定义:WEB容器启动的时候,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前应用。
一个WEB应用对应一个ServletContext对象。
一个WEB应用下有多个Servlet程序。
所以,所有的Servlet程序都共享一个ServletContext对象。
作用:
获取web应用的全局初始化参数。
public Enumeration getInitParameterNames() public String getInitParameter(String name)
package cn.servlet; import java.io.IOException; import java.util.Enumeration; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 获取全局初始化参数 */ @SuppressWarnings("serial") public class HelloServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("utf-8"); response.getWriter().println("哇 这是Servlet"); /** * 在GenericServlet中有这个方法,而HttpServlet继承了GenericServlet,所以直接使用this.getServletContext()就可以获得ServletContext对象 * public ServletContext getServletContext() { ServletConfig sc = getServletConfig(); if (sc == null) { throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized")); } return sc.getServletContext(); } */ //获取ServletContext对象 ServletContext context = this.getServletContext(); Enumeration<String> parameterNames = context.getInitParameterNames(); while(parameterNames.hasMoreElements()){ String paramterName = parameterNames.nextElement(); String paramterValue = context.getInitParameter(paramterName); System.out.println("全局初始化参数名称:"+paramterName+",全局初始化参数值:"+paramterValue); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>day09</display-name> <!-- 配置全局初始化参数 --> <context-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </context-param> <!-- 配置Servlet信息 --> <servlet> <!-- 配置Servlet名称,名称必须唯一 --> <servlet-name>HelloServlet</servlet-name> <!-- 配置Servlet的完全路径(包名+类名) --> <servlet-class>cn.servlet.HelloServlet</servlet-class> </servlet> <!-- 配置Servlet的一你射(访问路径) --> <servlet-mapping> <!-- 配置Servlet名称,和上面的名称必须相同 --> <servlet-name>HelloServlet</servlet-name> <!-- 配置访问路径 --> <url-pattern>/hello</url-pattern> </servlet-mapping> </web-app>
实现数据的共享。
public void setAttribute(String name,Object object) 存入数据 public Object getAttribute(String name) 获取数据 public void removeAttribute(String name) 删除数据
计算访问次数的CountServlet
package cn.servlet; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 统计网站的访问次数 * @author Administrator * */ @SuppressWarnings("serial") public class CountServlet extends HttpServlet { /** * 实例一被创建,调用init方法进行初始化 * 在ServletContext对象中存入一个变量,赋值为0 */ @Override public void init() throws ServletException { ServletContext context = this.getServletContext(); context.setAttribute("count", 0); } /** * 每一个访问,都会执行该方法 * 拿出count变量,值自增,然后存入ServletContext对象之中 */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext context = this.getServletContext(); Integer count = (Integer) context.getAttribute("count"); context.setAttribute("count", ++count); response.setCharacterEncoding("utf-8"); response.getWriter().println("欢迎欢迎"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
显示访问次数的ShowServlet
package cn.servlet; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 显示网站被访问的此时 * */ @SuppressWarnings("serial") public class ShowServlet extends HttpServlet { /** * 获取网站的访问次数 */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { ServletContext context = this.getServletContext(); Integer count = (Integer) context.getAttribute("count"); if(count != null ){ response.setContentType("text/html;charset=utf-8"); response.getWriter().println("<h3>该网站一共被访问了:"+count+"次</h3>"); }else{ response.setContentType("text/html;charset=utf-8"); response.getWriter().println("<h3>该网站一共被访问了:0次</h3>"); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>day09</display-name> <!-- 配置Servlet信息 --> <servlet> <!-- 配置Servlet名称,名称必须唯一 --> <servlet-name>HelloServlet</servlet-name> <!-- 配置Servlet的完全路径(包名+类名) --> <servlet-class>cn.servlet.HelloServlet</servlet-class> </servlet> <servlet> <servlet-name>CountServlet</servlet-name> <servlet-class>cn.servlet.CountServlet</servlet-class> </servlet> <servlet> <servlet-name>ShowServlet</servlet-name> <servlet-class>cn.servlet.ShowServlet</servlet-class> </servlet> <!-- 配置Servlet的一你射(访问路径) --> <servlet-mapping> <!-- 配置Servlet名称,和上面的名称必须相同 --> <servlet-name>HelloServlet</servlet-name> <!-- 配置访问路径 --> <url-pattern>/hello</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>CountServlet</servlet-name> <url-pattern>/count</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>ShowServlet</servlet-name> <url-pattern>/show</url-pattern> </servlet-mapping> </web-app>
读取资源文件。
public InputStream getResourceAsStream(String path) 通过文件的地址获取输入流 public String getRealPath(String path) 通过文件的地址可以获取文件的绝对磁盘路径
传统方式读取资源文件
package cn.servlet; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.Properties; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 读取资源文件 */ @SuppressWarnings("serial") public class ReadServlet extends HttpServlet { /** * 传统方式读取资源文件 * 交给服务器处理,相对的位置是tomcat/bin目录 * */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { InputStream is = new FileInputStream("/day09/src/db.properties"); Properties p = new Properties(); p.load(is); String username = p.getProperty("username"); String password = p.getProperty("password"); String desc = p.getProperty("desc"); System.out.println("用户名:"+username+",密码:"+password+",描述:"+desc); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>day09</display-name> <!-- 配置Servlet信息 --> <servlet> <!-- 配置Servlet名称,名称必须唯一 --> <servlet-name>HelloServlet</servlet-name> <!-- 配置Servlet的完全路径(包名+类名) --> <servlet-class>cn.servlet.HelloServlet</servlet-class> </servlet> <servlet> <servlet-name>CountServlet</servlet-name> <servlet-class>cn.servlet.CountServlet</servlet-class> </servlet> <servlet> <servlet-name>ShowServlet</servlet-name> <servlet-class>cn.servlet.ShowServlet</servlet-class> </servlet> <servlet> <servlet-name>ReadServlet</servlet-name> <servlet-class>cn.servlet.ReadServlet</servlet-class> </servlet> <!-- 配置Servlet的一你射(访问路径) --> <servlet-mapping> <!-- 配置Servlet名称,和上面的名称必须相同 --> <servlet-name>HelloServlet</servlet-name> <!-- 配置访问路径 --> <url-pattern>/hello</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>CountServlet</servlet-name> <url-pattern>/count</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>ShowServlet</servlet-name> <url-pattern>/show</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>ReadServlet</servlet-name> <url-pattern>/read</url-pattern> </servlet-mapping> </web-app>
这种办法是不行的啊,会出错,因为找不到文件,因为此时的相对位置是Tomcat的bin目录。
package cn.servlet; import java.io.IOException; import java.util.Properties; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 读取资源文件 */ @SuppressWarnings("serial") public class ReadServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Properties p = new Properties(); //传入服务器端地址 p.load(this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties")); String username = p.getProperty("username"); String password = p.getProperty("password"); String desc = p.getProperty("desc"); System.out.println("用户名:"+username+",密码:"+password+",描述:"+desc); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>day09</display-name> <!-- 配置Servlet信息 --> <servlet> <!-- 配置Servlet名称,名称必须唯一 --> <servlet-name>HelloServlet</servlet-name> <!-- 配置Servlet的完全路径(包名+类名) --> <servlet-class>cn.servlet.HelloServlet</servlet-class> </servlet> <servlet> <servlet-name>CountServlet</servlet-name> <servlet-class>cn.servlet.CountServlet</servlet-class> </servlet> <servlet> <servlet-name>ShowServlet</servlet-name> <servlet-class>cn.servlet.ShowServlet</servlet-class> </servlet> <servlet> <servlet-name>ReadServlet</servlet-name> <servlet-class>cn.servlet.ReadServlet</servlet-class> </servlet> <!-- 配置Servlet的一你射(访问路径) --> <servlet-mapping> <!-- 配置Servlet名称,和上面的名称必须相同 --> <servlet-name>HelloServlet</servlet-name> <!-- 配置访问路径 --> <url-pattern>/hello</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>CountServlet</servlet-name> <url-pattern>/count</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>ShowServlet</servlet-name> <url-pattern>/show</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>ReadServlet</servlet-name> <url-pattern>/read</url-pattern> </servlet-mapping> </web-app>
用getRealPath()获取资源文件
package cn.servlet; import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 读取资源文件 */ @SuppressWarnings("serial") public class ReadServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Properties p = new Properties(); //传入服务器端地址 p.load(new FileInputStream(this.getServletContext().getRealPath("/WEB-INF/classes/db.properties"))); String username = p.getProperty("username"); String password = p.getProperty("password"); String desc = p.getProperty("desc"); System.out.println("用户名:"+username+",密码:"+password+",描述:"+desc); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>day09</display-name> <!-- 配置Servlet信息 --> <servlet> <!-- 配置Servlet名称,名称必须唯一 --> <servlet-name>HelloServlet</servlet-name> <!-- 配置Servlet的完全路径(包名+类名) --> <servlet-class>cn.servlet.HelloServlet</servlet-class> </servlet> <servlet> <servlet-name>CountServlet</servlet-name> <servlet-class>cn.servlet.CountServlet</servlet-class> </servlet> <servlet> <servlet-name>ShowServlet</servlet-name> <servlet-class>cn.servlet.ShowServlet</servlet-class> </servlet> <servlet> <servlet-name>ReadServlet</servlet-name> <servlet-class>cn.servlet.ReadServlet</servlet-class> </servlet> <!-- 配置Servlet的一你射(访问路径) --> <servlet-mapping> <!-- 配置Servlet名称,和上面的名称必须相同 --> <servlet-name>HelloServlet</servlet-name> <!-- 配置访问路径 --> <url-pattern>/hello</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>CountServlet</servlet-name> <url-pattern>/count</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>ShowServlet</servlet-name> <url-pattern>/show</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>ReadServlet</servlet-name> <url-pattern>/read</url-pattern> </servlet-mapping> </web-app>
十一、Http协议
响应头
location 和302状态码一起完成重定向的操作
重定向:
我向小A借钱,小A没有,然后小A给我一个暗号302和地址,我接收到这个暗号302,我就知道小A没有,我接收到的地址,就知道小A告诉我谁有钱,然后我就去向谁借钱。
package cn.http; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 重定向 * */ @SuppressWarnings("serial") public class DemoServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); //response.getWriter().print("我向小A借钱"); //发送暗号 302 以表示没钱 response.setStatus(302); //发送地址 用来告诉我谁有钱 response.setHeader("location", "/day09/xu.html"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>day09</display-name> <servlet> <servlet-name>ReadServlet</servlet-name> <servlet-class>cn.servlet.ReadServlet</servlet-class> </servlet> <servlet> <servlet-name>DemoServlet</servlet-name> <servlet-class>cn.http.DemoServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>DemoServlet</servlet-name> <url-pattern>/demo</url-pattern> </servlet-mapping> </web-app>
在webRoot下新建xu.html
<!DOCTYPE html> <html> <head> <title>xul.html</title> <meta name="keywords" content="keyword1,keyword2,keyword3"> <meta name="description" content="this is my page"> <meta name="content-type" content="text/html; charset=UTF-8"> <!--<link rel="stylesheet" type="text/css" href="./styles.css">--> </head> <body> <h1> 老许我是土豪,有的是钱</h1> </body> </html>
因为是客户端请求,所以使用的是客户端绝对路径。而且通过f12,我们知道客户端发送了2次请求,此时的请求地址变为了http://localhost:8080/day09/xu.html,而不是http://localhost:8080/day09/demo。
refresh 页面的定时刷新
package cn.http; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @SuppressWarnings("serial") public class RefreshServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); response.getWriter().println("定时刷新"); response.setHeader("refresh", "5;URL=/day09/xu.html"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <servlet> <servlet-name>RefreshServlet</servlet-name> <servlet-class>cn.http.RefreshServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>RefreshServlet</servlet-name> <url-pattern>/refresh</url-pattern> </servlet-mapping> </web-app>
last-modefied和if-modefied-since以及304状态码控制页面的缓存