重定向与请求分派

“局部”参数——ServletConfig——servlet初始化参数

“全局”参数——ServletContext——上下文初始化参数

Web app的“构造器”——ServletContextListener

实战:如何创建一个全局的dog?

1、重定向与请求分派。

        resp.sendRedirect("http://www.cnblogs.com/xkxf/");
        RequestDispatcher view = req.getRequestDispatcher("result.jsp"); // 为JSP实例化一个请求分派器

        view.forward(req, resp); // 使用请求分派器要求容器准备好JSP,并向JSP发送请求和响应
  • 重定向由客户端完成,请求分派由服务器完成。
  • 重定向是让客户完成工作,而请求分派要求服务器上的某某来完成任务。

2、在页面中显示email。

很显然,不可能通过硬编码来完成。而是需要从数据库拿数据,可以想象这个过程,当我们点开某个社交网站,然后点开“个人资料”,这个时候servlet中会调用一个getEmail的方法得到email,之后把它传给视图,最后展示给用户。

那么,有没必要在部署描述文件(DD,deployment descriptor)中存储email呢?假设你写搭建一个个人博客、编辑一份网页简历,这是有可能的,总要好过硬编码在html中。

3、还是需要快速搭建一个测试环境,沿用上一节的代码。

4、如何在DD中添加email呢?如下所示:

先修改web.xml,

<?xml version="1.0" encoding="ISO-8859-1" ?>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4"> <servlet>
<servlet-name>MyTest</servlet-name>
<servlet-class>com.example.web.MyTest</servlet-class> <init-param>
<param-name>email</param-name>
<param-value>wyzxk_fx@163.com</param-value>
</init-param>
</servlet> <servlet-mapping>
<servlet-name>MyTest</servlet-name>
<url-pattern>/MyTest.do</url-pattern>
</servlet-mapping> </web-app>

修改servlet,

package com.example.web;

        import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*; public class MyTest extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
resp.setContentType("text/html"); PrintWriter out = resp.getWriter();
out.println(getServletConfig().getInitParameter("email"));
// 这里相当于调用this.getServletConfig().ge...,this是谁呢?this是一个HttpServlet对象。
}
}

重启Tomcat,点击submit,可以看到

BTW:需要注意的是,不能在构造函数中调用getServletConfig(),原因是在这个时候ServletConfig根本不存在!

package javax.servlet;

import java.io.IOException;

public interface Servlet {
void init(ServletConfig var1) throws ServletException; ServletConfig getServletConfig(); void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException; String getServletInfo(); void destroy();
}

回忆一下servlet的生命周期,servlet的生命周期由Web容器所掌控,Web容器首先调用Servlet的构造函数,在这之后才调用Servlet的init()函数。观察上面的代码,可以发现init()的参数正是ServletConfig。实际情况是这样的:

  • 容器初始化一个servlet的时候,会为这个servlet建立一个唯一的ServletConfig。
  • 容器从DD(也就是web.xml)中“读出”ServletConfig(也就是init-param)并把这些参数交给ServletConfig。然后把ServletConfig传递给servlet的init()方法。

5、有时候,需要一个更“全局”的参数,在Web的世界里,它被叫做上下文初始化参数,与servlet初始化参数不同的是,它的有效范围是整个Web App,而不仅仅是一个servlet。设置方法为:

<?xml version="1.0" encoding="ISO-8859-1" ?>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4"> <context-param>
<param-name>email</param-name>
<param-value>wyzxk_fx@163.com</param-value>
</context-param>
<servlet>
<servlet-name>MyTest</servlet-name>
<servlet-class>com.example.web.MyTest</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>MyTest</servlet-name>
<url-pattern>/MyTest.do</url-pattern>
</servlet-mapping> <!--在这之后,还可以以有更多的servlet,而context-param是对所有servlet有效的!--> </web-app>

调用的方式与servlet初始化参数类似:

package com.example.web;

        import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*; public class MyTest extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
resp.setContentType("text/html"); PrintWriter out = resp.getWriter();
// out.println(getServletConfig().getInitParameter("email"));
out.println(getServletContext().getInitParameter("email"));
// 只需要把Config改成Context就Ok了!
}
}

重启tomcat之后,点击submit,仍旧会得到相同的输出页面,对用户来说,不会体验到任何差别!不过需要再次强调:每个servlet有一个ServletConfig,每个Web应用有一个ServletContext。

6、在一些场合下,我们希望有一些代码在Web应用提供服务之前,首先被执行,类似于通过“静态加载块”来加载数据库连接,也就是在程序正式工作前,完成一些初始化工作,例如,创建一个“全局”的数据库连接,或是其它的全局对象,这就需要用到ServletContextListener

我们知道,完成一个事件响应,首先需要实现接口,然后注册事件,最后写响应方法。那么,这个Listener应该由谁来注册呢?如何使用这个监听者呢?

7、一个简单的ServletContextListener:如何创建一个全局的dog?

package com.example;

public class Dog {
private String breed; public Dog(String breed) {
this.breed = breed;
}
public String getBreed() {
return breed;
}
}
<?xml version="1.0" encoding="ISO-8859-1" ?>

<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4"> <servlet>
<servlet-name>ListenerTester</servlet-name>
<servlet-class>com.example.ListenerTester</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>ListenerTester</servlet-name>
<url-pattern>/ListenerTester.do</url-pattern>
</servlet-mapping> <context-param>
<param-name>breed</param-name>
<param-value>Great Dane</param-value>
</context-param>


