深入探索Servlet_Hello World!_百度空间

(转载)  

在讨论Servlet之前,我们先来看看JSP运行机制:服务器运行JSP时候,底层是将JSP编译成为java类文件来运行的,这种类文件就是Servlet

那么我们可不可以直接编写Servlet类呢?

1. 当我们在JSP里面写大量Java代码时,可以把Java代码分离到Servlet中。

2. 当我们希望程序运行得快一些时,可以使用Servlet

下面讨论一下Servlet的生命周期

     当客户端发送请求(Request)到Servlet中,Servlet{dy}次运行的时候会调用init()方法,然后调用service()doGet()doPost()方法,如果此时有第二个客户端再来访问这个Servlet,将直接调用service()doGet()doPost()方法,这些方法是采用多线程的方法实现以便能够让多个用户同时访问,当服务器关闭的时候,Servlet消亡,会自动调用destroy()方法。

Servlet生命周期实例

编写Servlet1.javaServlet类,实现测试Servlet的生命周期,代码如下

package wang.servlets; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Servlet1 extends HttpServlet { public Servlet1() { //构造函数 System.out.println("构造函数"); } public void init() throws ServletException { //初始化函数,重写,{dy}次访问Servlet时自动调用 System.out.println("初始化函数"); } //这个函数在以get方式请求这个Servlet时运行 //以get方式请求这个Servlet:包括链接、get方式表单提交、直接访问这个servlet等 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("doGet"); } //这个函数在以post方式请求这个Servlet时运行 //以get方式请求这个Servlet:包括post方式表单提交等 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("doPost"); this.doGet(request, response);//将post的内容转接给doGet方法 } /*service函数既可以接收get请求,也可以接收post请求 protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.service(req, resp); }*/ public void destroy() { //消亡函数,重写 System.out.println("消亡函数"); } }

web.xml中注册上面的Servlet类,配置代码如下

<servlet> <servlet-name>Servlet1</servlet-name> <servlet-class>wang.servlets.Servlet1</servlet-class> </servlet> <servlet-mapping> <servlet-name>Servlet1</servlet-name> <url-pattern>/servlet/Servlet1</url-pattern> <!-- 定义了Servlet1的访问方式 --> </servlet-mapping>

然后启动服务器,在浏览器地址栏中输入:http://localhost:8080/ServletPro/servlet/Servlet1,运行结果如下

构造函数

初始化函数

doGet

从结果可以看出Servlet的执行过程,如果再次刷新页面,相当于另外一个客户端来访问,此时只会得到doGet的输出结果,由此说明初始化函数是{dy}次运行Servlet的时候才会被调用,然后停止服务器,会得到消亡函数的输出结果,说明调用了消亡函数。

如何在Servlet中访问JSP的内置对象

request:就是参数中的request

response:就是参数中的response

session:利用request.getSession()方法。

application:利用getServletContext()方法。

编写Servlet2.javaServlet类,实现在Servlet中访问JSP的内置对象(九九乘法表的实现),代码如下

package wang.servlets; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class Servlet2 extends HttpServlet { public Servlet2() { } public void init() throws ServletException { } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //怎样在Servlet内访问Jsp内置对象 PrintWriter out = response.getWriter();//得到out //得到request:就是参数中的request //得到response:就是参数中的response HttpSession session = request.getSession();//得到session ServletContext application = this.getServletContext();//得到application for(int i=1;i<=9;i++) { for(int j=1;j<=i;j++) { out.print(i + "*" + j + "=" + i*j); } out.println(); } } public void destroy() { } }

运行结果将得到一个九九乘法表。

Servlet应该负责的怎样的工作?

上面程序存在一个问题,就是显示九九乘法表是在Servlet中实现的,一般情况下Servlet是负责动作或控制逻辑,而对于显示功能就应该使用JSP。但是Servlet{zh0}不要有大量的逻辑,这样会造成Servlet很庞大,并且功能很混杂,这个时候就应该使用JavaBean来实现部分的逻辑。

下面介绍几种Servlet的高级用法

1. 实现页面的跳转。

2. 读取web.xml中的初始化参数。

3. 实现过滤器。

Servlet内实现页面跳转

编写含有表单的JSP页面,form.jsp,代码如下

<%@ page language="java" import="java.util.*" pageEncoding="gb2312"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>My JSP 'form.jsp' starting page</title> </head> <body> <form action="/PrjFu8/servlet/Servlet3"> 输入一个消息:<input name="message"/><br/> <input type="submit" value="提交"/> </form> </body> </html>

编写结果页面result.jsp,代码如下

<%@ page language="java" import="java.util.*" pageEncoding="gb2312"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>My JSP 'form.jsp' starting page</title> </head> <body> 这是结果页面 </body> </html>

编写负责跳转用的Servlet类,Servlet3.java,首先采用重定向的方法

package wang.servlets; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class Servlet3 extends HttpServlet { public Servlet3() { } public void init() throws ServletException { } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //跳转方法1.浏览器地址栏变成了目标页面的url response.sendRedirect("/PrjFu8/result.jsp"); } public void destroy() { } }

运行form.jsp页面,点击提交按钮,将跳转到result.jsp页面中,由于上面采用的重定向的方法,所以跳转之后,地址栏上的url地址也发生了变化。

使用重定向方法进行跳转时,存在一个问题,就是在结果页面得不到request中的内容,包括参数和属性。

Servlet3.java中的doGet方法中添加代码,测试能否得到request的内容

String str = request.getParameter("message"); System.out.println(str); 在result.jsp中添加如下代码 <% String str = request.getParameter("message"); out.println(str); %> 运行form.jsp页面,输入消息,点击提交按钮,将跳转到result.jsp页面中,这时在控制台上得到正确的结果,但是在result.jsp中得不到request中的内容,结果页面中request内容丢失。

下面使用forward跳转方法,这种方法不会丢失request中的内容,在doGet方法添加相应代码,doGet方法如下

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String str = request.getParameter("message"); System.out.println(str); //跳转方法1.浏览器地址栏变成了目标页面的url //到了目标页面之后,request内的参数值、属性值丢失了 response.sendRedirect("/PrjFu8/result.jsp"); //跳转方法2.浏览器地址栏没有变成目标页面的url //相当于在服务器内部将目标页面的输出送给客户端,request参数值、属性值没有丢失 ServletContext application = this.getServletContext(); RequestDispatcher rd = application.getRequestDispatcher("/result.jsp"); rd.forward(request, response); /** * 使用经验:如果在A页面有一些内容要在B页面显示,但是如果内容数量较大,并且是暂态数据 * 可以将内容不要放在session内,放在request内,用跳转方法2跳转到B页面显示,节省内存 * 跳转方法1相当于重新在客户端输入目标页面地址,重新请求 * 方法2相当于服务器内部的跳转 * 如果要跳转到服务器以外的url,必须使用方法1,比如跳转到百度 */ }

读取web.xml中的参数

web.xml中可以定义两种形式的参数,全局参数和局部参数

读取全局参数

web.xml中定义全局参数,代码如下

<?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"> <!-- 定义全局参数,所有的Servlet都可以读取 --> <context-param> <param-name>GlobalParam</param-name> <param-value>Welcome(Global)</param-value> </context-param> <servlet> <servlet-name>Servlet3</servlet-name> <servlet-class>wang.servlets.Servlet3</servlet-class> </servlet> <servlet-mapping> <servlet-name>Servlet3</servlet-name> <url-pattern>/servlet/Servlet3</url-pattern> </servlet-mapping> </web-app> 在Servlet中读取全局参数的代码可以编写在doGet方法,doGet方法代码如下

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //读取全局参数 ServletContext application = this.getServletContext(); String value = application.getInitParameter("GlobalParam"); System.out.println(value); }

读取局部参数

web.xml中定义局部参数,代码如下

<servlet> <servlet-name>Servlet3</servlet-name> <servlet-class>wang.servlets.Servlet3</servlet-class> <!-- 定义局部参数,只有这个Servlet才能识别 --> <init-param> <param-name>LocalParam</param-name> <param-value>Welcome(Local)</param-value> </init-param> </servlet>

doGet读取参数的代码如下

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //读取全局参数 ServletContext application = this.getServletContext(); String value = application.getInitParameter("GlobalParam"); System.out.println(value); //读取局部参数 String value2 = this.getInitParameter("LocalParam"); System.out.println(value2); }

实现过滤器

过滤器能使每次提交(广义,所有的getpost提交)的时候自动做一些事情。

如何编写过滤器?

1.编写一个类,实现javax.servlet.Filter。

2.编写doFilterFilterChain.doFilter(request, response)。

3.web.xml中注册这个过滤器。

<filter>

<filter-name>名称</filter-name>

<filter-class></filter-class>

</filter>

<filter-mapping>

       <filter-name>名称</filter-name>

       <url-pattern>/*</url-pattern>

</filter-mapping>

案例:利用过滤器解决中文问题

编写过滤器类,EncodingFilter.java,实现解决中文问题,代码如下

package wang.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public class EncodingFilter implements Filter { private String encoding; public EncodingFilter() { System.out.println("过滤器构造方法"); } public void init(FilterConfig config) throws ServletException { //初始化函数,服务器运行能自动运行一次 System.out.println("过滤器初始化函数"); config.getInitParameter("xxx"); //得到局部参数 encoding = config.getServletContext().getInitParameter("encoding");//得到全局参数 } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //每次提交都会运行 System.out.println("过滤器doFilter函数"); request.setCharacterEncoding(encoding);//解决中文问题 //过滤器是在提交到达处理之前运行,所以这里要将这个请求向后传递 chain.doFilter(request, response); } public void destroy() { //消亡时运行 System.out.println("过滤器消亡函数"); } } 在web.xml中注册这个过滤器,代码如下

<!-- 注册过滤器 --> <filter> <filter-name>EncodingFilter</filter-name> <filter-class>wang.filter.EncodingFilter</filter-class> </filter> <!-- 配置过滤器要过滤的对象 --> <filter-mapping> <filter-name>EncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>

过滤器比较重要的作用

1. 做初始化工作,不仅仅是为过滤器本身初始化,而且可以为整个系统工作初始化工作,并且初始化工作只运行一次。

2. 每次做提交的时候(广义上的提交),doFilter()方法都会被调用,这就给我们带来比较好的作用,比如我们登录某个系统,当我们退出该系统时,直接点击浏览器上面的后退按钮,如果不做处理,就会返回到之前登录状态,这显然是不安全的。我们可以通过检查session是不是为空来控制,session为空的话就提示用户重新登录,所以要清空页面的session,这时可以使用过滤器,把要检查session的页面共同用一个过滤器来做过滤,每次访问它们之前都来检查session。只要在访问的时候要做检查的工作,我们都可以用过滤器来实现。



郑重声明:资讯 【深入探索Servlet_Hello World!_百度空间】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——