第一章_servlet

时间:2021-12-10 06:38:06

[Servlet与Jsp学习指南]

*学习这servlet前。需要下载servlet-api.jar,MyEclipse给自己带来的需求javaEE3.0的天赋足以使用注解获得的版本号servlet

1.1、Servlet API概述

Javax.servlet 包括定义Servlet与Servlet容器之间契约的类和接口

Javax.servlet.http 包括定义http servlet与servlet容器之间契约的类和接口

Javax.servlet.annotation 包括对servlet、filter和listener进行标注的注解。它还为标注元件指定元数据。

Javax.servlet.descriptor 包括为web应用程序的配置信息提供编程式訪问的类型。

Servlet技术的核心是Servlet接口。这是全部Servlet类都必须直接或者间接实现的一个接口。用户的请求会引发Servlet容器调用一个servlet的service方法,并给这种方法传入一个ServletRequest实例和一个ServletResponse实例。

1.2、Servlet

Servlet接口定义了下面5个方法。

Void init(ServletConfig config) throws ServletException

Void service(ServletRequest request,ServletResponse response) throws ServletException,java.io.IOException

Void destroy()

java.lang.String getServletInfo()

ServletConfig getServletConfig()

Init、service和destroy方法属于Servlet声明周期方法。Servlet容器将依据下面原则调用这三个方法。

1. Init。

第一次请求Servlet时,Servlet容器就会调用这种方法。在兴许的请求中,将不再调用该方法。

能够利用这种方法来编写一些应用程序初始化相关的代码。在调用这种方法时,Servlet容器会传递一个ServletConfig。一般来说,会将ServletConfig赋给一个类级变量,以便Servlet类中的其它方法也能够使用这个对象。

2. Service。每次请求Servlet时,Servlet容器都会调用这种方法。

必须在这里编写要Servlet完毕的对应代码。第一次请求Servlet时,Servlet容器会调用init方法和service方法,对于兴许请求,则仅仅调用service方法。

3. Destroy。

要销毁Servlet时,Servlet容器就会调用这种方法。它通常发生在卸载应用程序,或者关闭Servlet容器的时候。

一般来说,能够在这种方法中编写一些资源清理相关的代码。

Servlet中的另外两个方法是非声明周期方法:getServletInfo和getServletConfig。

1.  getServletInfo。

该方法返回Servlet的描写叙述,能够返回可能实用的随意字符串,甚至是null。

2. getServletConfig。该方法返回由Servlet容器传给init方法的ServletConfig。可是,为了让getServletConfig返回非null值。你肯定已经为传给init方法的ServletConfig赋给了一个类级变量。

*必须注意个一点是线程安全性。一个应用程序中的全部用户将共用一个Servlet实例。因此不建议使用类级变量。除非他们是仅仅读的,或者是java.util.concurrent.atomic包中的成员。

1.3、编写基础的Servlet应用程序

package servlet;

import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
@WebServlet(name="MyServlet",urlPatterns={"/my"})
public class MyServlet implements Servlet{
private transient ServletConfig servletConfig ; @Override
public void destroy() {
// TODO Auto-generated method stub } @Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return servletConfig;
} @Override
public String getServletInfo() {
// TODO Auto-generated method stub
return "My Servlet";
} @Override
public void init(ServletConfig servletConfig) throws ServletException {
// TODO Auto-generated method stub
this.servletConfig = servletConfig ;
} @Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
// TODO Auto-generated method stub
String servletName = servletConfig.getServletName() ;
res.setContentType("text/html");
PrintWriter writer = res.getWriter() ;
writer.print("<html><head></head><body>Hello from " + servletName + "</body></html>") ;
} }

第一章_servlet

1.4、ServletRequest

对于每个HTTP请求,Servlet容器都会创建一个serveltRequest实例,并将它传给Servlet的service方法。ServletRequest封装有关请求的信息。

以下是ServletRequest接口中的方法。

Public int getContentLength()

返回请求主体中的字节数。假设不知道字节的长度,该方法将返回-1。

Public java.lang.String getContentType()

返回请求主体MIME类型,假设不知道类型。则返回null。

Public java.lang.String getParameter(java.lang.String name)

返回指定请求參数的值

Public java.lang.String getProtocol()

返回这个HTTP请求的协议名称和版本

getParameter是ServletRequest中最经常使用的方法。

该方法通经常使用来返回一个HTML表单域的值。

getParameter也能够用来获取查询字符串的值。比如:假设利用以下这个URI调用一个servlet:

id=123">http://domain/context/servletName?

id=123

将能够在Servlet中利用以下这个语句来获取id的值

String id = request.getParameter(“id”) ;

