Servlet和JSP读书笔记(二)
一. GenericServlet
1. 前面写的 Servlet和JSP学习笔记(一) 中的实例都是通过实现Servlet接口编写的,这样存在的问题就是:你必须实现Servlet中的所有方法,而不管该方法是否包含有用的
代码。所以,在此基础上Servlet API 为我们提供了GenericServlet 抽象类。
2. javax.servlet.GenericServlet接口 的源码如下:
package javax.servlet; import java.io.IOException;
import java.util.Enumeration; public abstract class GenericServlet implements Servlet, ServletConfig,
java.io.Serializable { private static final long serialVersionUID = 1L; private transient ServletConfig config; public GenericServlet() {
// NOOP
}
@Override
public void destroy() {
// NOOP by default
} @Override
public String getInitParameter(String name) {
return getServletConfig().getInitParameter(name);
} @Override
public Enumeration<String> getInitParameterNames() {
return getServletConfig().getInitParameterNames();
} /*
为我们提供了方法获取ServletConfig实例
*/
@Override
public ServletConfig getServletConfig() {
return config;
} @Override
public ServletContext getServletContext() {
return getServletConfig().getServletContext();
} @Override
public String getServletInfo() {
return "";
} /*
在此方法中将ServletConfig对象赋值给一个类成员变量,通过getServletConfig()获取该类级成员变量 */
@Override
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
} public void init() throws ServletException {
// NOOP by default
} public void log(String msg) {
getServletContext().log(getServletName() + ": " + msg);
} public void log(String message, Throwable t) {
getServletContext().log(getServletName() + ": " + message, t);
} @Override
public abstract void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException; public String getServletName() {
return config.getServletName();
}
}
该抽象类主要做了一下的三件事:
①在init方法中将ServletConfig对象赋值给一个类成员变量,通过getServletConfig()获取该类级成员变量。
②为Servlet接口中的方法供默认实现。
③ 提供方法包装ServletConfig中的方法。
2. GenericServlet示例。
备注:根据源码个人需求,在继承GenericServlet抽象类时,我们只需要实现service抽象方法就可以了,其他的方法GenericServlet已经帮我们做了处理。
① 编写Servlet 类
package com.hjj.servlet.two; import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; public class TestGenericServlet extends GenericServlet { @Override
public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
String name = this.getServletConfig().getInitParameter("two");
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8");
PrintWriter pw = response.getWriter();
pw.print("<html><head><head><title>测试GenericServlet</title><body> hello "+name+"</body></html>"); } }
②因为在之前的实例中我用的是注解的方式进行servlet的配置,所以在这里我使用web.xml进行配置。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>testGenericServlet</servlet-name>
<servlet-class>com.hjj.servlet.two.TestGenericServlet</servlet-class>
<init-param>
<param-name>two</param-name>
<param-value>GenericServlet</param-value>
</init-param>
</servlet> <servlet-mapping>
<servlet-name>testGenericServlet</servlet-name>
<url-pattern>/testGenericServlet</url-pattern>
</servlet-mapping> </web-app>
二. Servlet中的第二个包 javax.servlet.http.* 的主要类型
备注:这个包中提供的HttpServlet为我们编写Servlet提供另外一种写法
public abstract class javax.servlet.http.HttpServlet
public interface javax.servlet.http.HttpServletRequest public interface javax.servlet.http.HttpServletResponse
三. public class javax.servlet.http.HttpServlet
1. HttpServlet具体信息为:public abstract class HttpServlet extends GenericServlet implements java.io.Serializable
2.该类的部分源码如下:
package javax.servlet.http; import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.ResourceBundle; import javax.servlet.DispatcherType;
import javax.servlet.GenericServlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; public abstract class HttpServlet extends GenericServlet { private static final long serialVersionUID = 1L; private static final String METHOD_DELETE = "DELETE";
private static final String METHOD_HEAD = "HEAD";
private static final String METHOD_GET = "GET";
private static final String METHOD_OPTIONS = "OPTIONS";
private static final String METHOD_POST = "POST";
private static final String METHOD_PUT = "PUT";
private static final String METHOD_TRACE = "TRACE"; private static final String HEADER_IFMODSINCE = "If-Modified-Since";
private static final String HEADER_LASTMOD = "Last-Modified"; private static final String LSTRING_FILE =
"javax.servlet.http.LocalStrings";
private static ResourceBundle lStrings =
ResourceBundle.getBundle(LSTRING_FILE); public HttpServlet() {
// NOOP
} protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
{
String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_get_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
}
} protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException { String protocol = req.getProtocol();
String msg = lStrings.getString("http.method_post_not_supported");
if (protocol.endsWith("1.1")) {
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
} else {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
}
} //重载的service方法
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException { String method = req.getMethod(); if (method.equals(METHOD_GET)) {
long lastModified = getLastModified(req);
if (lastModified == -1) {
// servlet doesn't support if-modified-since, no reason
// to go through further expensive logic
doGet(req, resp);
} else {
long ifModifiedSince;
try {
ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
} catch (IllegalArgumentException iae) {
// Invalid date header - proceed as if none was set
ifModifiedSince = -1;
}
if (ifModifiedSince < (lastModified / 1000 * 1000)) {
// If the servlet mod time is later, call doGet()
// Round down to the nearest second for a proper compare
// A ifModifiedSince of -1 will always be less
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
} } else if (method.equals(METHOD_HEAD)) {
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp); } else if (method.equals(METHOD_POST)) {
doPost(req, resp); } else if (method.equals(METHOD_PUT)) {
doPut(req, resp); } else if (method.equals(METHOD_DELETE)) {
doDelete(req, resp); } else if (method.equals(METHOD_OPTIONS)) {
doOptions(req,resp); } else if (method.equals(METHOD_TRACE)) {
doTrace(req,resp); } else {
//
// Note that this means NO servlet supports whatever
// method was requested, anywhere on this server.
// String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[1];
errArgs[0] = method;
errMsg = MessageFormat.format(errMsg, errArgs); resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
}
}
//重写父类GenericServlet的service
@Override
public void service throws ServletException, IOException { HttpServletRequest request;
HttpServletResponse response; try {
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
} catch (ClassCastException e) {
throw new ServletException("non-HTTP request or response");
} //实际上调用上的还是上面的重载的方法:protected void service(HttpServletRequest req, HttpServletResponse resp)
service(request, response);
}
//此处省略部分源码
}
3. 该类继承了GenericServlet。重写的service方法,传递的参数依然是ServletRequest实例和ServletResponse实例。但是我们可以看到源码,它把ServletRequest和
ServletResponse两个实例分别转化为HttpServletRequest和HttpServletResponse实例。同时实现了重载了一个方法: service(HttpServletRequest req,
HttpServletResponse resp)。并且在参数类型为ServletRequest和ServletResponse的重写方法service 中调用了参数类型为HttpServletRequest 和
HttpServletResponse 的重载方法 service。service重载方法做的事情为:判断请求的类型是GET、POST、HEAD、OPTIONS、PUT、DELETE或者TRACE,然后分别调用相应
的doGet,doPost,doHead,doOptions,doPut,doDelete,doTrace方法。我们常用的请求有GET和POST,因此,我贴上去的源码只有doGet和doPut方法。基于源码的实现,我
们通过继承HttpServlet去编写一个Servlet应用程序时,只需要实现重写doGet()和doPost()方法即可。
四. 关于service重载方法传递的两个参数:HttpServletRequest和HttpServletResponse
1. HttpServletRequest
① 具体信息 :public interface extends ServletRequest
②HttpServletRequest表示HTTP环境中的Servlet请求。
③比ServletRequest接口增加的主要方法有:
public java.lang.String getContextPath() //返回请求Servlet应用程序的URI部分。
public Cookie[] getCookies() //返回一个Cookies数组
public java.lang.String getHeader(java.lang.String name) //返回指定的HTTP 标头的值
public java.lang.String getMethod() // 返回发出这条请求的HTTP方法的名称
public java.lang.String getQueryString()//返回请求Servlet应用的URL中的查询字符串
public HttpSession getSession(boolean create) //返回与这个请求有关的session对象。如果没找到,且create为true,则创建新的session
public HttpSession getSession() //返回与这个请求有关的session对象,如果没有则创建新的session并且返回
2. HttpServletResponse
①具体信息:public interface HttpServletResponse extends ServletResponse
②HttpServletResponse表示HTTP环境下的Servlet响应。
③声明的部分方法:
public void addCookie(Cookie cookie) //给当前的响应对象添加cookie public void sendRedirect(java.lang.String location) throws java.io.IOException // 将浏览器重定向到指定位置
public void addHeader(java.lang.String name, java.lang.String value ) // 给当前的响应添加标头
五. 采用继承HttpServlet编写Servlet小示例。
1. 通过继承HttpServlet实现编写一个Servlet应用程序。
package com.hjj.servlet.two; import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(name="testHttpServlet",urlPatterns="/testHttpServlet")
public class TestHttpServlet extends HttpServlet{ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("我是 doGet 方法,我被调用了");
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8"); PrintWriter pw = response.getWriter();
pw.println("<html><head></head><title>测试HttpServlet</title><body><center>");
pw.println("<center><h1>提交数据</h1></center>" );
pw.println("<form method='post' action='testHttpServlet'>");
pw.println("<p>姓名<input name='name' type='text '/></p>");
pw.println("<p><input value='提交' type='submit'/></p>");
pw.println("</form></center></body></html>");
} protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("我是 doPost 方法,我被调用了");
response.setContentType("text/html");
response.setCharacterEncoding("UTF-8"); String name = request.getParameter("name"); PrintWriter pw = response.getWriter();
pw.println("<html><head></head><title>测试提交数据</title><body>");
pw.println("<center><h1>");
pw.println("get提交的表单的值为:"+name);
pw.println("</h1></center></body></html>");
}
}
2. 在浏览器中输入url:http://localhost:8080/one/testHttpServlet
页面显示:
控制台打印:
我是 doGet 方法,我被调用了
3. 在上一个页面的表单中输入值
u
提交后页面显示:
控制台打印:
我是 doPost 方法,我被调用了
service
Servlet和JSP读书笔记(二)的更多相关文章
- Servlet和JSP读书笔记(一)
Java Servlet 技术,简称Servlet,是Java中用于开发web应用程序的基本技术. Servlet实际上也就是一个Java程序.一个Servlet应用程序通常包含很多Servlet.而 ...
- Servlet和JSP读书笔记(三)之Cookie
一. 浏览器和服务器之间通信的简单介绍引出Cookie和Session(只是简单的简介,不包含协议方面的知识) 1.当我们在浏览器中输入一个地址后,回车后就可以看到浏览器给我们展示的漂亮页面.在这个过 ...
- how tomcat works 读书笔记(二)----------一个简单的servlet容器
app1 (建议读者在看本章之前,先看how tomcat works 读书笔记(一)----------一个简单的web服务器 http://blog.csdn.net/dlf123321/arti ...
- 《你必须知道的.NET》读书笔记二:小OO有大原则
此篇已收录至<你必须知道的.Net>读书笔记目录贴,点击访问该目录可以获取更多内容. 一.单一职责原则 (1)核心思想:一个类最好只做一件事,只有一个引起它变化的原因 (2)常用模式:Fa ...
- spring揭秘 读书笔记 二 BeanFactory的对象注册与依赖绑定
本文是王福强所著<<spring揭秘>>一书的读书笔记 我们前面就说过,Spring的IoC容器时一个IoC Service Provider,而且IoC Service Pr ...
- ES6读书笔记(二)
前言 前段时间整理了ES6的读书笔记:<ES6读书笔记(一)>,现在为第二篇,本篇内容包括: 一.数组扩展 二.对象扩展 三.函数扩展 四.Set和Map数据结构 五.Reflect 本文 ...
- spring揭秘 读书笔记 二 BeanFactory的对象注冊与依赖绑定
本文是王福强所著<<spring揭秘>>一书的读书笔记 我们前面就说过,Spring的IoC容器时一个IoC Service Provider,并且IoC Service Pr ...
- 【记】《.net之美》之读书笔记(二) C#中的泛型
前言 上一篇读书笔记,很多小伙伴说这本书很不错,所以趁着国庆假期,继续我的读书之旅,来跟随书中作者一起温习并掌握第二章的内容吧. 一.理解泛型 1.为什么要使用泛型?-----通过使用泛型,可以极大地 ...
- Mastering Web Application Development with AngularJS 读书笔记(二)
第一章笔记 (二) 一.scopes的层级和事件系统(the eventing system) 在层级中管理的scopes可以被用做事件总线.AngularJS 允许我们去传播已经命名的事件用一种有效 ...
随机推荐
- BZOJ 2073: [POI2004]PRZ( 状压dp )
早上这道题没调完就去玩NOI网络同步赛了.... 状压dp , dp( s ) 表示 s 状态下所用的最短时间 , 转移就直接暴力枚举子集 . 可以先预处理出每个状态下的重量和时间的信息 . 复杂度是 ...
- 一、Nginx配置文件详解
配置文件介绍 主要有两部分:分别是 main:主体部分 http{}:虚拟主机配置部分 配置指令主要以分号结尾:配置语法:directive value1 [value2 ....] 支持使用的变量 ...
- 回归基础从新认识——HTML+CSS
前言 这段时间工作没那么繁杂,索性就想说来套系统的学习,之前去面试的时候,有被问及些基础的知识,居然回答不上来,也不能说是回答不上吧,回答的不全面.前端群上问了那个机构比较好,选择了慕课网.看了一段时 ...
- img标签中的src为php文件
先来看个例子: <img src="imgcode.php" alt="看不清楚,换一张" style="cursor: pointer;&qu ...
- javascript笔记整理(对象遍历封装继承)
一.javascript对象遍历 1.javascript属性访问 对象.属性名 对象['属性名'] var obj={name:'chen',red:function(){ alert(1);ret ...
- 终于懂了:Delphi重定义消息结构随心所欲,只需要前4个字节是消息编号就行了(有了这个,就有了主动)
Delphi重定义消息结构随心所欲,只需要前4个字节是消息编号就行了,跟Windows消息虽然尽量保持一致,但其实相互没有特别大的关系.有了这个,就有了主动,带不带句柄完全看需要. 比如这个结构就带句 ...
- XSS漏洞解决方案之一:过滤器
一:web.xml文件 <!-- 解决xss漏洞 --> <filter> <filter-name>xssFilter</filter-name> ...
- 修改Android 4.2.2的原生Camera引出的java.lang.UnsatisfiedLinkError: Native method not found,及解决方法
修改Android 4.2.2的原生Camera应用,做一些定制,将Camera的包名从之前的 package com.android.* 修改成了com.zhao3546.*. 调整后,应用可以正常 ...
- notepad++ 配置笔记
0.notepad++简单介绍 Notepad++是一套很有特色的自由软件的纯文字编辑器,有完整的中文化接口及支援多国语言撰写的功能.它的功能比 Windows 中的 Notepad更强大.Notep ...
- JSP页面小脚本实现日期比較,Java同理,精简过后的,可能在效率上不太好,有大大能够给优化下就更好了
<% java.text.SimpleDateFormat formatter = new java.text.SimpleDateFormat("yyyy-MM-dd ...