Servlet (1)

Servlet 的 HelloWorld

1.创建一个 Servlet 接口的实现类. 

public class HelloServlet implements Servlet {

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		System.out.println("destroy");
	}

	@Override
	public ServletConfig getServletConfig() {
		// TODO Auto-generated method stub
		System.out.println("getServletConfig");
		return null;
	}

	@Override
	public String getServletInfo() {
		// TODO Auto-generated method stub
		System.out.println("getServletInfo");
		return null;
	}

	@Override
	public void init(ServletConfig servletConfig) throws ServletException {
		// TODO Auto-generated method stub
		System.out.println("init");
	}

	@Override
	public void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException {
		// TODO Auto-generated method stub
		System.out.println("service");
	}

	public HelloServlet() {
		super();
		// TODO Auto-generated constructor stub
		System.out.println("HelloServlet ...Constructor");
	}

}

2.在 web.xml 文件中配置和映射这个 Servlet

	<!-- 配置和映射 Servlet -->
	<servlet>
		<!-- Servlet 注册的名字 -->
		<servlet-name>helloServlet</servlet-name>
		<!-- Servlet 的全类名 -->
		<servlet-class>com.javaweb.HelloServlet</servlet-class>
	</servlet>
	
	<servlet-mapping>
		<!-- 需要和某一个 servlet 节点的 serlvet-name 子节点的文本节点一致 -->
		<servlet-name>helloServlet</servlet-name>
		<!-- 映射具体的访问路径: / 代表当前 WEB 应用的根目录. -->
		<url-pattern>/hello</url-pattern>
	</servlet-mapping>

启动Tomcat,浏览器访问http://localhost:8080/项目名/hello

控制台打印

HelloServlet ...Constructor
init
service

3.Servlet 生命周期

第一次访问http://localhost:8080/项目名/hello,结果如上

之后再访问只输出

...
service
service
service
...

stop tomcat后打印

destroy
1). 构造器: 只被调用一次. 只有第一次请求 Servlet 时, 创建 Servlet 的实例. 调用构造器. 这说明 Serlvet 的单实例的!
2). init 方法: 只被调用一次. 在创建好实例后立即被调用. 用于初始化当前 Servlet. 
3). service: 被多次调用. 每次请求都会调用 service 方法. 实际用于响应请求的. 
4). destroy: 只被调用一次. 在当前 Servlet 所在的 WEB 应用被卸载前调用. 用于释放当前 Servlet 所占用的资源. 

4. load-on-startup 参数:

  <servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>com.javaweb.HelloServlet</servlet-class>
	<!-- 可以指定 Servlet 被创建的时机 -->
     <load-on-startup>1</load-on-startup>
  </servlet>
  
  <servlet>
	  <servlet-name>secondServlet</servlet-name>
	  <servlet-class>com.javaweb.SecondServlet</servlet-class>
	  <load-on-startup>2</load-on-startup>
  </servlet>


2). load-on-startup: 可以指定 Serlvet 被创建的时机. 若为负数, 则在第一次请求时被创建.若为 0 或正数, 则在当前 WEB 应用被
Serlvet 容器加载时创建实例, 且数值越小越早被创建


5. 关于 serlvet-mapping

1). 同一个Servlet可以被映射到多个URL上,即多个 <servlet-mapping> 元素的<servlet-name>子元素的设置值可以是同一个
Servlet的注册名。

例如

<servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>com.javaweb.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
   <servlet-name>hello</servlet-name>
   <url-pattern>/hello</url-pattern>
</servlet-mapping>
    <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>/hello2</url-pattern>
</servlet-mapping>
即  HelloServlet 可以 通过 /hello 访问,也可以通过/hello2来访问