<listener>
<listener-class>
com.example.MyServletContextListener
<!--在初始化任何servlet之前初始化应用-->
</listener-class>
</listener>
</web-app>
package com.example;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener; public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
ServletContext servletContext = servletContextEvent.getServletContext();
String breed = servletContext.getInitParameter("breed"); Dog dog = new Dog(breed);
servletContext.setAttribute("dog"
, dog);
} @Override
public void contextDestroyed(ServletContextEvent servletContextEvent) { }
}
package com.example;

import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.*; public class ListenerTester extends HttpServlet {
@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
PrintWriter out = resp.getWriter(); out.println("test context attribute set by listener <br />");
out.println("<br />"); Dog dog = (Dog)getServletContext().getAttribute("dog");
out.println("Dog's breed is: " + dog.getBreed());
}
}

【Head First Servlets and JSP】笔记7:如何创建一个全局的dog?的更多相关文章

  1. 天书笔记:如何创建一个现代的footer(页脚)

    此笔记纯属本人脑残笔记,阅读困难不理解属正常现象,初学者尽量不要阅读,否则轻则口吐白沫重则走火入魔,切记切记 老规矩,效果图 这个布局也是从b站看到的,回来自己实现了一遍 HTML: <div ...

  2. twisted 学习笔记二:创建一个简单TCP客户端

    #coding=utf-8 from twisted.internet import reactor,protocol class QuickClient(protocol.Protocol): de ...

  3. 【Head First Servlets and JSP】笔记23:Expression Language(EL) 完全攻略

    基本上是<Head First Servlets and JSP>内容的整理.扩充.顺便推荐一个供参考的JSP教程:JSP Tutorial内容很全面,还有一些有趣的实例. 完整代码参考 ...

  4. 【Head First Servlets and JSP】笔记22:直接从请求到JSP & 获取Person的嵌套属性

    直接从请求到JSP,不经过servlet <!DOCTYPE html> <html lang="en"> <head> <meta ch ...

  5. 【Head First Servlets and JSP】笔记1

    1.把Java放到HTML中,JSP应运而生. 2.Servlet本身并没有main()方法,所以必须要有其他Java程序去调用它,这个Java程序就是Web容器(Container).Tomcat就 ...

  6. 【Head First Servlets and JSP】笔记12:URL重写

    1.会话管理的核心在于“交换会话ID”,来回传递cookie是最简单的方法,容器通过客户端发来的JSSESIONID查找匹配的对话. 2.如果浏览器禁用了cookie,那就意味着浏览器将忽略响应首部中 ...

  7. JSP笔记02——概述(转)

    不完全翻译,结合谷歌,一定主观性,还可能有误,原始内容地址:https://www.tutorialspoint.com/jsp/jsp_overview.htm 主要内容如下: 什么是JSP? 为什 ...

  8. jsp笔记2(编译指令与动作指令)

    一.jsp的编译指令是通知jsp引擎的消息,不会生成输出. jsp的3个编译指令: page:针对当前页面的指令   include:包含另一个页面的指令   taglib:用于定义和访问自定义标签 ...

  9. maven权威指南学习笔记(三)——一个简单的maven项目

    目标: 对构建生命周期 (build  lifecycle),Maven仓库 (repositories),依赖管理 (dependency management)和项目对象模型 (Project O ...

随机推荐

  1. 设置内容 - text()、html() 以及 val()

    我们将使用前一章中的三个相同的方法来设置内容: text() - 设置或返回所选元素的文本内容 html() - 设置或返回所选元素的内容(包括 HTML 标记) val() - 设置或返回表单字段的 ...

  2. 用关键字interface定义接口,通过关键字implements来实现接口

    [定义]Java中,能够完成特定功能的,由若干属性和方法组织成的,相对独立的属性和方法的集合. [用途]实现类的多继承,以解决Java只能单继承,不支持多继承的问题. [特点] 用关键字interfa ...

  3. Intent跳转系统的应用

    1.从google搜索内容    Intent intent = new Intent();    intent.setAction(Intent.ACTION_WEB_SEARCH);    int ...

  4. 如何顺利解决mac下命令不管用的情况

    背景: 昨晚通过brew安装了node,结果导致我的终端除了cd和ls管用外,其他的命令都不管用了,网上搜索了一大堆,结果没有一个能正确解决我的问题的,记录一下吧. 打开终端就显示: -bash: t ...

  5. Android开发:《Gradle Recipes for Android》阅读笔记1.5

    这节讲的是如何如何添加JAVA依赖库. 默认的android项目有两个build.gradle文件,分别位于顶级目录,和应用自己的目录下(通常放在一个叫app的目录下面). gradle支持多种方式列 ...

  6. Android Studio中debug和release模式默认的参数配置

    The possible properties and their default values are: debuggable:表示是否可以在手机上调试程序. 在Eclipse中,只有android ...

  7. JS实现全选,全不选

    <script type="text/javascript"> function selectItem() { document.getElementById(&quo ...

  8. OC中nil、Nil、NULL、NSNull的区别

    nil:指向OC中对象的空指针 e.g.: NSString *string = nil; Nil:指向OC中类的空指针    e.g.:Class class = Nil; NULL:指向其他类型的 ...

  9. JavaScript数据结构与算法-队列练习

    队列的实现 // 队列类 function Deque () { this.dataStore = []; this.enqueueFront = enqueueFront; this.enqueue ...

  10. js内置数据类型

    JS 中分为七种内置类型,七种内置类型又分为两大类型:基本类型和对象(Object). 基本类型有六种: number , string , boolean , null , undefined ,  ...