注意。假设该參数不存在,那么getParameter将返回null。

1.5、ServletResponse

ServletResponse中定义的当中一个方法是getWriter方法,它返回能够将文本传给client的java.io.PrintWriter。在默认情况下,PrintWriter对象採用ISO-8859-1编码。

1.6、ServletConfig

为了从一个Servlet内部获取某个初始參数的值。应该在由Servlet容器传给Servlet的init方法的ServletConfig中调用getInitParameter方法。

getInitParameter方法的签名例如以下:

java.lang.getInitParameter(java.lang.String name) ;

此外,getInitParameterNames方法则是返回全部初始化參数名称的一个Enumeration:

java.util.Enumeration<java.lang.String> getInitParameterNames()

除了这2个方法外,ServletConfig还提供了还有一个非常实用的方法:getServletContext。能够利用这种方法从Servlet内部获取ServletContext。

package servlet;

import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
@WebServlet(name="ServletConfigDemoServlet",
urlPatterns={"/servletConfigDemo"},
initParams={
@WebInitParam(name="admin",value="Benjamin"),
@WebInitParam(name="email",value="whx449261417@sina.com")
}
)
public class ServletConfigDemoServlet implements Servlet{
private transient ServletConfig servletConfig ;
@Override
public void destroy() {
} @Override
public ServletConfig getServletConfig() {
// TODO Auto-generated method stub
return servletConfig;
} @Override
public String getServletInfo() {
// TODO Auto-generated method stub
return "servletConfig demo";
} @Override
public void init(ServletConfig servletConfig) throws ServletException {
// TODO Auto-generated method stub
this.servletConfig = servletConfig ;
} @Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
ServletConfig servletConfig = getServletConfig() ;
String admin = servletConfig.getInitParameter("admin") ;
String email = servletConfig.getInitParameter("email") ;
res.setContentType("text/html");
PrintWriter writer = res.getWriter() ;
writer.print("<html><head></head><body>Admin:"+admin+"<br/>Email:"+email+"</body></html>") ;
} }

第一章_servlet

第一章_servlet
第一章_servlet

1.7、ServletContext

ServletContext标识Servlet应用程序。每一个Web应用程序仅仅有一个context。在分布式环境中,一个应用程序同一时候部署到多个容器中。而且每台java虚拟机都有一个ServletConfig对象。

在ServletConfig中调用getServletContext方法能够获得ServletContext。

1.8、GenericServlet

GenericServlet通过在init方法中将ServletConfig对象赋给一个类级变量servlet-config,实现对ServletConfig的保存。以下是GeneericServlet的源码:

package javax.servlet;

import java.io.IOException;
import java.io.Serializable;
import java.util.Enumeration;
import java.util.ResourceBundle; public abstract class GenericServlet
implements Servlet, ServletConfig, Serializable
{
private static final String LSTRING_FILE = "javax.servlet.LocalStrings";
private static ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.LocalStrings");
private transient ServletConfig config; public void destroy()
{
} public String getInitParameter(String name)
{
ServletConfig sc = getServletConfig();
if (sc == null) {
throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
} return sc.getInitParameter(name);
} public Enumeration<String> getInitParameterNames()
{
ServletConfig sc = getServletConfig();
if (sc == null) {
throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
} return sc.getInitParameterNames();
} public ServletConfig getServletConfig()
{
return this.config;
} public ServletContext getServletContext()
{
ServletConfig sc = getServletConfig();
if (sc == null) {
throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
} return sc.getServletContext();
} public String getServletInfo()
{
return "";
} public void init(ServletConfig config)
throws ServletException
{
this.config = config;
init();
} public void init()
throws ServletException
{
} public void log(String msg)
{
getServletContext().log(getServletName() + ": " + msg);
} public void log(String message, Throwable t)
{
getServletContext().log(getServletName() + ": " + message, t);
} public abstract void service(ServletRequest paramServletRequest, ServletResponse paramServletResponse)
throws ServletException, IOException; public String getServletName()
{
ServletConfig sc = getServletConfig();
if (sc == null) {
throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
} return sc.getServletName();
}
}

大家考虑一下为什么GenericServlet中有两个init方法?

GenericServlet通过在init方法中将ServletConfig对象赋给一个类级变量servletConfig,实现对ServletConfig的保存。

可是假设在类中覆盖了这种方法,则调用servlet中的init方法。而且必须调用super.init(servletConfig)来保存ServletConfig。为了避免这么做。GenericServlet又另外提供了一个init方法,它不带參数。当把ServletConfig赋给servletConfig之后。这种方法就会被第一个init方法调用。从而不影响servletConfig的创建。

1.9、HTTP Servlet

1.9.1 HttpServlet