2). 在Servlet映射到的URL中也可以使用 * 通配符,但是只能有两种固定的格式:
一种格式是“*.扩展名”,另一种格式是以正斜杠(/)开头并以“/*”结尾。

<servlet-mapping>
	<servlet-name>secondServlet</servlet-name>
	<url-pattern>/*</url-pattern>
</servlet-mapping>

OR

<servlet-mapping>
	<servlet-name>secondServlet</servlet-name>
	<url-pattern>*.do</url-pattern>
</servlet-mapping>

注意: 以下的既带 / 又带扩展名的不合法. 

<servlet-mapping>
	<servlet-name>secondServlet</servlet-name>
	<url-pattern>/*.action</url-pattern>
</servlet-mapping>

6. ServletConfig: 封装了 Serlvet 的配置信息, 并且可以获取 ServletContext 对象

1). 配置 Serlvet 的初始化参数

<servlet>
    <servlet-name>hello</servlet-name>
    <servlet-class>com.javaweb.HelloServlet</servlet-class>
	
	<!-- 配置 Serlvet 的初始化参数。 且节点必须在 load-on-startup 节点的前面 -->
    <init-param>
	  <!-- 参数名 -->
      <param-name>user</param-name>
	  <!-- 参数值 -->
      <param-value>root</param-value>
    </init-param>
    <init-param>
      <param-name>password</param-name>
      <param-value>root</param-value>
    </init-param>
	
     <load-on-startup>1</load-on-startup>
 </servlet>

2). 获取初始化参数,Serlvet 的配置名称(了解),获取 ServletContext 对象

	@Override
	public void init(ServletConfig servletConfig) throws ServletException {
		// TODO Auto-generated method stub
		System.out.println("init");
		// 获取初始化参数
		String user = servletConfig.getInitParameter("user");
		System.out.println("user: " + user);

		Enumeration<String> names = servletConfig.getInitParameterNames();
		while (names.hasMoreElements()) {
			String name = names.nextElement();
			String value = servletConfig.getInitParameter(name);
			System.out.println("--" + name + " : " + value);

		}

		//获取Servlet注册名称
		String servletName = servletConfig.getServletName();
		System.out.println(servletName);
		
		//获取ServletContext
		ServletContext servletContext = servletConfig.getServletContext();

	}

结果

init
user: root
--user : root
--password : root
hello


ServletConfig的4个常用方法:

(1)、public String getInitParameter(String name):返回指定名称的初始化参数值;

(2)、public Enumeration getInitParameterNames():返回一个包含所有初始化参数名的Enumeration对象;

(3)、public String getServletName():返回在DD文件中<servlet-name>元素指定的Servlet名称;

(4)、public ServletContext getServletContext():返回该Servlet所在的上下文对象;



7.ServletContext


1). 可以由  SerlvetConfig 获取:

ServletContext servletContext = servletConfig.getServletContext();

2). 该对象代表当前 WEB 应用: ServletContext,是一个全局的储存信息的空间,服务器开始,其就存在,服务器关闭,其才释放。

可以从中获取到当前 WEB 应用的各个方面的信息.


①. 获取当前 WEB 应用的初始化参数

设置初始化参数: 可以为所有的 Servlet 所获取

  <context-param>
    <param-name>driver</param-name>
    <param-value>com.mysql.jdbc.Driver</param-value>
  </context-param>

方法:

getInitParameter
getInitParameterNames

代码

	@Override
	public void init(ServletConfig servletConfig) throws ServletException {
		// TODO Auto-generated method stub
		System.out.println("init");
		
		...

		// 获取ServletContext
		ServletContext servletContext = servletConfig.getServletContext();

		String contextParam = servletContext.getInitParameter("driver");
		System.out.println(contextParam);
		Enumeration<String> names2 = servletContext.getInitParameterNames();

		while (names2.hasMoreElements()) {
			String name = names2.nextElement();
			String value = servletContext.getInitParameter(name);
			System.out.println("kk" + name + " : " + value);

		}

	}

②. 获取当前 WEB 应用的某一个文件在服务器上的绝对路径, 而不是部署前的路径

		 String realPath = servletContext.getRealPath("/");
		 System.out.println(realPath);
		 String realPath2 = servletContext.getRealPath("/hello.jsp");
		 System.out.println(realPath2);

输出

D:\workspaces\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\FirstWeb\
D:\workspaces\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps\FirstWeb\hello.jsp

③. 获取当前 WEB 应用的名称: 

getContextPath()

		 String servletContextName = servletContext.getServletContextName();
		 String contextPath = servletContext.getContextPath();
		 System.out.println(contextPath + "------" + servletContextName);
结果
/FirstWeb------FirstWeb

④. 获取当前 WEB 应用的某一个文件对应的输入流. 

getResourceAsStream(String path): path 的 / 为当前 WEB 应用的根目录. 

代码:

		Properties pros = new Properties();
		
		try {
			ClassLoader classLoader = getClass().getClassLoader();
			InputStream is = classLoader.getResourceAsStream("jdbc.properties");
			System.out.println("1. " +  is);
			pros.load(is);
			
			System.out.println(pros.getProperty("name"));  
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		pros = new Properties();
		
		try {
			InputStream is2 = servletContext.getResourceAsStream("/WEB-INF/classes/jdbc.properties");
			System.out.println("2. " + is2);
			pros.load(is2);
			System.out.println(pros.getProperty("name"));  
		} catch (Exception e) {
			e.printStackTrace();
		}

等等。。。


8. GET 请求和 POST 请求:

1). 使用GET方式传递参数:

①. 在浏览器地址栏中输入某个URL地址或单击网页上的一个超链接时,浏览器发出的HTTP请求消息的请求方式为GET。 
②. 如果网页中的<form>表单元素的 method 属性被设置为了“GET”,浏览器提交这个FORM表单时生成的HTTP请求消息的请求方式也为GET。 
③. 使用GET请求方式给WEB服务器传递参数的格式:  

http:/localhost:8080/counter.jsp?name=lc&password=123

④. 使用GET方式传送的数据量一般限制在 1KB 以下。 


2). 使用 POST 方式传递参数:


①. POST 请求方式主要用于向 WEB 服务器端程序提交 FORM 表单中的数据: form 表单的 method 置为 POST
②. POST 方式将各个表单字段元素及其数据作为 HTTP 消息的实体内容发送给 WEB 服务器,传送的数据量要比使用GET方式传送的数据量大得多。  


POST /counter.jsp HTTP/1.1
referer: http://localhost:8080/Register.html
content-type: application/x-www-form-urlencoded
host: localhost:8080
content-length: 43


name=zhangsan&password=123              --请求体中传递参数



9. 如何在 Serlvet 中获取请求信息:

1). Servlet 的 service() 方法用于应答请求: 因为每次请求都会调用 service() 方法


public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException

ServletRequest: 封装了请求信息. 可以从中获取到任何的请求信息.
ServletResponse: 封装了响应信息, 如果想给用户什么响应, 具体可以使用该接口的方法实现. 


这两个接口的实现类都是服务器给予实现的, 并在服务器调用 service 方法时传入. 

2). ServletRequest: 封装了请求信息. 可以从中获取到任何的请求信息.


①. 获取请求参数: 

> String getParameter(String name): 根据请求参数的名字, 返回参数值. 
若请求参数有多个值(例如 checkbox), 该方法只能获取到第一个提交的值. 


> String[] getParameterValues(String name): 根据请求参数的名字, 返回请求参数对应的字符串数组. 

> Enumeration getParameterNames(): 返回参数名对应的 Enumeration 对象, 
类似于 ServletConfig(或 ServletContext) 的 getInitParameterNames() 方法. 


> Map getParameterMap(): 返回请求参数的键值对: key: 参数名,  value: 参数值, String 数组类型. 


②. 获取请求的 URI:


HttpServletRequest httpServletRequest = (HttpServletRequest) request;

String requestURI = httpServletRequest.getRequestURI();
System.out.println(requestURI); //  /day_29/loginServlet


③. 获取请求方式: 


String method = httpServletRequest.getMethod();
System.out.println(method); //GET

④. 若是一个 GET 请求, 获取请求参数对应的那个字符串, 即 ? 后的那个字符串


String queryString = httpServletRequest.getQueryString();
System.out.println(queryString); //user=ddf&password=123456&interesting=game&interesting=party&interesting=shopping


⑤. 获取请求的 Serlvet 的映射路径 
  
   String servletPath = httpServletRequest.getServletPath();
   System.out.println(servletPath);  //  /loginServlet
   
⑥. 和 attribute 相关的几个方法:   


3). HttpServletRequest: 是 SerlvetRequest 的子接口. 针对于 HTTP 请求所定义. 里边包含了大量获取 HTTP 请求相关的方法. 
 
4). ServletResponse: 封装了响应信息, 如果想给用户什么响应, 具体可以使用该接口的方法实现. 


①. *getWriter(): 返回 PrintWriter 对象. 调用该对象的 print() 方法, 将把 print() 中的参数直接打印
到客户的浏览器上. 


②. 设置响应的内容类型: response.setContentType("application/msword");


③. void sendRedirect(String location): 请求的重定向. (此方法为 HttpServletResponse 中定义.)

form表单

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<form action="loginService" method="post">
		用户名<input name="user" type="text"><br> 密码<input
			name="password" type="password"><br> <br> <br>
		爱好 : 
		<input type="checkbox" name="interesting" value="reading">reading 
		<input type="checkbox" name="interesting" value="shopping">shopping
		<input type="checkbox" name="interesting" value="sport">sport 
		
		<input type="submit">
	</form>
</body>
</html>


import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Map;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

public class LoginServlet implements Servlet {

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
	}

	@Override
	public ServletConfig getServletConfig() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getServletInfo() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void init(ServletConfig arg0) throws ServletException {
		// TODO Auto-generated method stub

	}

	@Override
	public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		System.out.println("请求来了。。。");

		// 获取请求参数
		String user = request.getParameter("user");
		String password = request.getParameter("password");
		System.out.println("user=" + user + " password=" + password);
		//request.getParameter("interesting") checkbox 只能获取 第一个被选中的
		String interesting = request.getParameter("interesting");
		System.out.println("request.getParameter(\"interesting\")的值:" + interesting);
		
		//获取checkbox 全部被选中的值
		String[] intreastinges = request.getParameterValues("interesting");
		for (String str : intreastinges) {
			System.out.println(str);
		}

		//获取全部请求参数
		Enumeration<String> names = request.getParameterNames();
		while (names.hasMoreElements()) {
			String name = names.nextElement();
			String value = request.getParameter(name);
			System.out.println(name + " =" + value);
		}

		Map<String, String[]> map = request.getParameterMap();
		for (Map.Entry<String, String[]> entry : map.entrySet()) {
			System.out.println(entry.getKey() + " " + Arrays.asList(entry.getValue()));
		}

		HttpServletRequest httpServletRequest = (HttpServletRequest) request;
		String requestURI = httpServletRequest.getRequestURI();
		System.out.println(requestURI);
		
		//获取请求参数对应的那个字符串, 即 ? 后的那个字符串
		String queryString = httpServletRequest.getQueryString();
		System.out.println(queryString);

		//获取请求的 Serlvet 的映射路径 
		String servletPath = httpServletRequest.getServletPath();
		System.out.println(servletPath);

		//获取web项目的根路径
		String contextPath = httpServletRequest.getContextPath();
		System.out.println(contextPath);

		PrintWriter writer = response.getWriter();
		writer.println("helloworld");

	}

}



请问HttpServletRequest和ServletRequest的区别? 


servlet理论上可以处理多种形式的请求响应形式 
http只是其中之一 


所以HttpServletRequest、 HttpServletResponse分别是ServletRequest和ServletResponse的子类 


参考阅读: 
========== 
HttpServletRequest和ServletRequest都是接口 
HttpServletRequest继承自ServletRequest 
HttpServletRequest比ServletRequest多了一些针对于Http协议的方法。 
如 
getHeader(String name), 
getMethod() , 
getSession() 
等等。 
他们对应的实现类: 
javax.servlet.ServletRequestWrapper (implements javax.servlet.ServletRequest) 
javax.servlet.http.HttpServletRequestWrapper (implements javax.servlet.http.HttpServletRequest) 












發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章