Servlet(一)

一、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状态码控制页面的缓存

时间: 2024-10-09 18:12:19

Servlet(一)的相关文章

Description Resource Path Location Type The superclass &quot;javax.servlet.http.HttpServlet&quot; was not foun

一段时间没亲自建新项目玩乐,今天建立了一Maven project的时候发现了以下异常,Description Resource Path Location Type The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path index.jsp /easyBuy/src/main/webapp line 1 JSP Problem 经过查找原因,原来是因为忘记设置server

Spring Cloud ZooKeeper集成Feign的坑2,服务调用了一次后第二次调用就变成了500,错误:Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is com.n

错误如下: 2017-09-19 15:05:24.659 INFO 9986 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.spring[email protected]56528192: startup date [Tue Sep 19 15:05:24 CST 2017]; root of context hierarchy 2017-09-19 15:05:24.858 INFO 9986 --

Java web之servlet

入坑必备之servlet(O(∩_∩)O哈!) 两个问题:是什么?怎么用? the first question:what?       Servlet是sun公司提供的一门用于开发动态web资源的技术,sun公司在其API中提供了一个servlet接口.由此可以理解为原生的servlet是一个接口,提到接口,我们应该想道我们必须去实现它才能被我们使用,servlet这个接口当然也不例外,从概念上讲,servlet是指sun公司提供的这个API接口,约定俗称,现在我们说的servlet是指实现这

JavaWeb之Java Servlet完全教程(转)

Servlet 是一些遵从Java Servlet API的Java类,这些Java类可以响应请求.尽管Servlet可以响应任意类型的请求,但是它们使用最广泛的是响应web方面的请求. Servlet必须部署在Java servlet容器才能使用.虽然很多开发者都使用Java Server Pages(JSP)和Java Server Faces(JSF)等Servlet框架,但是这些技术都要在幕后通过Servlet容器把页面编译为Java Servlet.也就是说,了解Java Servle

servlet理解

一.Servlet简介 Servlet是sun公司提供的一门用于开发动态web资源的技术. Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤: 1.编写一个Java类,实现servlet接口. 2.把开发好的Java类部署到web服务器中. 按照一种约定俗成的称呼习惯,通常我们也把实现了servlet接口的java程序,称之为Servlet 二.Servlet的运行过程 Servlet程序是由WEB

web.xml 中的listener、filter、servlet加载及一些配置

在项目中总会遇到一些关于加载的优先级问题,近期也同样遇到过类似的,所以自己查找资料总结了下,下面有些是转载其他人的,毕竟人家写的不错,自己也就不重复造轮子了,只是略加点了自己的修饰. 首先可以肯定的是,加载顺序与它们在 web.xml 文件中的先后顺序无关.即不会因为 filter 写在 listener 的前面而会先加载 filter.最终得出的结论是:listener -> filter -> servlet 同时还存在着这样一种配置节:context-param,它用于向 Servlet

Servlet简介与生命周期

转载请注明原文地址: 一:Servlet是什么 Servlet是运行在Web服务器上的Java程序,作为处理来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层.JSP在web服务器上要先转换成servlet,然后才能在JVM运行,并把结果拼接成浏览器可识别的文件(如html)传回浏览器显示. 二:Servlet的应用场景 单纯地对客户端的请求做处理时,如果我们用纯JSP文件(即:只有Java语句)来处理的话,还需要先转换为servlet才能运行

Java—Servlet开发

掌握Servlet API是Java Web的基础. 首先新建一个Web类型的工程,然后再创建Servlet类.而且Servlet类名,要以Servlet作为后缀.--Servlet技术,就在Servlet类中. 然后要运行Servlet,就需要一个容器(JSP也需要),如开源的Tomcat. Tomcat的配置: 下载:

Servlet的生命周期

Servlet的生命周期是由Servlet的容器来控制的,它可以分为三个阶段:初始化.运行.销毁1.初始化阶段:(1)Servlet容器加载Servlet类,把Servlet类的.class文件中数据读到内存中:(2)然后Servlet容器创建一个ServletConfig对象.ServletConfig对象包含了Servlet的初始化配置信息:(3)Servlet容器创建一个Servlet对象:(4)Servlet容器调用Servlet对象的init方法进行初始化.2.运行阶段当Servlet

Servlet入门

1.在tomcat中新建一个day01web应用,然后在web应用中新建一个web-inf/classes目录:2.在classes目录中新建一个FirstServlet.java文件:package cn.itcastimport java.io.*;import javax.servlet.*;public class Firstservlet extends GenericServlet{ public void service(ServletRequest req, ServletRes