HttpServlet类覆盖javax.servlet.GenericServlet类。在使用HttpServlet时,还要使用HttpServletRequest和HttpServletResponse对象,它们分别标识Servlet请求和Servlet响应。

HttpServletRequest接口集成javax.servlet.ServletRequest。HttpServletResponse继承javax.servlet.ServletResponse。

这个新的service方法与javax.servlet.Servlet中的差别在于。前者接受的是HttpServletRequest和HttpServletResponse,而不是ServletRequest和ServletResponse。

原始的service方法将请求和响应对象进行向下转换。分别从Servlet容器转换成HttpServletRequest和HttpServletResponse,并调用新的service方法。

HttpServlet中新的service方法会查看通经常使用来发送琴秋(通过调用request.getMethod)的Http方法,并调用下面某个方法(doGet、doPost、doHead、doPut、doTrace、doOptions和doDelete)。

总之,HttpServlet中有两项特性是GenericServlet所没有的:

1、不覆盖service方法,而是覆盖doGet、doPost,或者两者都覆盖调。

2、将用HttpServletRequest和HttpServletResponse取代ServletRequest和ServletResponse

1.9.2 HttpServletRequest

HttpServletRequest表示HTTP环境中的Servlet请求。它集成javax.servlet.ServletRequest接口。并添加了几个方法。比如:

Java.lang.String getContextPath()

返回表示请求context的请求URI部分。

Cookie[] getCookies()

返回一个Cookie对象数组

java.lang.String getHeader(java.lang.String name)

返回指定HTTP标头的值

java.lang.String getMethod()

返回发出这条请求的HTTP方法的名称

java.lang.String getQueryString()

返回请求URL中的查询字符串

HttpSession getSession()

返回与这个请求有关的session对象。

假设没有找到,则创建新的session对象。

HttpSession getSession(boolean create)

返回与这个请求有关的session对象。假设没有找到,而且create參数为true,那么将创建新的session对象。假设为false,返回空

1.9.3 HttpServletResponse

HttpServletResponse表示HTTP环境下的Servlet响应。以下是当中定义的部分方法:

Void addCookie(Cookie cookie)

给这个响应对象加入cookie

Void addHeader(java.lang.String name,java.lang.String value)

给这个响应对象加入标头

Void sendRedirect(java.lang.String location)

发送响应代号,将浏览器重定向到指定的位置

1.10、处理HTML表单

1.11使用部署描写叙述符(配置文件)

package app01c;

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 SimpleServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html") ;
PrintWriter writer = resp.getWriter() ;
writer.print("<html><head></head><body>Simple Servlet</body></html>") ;
}
}
package app01c;

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 WelcomeServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html") ;
PrintWriter writer = resp.getWriter() ;
writer.print("<html><head></head><body>Welcome</body></html>") ;
}
}
<?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">
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>ss</servlet-name>
<servlet-class>app01c.SimpleServlet</servlet-class>
<load-on-startup>10</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ss</servlet-name>
<url-pattern>/simple</url-pattern>
</servlet-mapping> <servlet>
<servlet-name>ww</servlet-name>
<servlet-class>app01c.WelcomeServlet</servlet-class>
<load-on-startup>20</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ww</servlet-name>
<url-pattern>/welcome</url-pattern>
</servlet-mapping>
</web-app>

这样我们就能够利用以下这些路径去訪问它们了:

http://localhost:8080/app01c/simple

http://localhost:8080/app01c/welcome

1.12、小结

Servlet技术是JavaEE技术的组成部分。Servlet容器中执行的全部Servlet,以及容器与Servlet之间的契约,都採用了javax.servlet.Servlet接口的形式。Javax.servlet包也提供了实现Servlet接口的GenericServlet抽象类。

这是一个便利类。能够通过扩展它来创建Servlet。可是,大多数现代的Servlet都在HTTP环境中处理请求。因此,将javax.servlet.http.HttpServlet类子类化会更有意义。HttpServlet类本身也是GenericServlet的一个子类。

版权声明:本文博主原创文章。博客,未经同意不得转载。

第一章_servlet的更多相关文章

  1. 《Django By Example》第一章 中文 翻译 (个人学习,渣翻)

    书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:本人目前在杭州某家互联网公司工作, ...

  2. MyBatis3&period;2从入门到精通第一章

    第一章一.引言mybatis是一个持久层框架,是apache下的*项目.mybatis托管到goolecode下,再后来托管到github下.(百度百科有解释)二.概述mybatis让程序将主要精力 ...

  3. Nova PhoneGap框架 第一章 前言

    Nova PhoneGap Framework诞生于2012年11月,从第一个版本的发布到现在,这个框架经历了多个项目的考验.一直以来我们也持续更新这个框架,使其不断完善.到现在,这个框架已比较稳定了 ...

  4. 第一章 MYSQL的架构和历史

    在读第一章的过程中,整理出来了一些重要的概念. 锁粒度  表锁(服务器实现,忽略存储引擎). 行锁(存储引擎实现,服务器没有实现). 事务的ACID概念 原子性(要么全部成功,要么全部回滚). 一致性 ...

  5. 第一章 Java多线程技能

    1.初步了解"进程"."线程"."多线程" 说到多线程,大多都会联系到"进程"和"线程".那么这两者 ...

  6. 【读书笔记】《编程珠玑》第一章之位向量&amp&semi;位图

    此书的叙述模式是借由一个具体问题来引出的一系列算法,数据结构等等方面的技巧性策略.共分三篇,基础,性能,应用.每篇涵盖数章,章内案例都非常切实棘手,解说也生动有趣. 自个呢也是头一次接触编程技巧类的书 ...

  7. 《JavaScript高级程序设计(第3版)》阅读总结记录第一章之JavaScript简介

    前言: 为什么会想到把<JavaScript 高级程序设计(第 3 版)>总结记录呢,之前写过一篇博客,研究的轮播效果,后来又去看了<JavaScript 高级程序设计(第3版)&g ...

  8. 《Entity Framework 6 Recipes》翻译系列 &lpar;1&rpar; -----第一章 开始使用实体框架之历史和框架简述

    微软的Entity Framework 受到越来越多人的关注和使用,Entity Framework7.0版本也即将发行.虽然已经开源,可遗憾的是,国内没有关于它的书籍,更不用说好书了,可能是因为EF ...

  9. 《Entity Framework 6 Recipes》翻译系列&lpar;2&rpar; -----第一章 开始使用实体框架之使用介绍

    Visual Studio 我们在Windows平台上开发应用程序使用的工具主要是Visual Studio.这个集成开发环境已经演化了很多年,从一个简单的C++编辑器和编译器到一个高度集成.支持软件 ...

随机推荐

  1. emmet的使用

    http://blog.wpjam.com/m/emmet-grammar/ 使用 Emmet 生成 HTML 的语法详解 开源程序 浏览:21537 2013年05月09日 文章目录[隐藏] 生成 ...

  2. Date、Calender类及日期和字符串转换

    Calendar是一个抽象类,抽象类java.util.Calendar 不可以通过new来获取一个实例,可以通过类方法getinstance()获取此类型的一个通用的对象 ①用法: Calendar ...

  3. 在iMac机os x上装win7双系统经验心得

    首先,以上iMac的内存超过4GB,需要安装x64版的win7,可以用QQ旋风从这里下载(cn_windows_7_ultimate_with_sp1_x64_dvd_u_677408.iso) 下载 ...

  4. 使用FROM确认按钮&lpar;键盘13号键&rpar;提交特性并使用ajax&period;POST提交&period;

    如果又想使用FROM确认按钮(键盘13号键)提交特性  还能继续用AJAX.POST提交.就需要使用return false 来阻止FROM默认提交 代码如下: HTML页面 这里最关键就是用了ret ...

  5. 最短路径算法之三——Bellman-Ford算法

    Bellman-Ford算法 Dijkstra算法无法判断含负权边的图的最短路. 如果遇到负权,在没有负权回路存在时,即便有负权的边,也可以采用Bellman-Ford算法正确求出最短路径. PS:负 ...

  6. 前端学习 -- Html&amp&semi;Css -- 表格

    表格在日常生活中使用的非常的多,比如excel就是专门用来创建表格的工具,表格就是用来表示一些格式化的数据的,比如:课程表.银行对账单.在网页中也可以来创建出不同的表格. 在HTML中,使用table ...

  7. tree-data

    [{ label: '一级 1', children: [{ label: '二级 1-1', children: [{ label: '三级 1-1-1' }] }] }, { label: '一级 ...

  8. tsung执行时报Can&&num;39&semi;t locate Template&period;pm的解决

    [root@openfire-x86v-app01 20141118-0931]# tsung_stats creating subdirectory data creating subdirecto ...

  9. Java设计模式六大原则之场景应用分析

    定义:不要存在多于一个导致类变更的原因. 通俗的说.即一个类仅仅负责一项职责. 问题由来:类T负责两个不同的职责:职责P1,职责P2.当由于职责P1需求发生改变而须要改动类T时,有可能会导致原本执行正 ...

  10. iqueryable lambda表达式

    1.groupby 1.group by var newLaborDtos = laborDtos.GroupBy(s => new { s.FinancingAmount, s.Company ...