Servlet程序编写与配置、生命周期、取得内置对象、跳转

目录

简介

Servlet程序编写

servlet程序编写与web.xml配置

Servlet定义与执行流程分析

Servlet与表单

Servlet生命周期

简介

基础生命周期

Servlet扩展生命周期

内置对象取得

取得session内置对像

取得application内置对象

Servlet跳转

Servlet实现客户端跳转

Servlet实现服务器端跳转


简介

使用JSP+JavaBean可以完成项目的开发,但是项目开发的设计结构不清晰,所以不合适项目的结构划分,以及程序功能的扩充,代码有大量的重复操作。就需要Servlet类来改进,需要具备以下功能:

  • 此类可以接收所有的请求参数的操作(包括头信息、数据);

  • 此类可以跳转到任意的页面上;

  • 此类可以灵活的配置Java程序。

Servlet是使用Java实现CGI程序,Serlet是采用多线程的方式进行处理,所以处理的性能会个非常的高。

开发Servlet程序需要有Servelt开发的支持包,是在Tomcat的安装路径之中的servlet-api.jar,将开发包配置到CLASSPATH之中就能够开发servlet程序了。

Servlet程序编写

servlet程序编写与web.xml配置

如果要进行Servlet的程序编写,需要使用Servlet类去继承javax.servlet.http.HttpServlet父类(该类是一个抽象类)。这个类要想处理用户的操作请求需要覆doGet()方法,该方法的主要功能是处理get()请求(用户访问地址,发送地址信息)。

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {	}

这里关注的不是内置对象的名称,而是内置对象的类型。

范例: 定义一个Servlet

package cn.ren.myservlet;

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 HelloServlet extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		PrintWriter pw = resp.getWriter() ;  // 取得客户端的输出数据流
		pw.print("hello");
	}
}

Servlet是一个Java程序,Eclipse所有的Java程序编译过后都是默认保存在WEB-INF的目录下,安全性非常的高,用户无法访问,用户要想访问,需要修改web.xml文件的配置追加映射操作处理。

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
  <display-name>ServletProject</display-name>
  <servlet>
  	<servlet-name>hello-servlet</servlet-name>
  	<servlet-class>cn.ren.myservlet.HelloServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>hello-servlet</servlet-name>
  	<!-- 浏览器中的访问路径  -->
  	<url-pattern>/hello</url-pattern> 
  </servlet-mapping>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
</web-app>

同一个Servlet可以映射不同的名称,只需要配置多个“<servlet-maping>”元素即可。

范例:配置多个名称

Servlet定义与执行流程分析

servlet是一个纯粹的Java程序,通过web.xml进行部署,可以发现配置web.xml的时候使用的是完整的路径,而后web容器就能够加载配置,显然这是反射的应用。

Servlet与表单

编写一个表单将表单提交给Servlet进行显示

1、建立一个InputServlet程序类

package cn.ren.myservlet;

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 InputServlet extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		
		req.setCharacterEncoding("UTF-8");
		resp.setCharacterEncoding("UTF-8");
		String paramValue = req.getParameter("info") ;
		PrintWriter pw = resp.getWriter() ;  // 取得客户端的输出数据流
		pw.print("<h1>" + paramValue + "</h1>");
	}
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		this.doGet(req, resp);
	}
}

这里面没有路径的概念,路径完全由web.xml配置的

2、修改web.xml文件,追加InputServlet路径

  <servlet>
  	<servlet-name>InputServlet</servlet-name>
  	<servlet-class>cn.ren.myservlet.InputServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>InputServlet</servlet-name>
  	<url-pattern>/InputServlet</url-pattern>
  </servlet-mapping>

3、在根路径上建立一个input.html页面,该页面定义一个表单;

<%@ page language="java" pageEncoding="UTF-8"%>
<html>
<head>
<title>Insert title here</title>
</head>
<body>
<%
	request.setCharacterEncoding("UTF-8") ;
%>
<form action="InputServlet" method="post">
	请输入信息: <input type="text" name="info">
	<input type="submit" value="提交">
</form>
</body>
</html>

如果此时将input.jsp放在其它路径下,那么直接访问InputServlet是不可能的,因为此时的InputServelet被映射到了根路径下。那么最好的解决方案是把Servlet也映射到与页面相同的路径之中。

Servlet映射路径配置操作原则:必须要与处理的JSP保持在同一一个路径下,否在无法进行准确的定位。

Servlet生命周期

简介

servlet程序也会有与之相似的生命周期:

之前使用的doGet()、doPost()就属于服务的处理,这个服务可以调用多次。

Servlet生命周期的控制都在HttpServlet、GenericServlet类中提供,只需要按照指定的方法名称进行方法的覆写,即可以实现生命周期的控制。

基础生命周期

如果要想实现一个Servlet基础的生命周期只需要找到三类方法:

  • 初始化: public void init() throws ServletException;

  • 服务处理:主要是考虑GET与POST请求处理服务,覆写doGet()、doPost();

  • 销毁:public void destory();(不用覆写)

范例:编写一个基础生命周期控制

package cn.ren.myservlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class LifeCycleBvase extends HttpServlet {
	@Override
	public void init() throws ServletException {
		System.out.println("*** 初始化 ***");
	}
	
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("*** 服务 ****" + request.getMethod() + "**");
	}
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doGet(request, response);
	}
	@SuppressWarnings("unused")
	private void destory() {
		System.out.println("销毁");
	}
}
  <servlet>
  	<servlet-name>LifeCycleBvase</servlet-name>
  	<servlet-class>cn.ren.myservlet.LifeCycleBvase</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>LifeCycleBvase</servlet-name>
  	<url-pattern>/life</url-pattern>
  </servlet-mapping>

可以发现如下特点:

  • 默认情况下,容器启动的时候不会对servlet进行初始化,只有在访问的时候才会;

  • 服务方法可以使用多次;

  • 销毁操作一般出现在以下一种情况下:

       |- 容器关闭自动销毁

       |-当项目之中配置了自动加载新的程序类,这个时候也会发生销毁处理。

Servlet扩展生命周期

1、Servlet程序默认是在程序第一次执行的时候进行初始化,但是往往很多时候需要在启动容器的时候就进行初始化,那么就需要修改web.xml。

  <servlet>
  	<servlet-name>LifeCycleExtend</servlet-name>
  	<servlet-class>cn.ren.myservlet.LifeCycleExtend</servlet-class>
  	<load-on-startup>1</load-on-startup>
  </servlet>

2、在GenericServlet里面发现有两个初始化方法:

	@Override
	public void init(ServletConfig config) throws ServletException {
		System.out.println("*** 初始化 ***初始化参数:" + config.getInitParameter("msg"));
	}
  <servlet>
  	<servlet-name>LifeCycleExtend</servlet-name>
  	<servlet-class>cn.ren.myservlet.LifeCycleExtend</servlet-class>
  	<init-param>
  		<param-name>msg</param-name>
  		<param-value>ww.baidu.com</param-value>
  	</init-param>
  	<load-on-startup>1</load-on-startup>
  </servlet>

可以发现有参的init()替代无参的init();

3、服务使用的doGet()和doPost()方法,但是在GenericServlet里面有一个服务方法:

如果在程序中覆写了service方法,那么doGet()、doPost()就会失效,原因如下:

用户的所有的请求都会交给service()完成,service会根据用户请求的类型进行方法的分配,例如:GET请求找到doGet()方法,但是如果子类中没有覆写此方法,那么就会使用HttpServlet中的方法抛出异常,显然这是模板设计模式。如果service()被覆写了,那么子类覆写的doGet()、doPost()方法就会失效。

内置对象取得

如果要想开发基本程序,至少需要:request、response、application、session。

取得session内置对像

服务器区分不同sessio的本质依靠的是Cookie,因为所有的session id都会在服务器第一次响应之后发送给客户端浏览器的Cookie,在用户每一次发送请求的时候都会将Cookie的数据以头信息的方式发送给服务器,服务器依靠request接收这些信息,所以要想解决session的问题就必须依赖HttpServletRequest接口完成,使用该接口中的如下方法: 

  • 取得当前的Seesion:public HttpSeesion getSession();如果现在的Session存在则直接取得,如果不存在则创建一个新session。

范例:取得Session对象

package cn.ren.myservlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@SuppressWarnings("serial")
public class ObjectServlet extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		HttpSession ses = request.getSession() ; // 取得当前的Session对像
		System.out.println("*** Seesion ID = " + ses.getId());
		
	}
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doGet(request, response);
	}
}
  <servlet>
  	<servlet-name>ObjectServlet</servlet-name>
  	<servlet-class>cn.ren.myservlet.ObjectServlet</servlet-class>
  </servlet>
  <servlet-mapping>
  	<servlet-name>ObjectServlet</servlet-name>
  	<url-pattern>/obj</url-pattern>
  </servlet-mapping>

既然可以取得Session对象,那么就可以进行登录验证。

取得application内置对象

在开发之中往往使用getServletContext()方法来代替application对象,在GenericServlet类中提供有:public ServletContext getServletContext()。

范例:取得application内置对象

package cn.ren.myservlet;

import java.io.IOException;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class ObjectServlet extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		ServletContext app = super.getServletContext() ;
		System.out.println("PATH = " + app.getRealPath("/"));
	}
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doGet(request, response);
	}
}

拥有application对象之后就意味着可以进行文件操作了。

Servlet跳转

在web开发之中存在两类跳转:客户端跳转、服务器端跳转。下面观察从servlet跳转到JSP。

Servlet实现客户端跳转

在HttpServletResponse里面提供有跳转方法: sendRedirect()。

范例:在根目录中定义一个show.jsp页面,作为跳转后的页面

<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<title>Insert title here</title>
</head>
<body>
<h1>REQUEST属性:<%= request.getAttribute("paramA") %></h1>
<h1>SESSION属性:<%= session.getAttribute("paramB") %></h1>
</body>
</html>

范例:定义一个ForwardServlet.java

package cn.ren.myservlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class ForwardServlet extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setAttribute("paramA", "valueA");
		request.getSession().setAttribute("paramB", "valueB");
		response.sendRedirect("show.jsp");
	}
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doGet(request, response);
	}
}

发现地址栏发生了改变,所以属于客户端跳转,跳转之后session属性可以继续传递,而request由于请求路径的变化所以无法向后进行传递。

Servlet实现服务器端跳转

如果要想传递request属性就需要使用:<jsp:forward\>标签指令、pageContext.forward()。可是标签指令无法在Servlet中出现,同时pageContext只能jsp页面使用。

要想在Servlet中实现服务器端跳转需要使用“javax.servlet.RequestDispatcher”接口,在该接口中提供两个方法:

由于RequestDispatcher()是一个接口,如果要操作它需要使用接口的实例化对象,这个实例化需要依靠ServletRequest完成,在ServletRequest里面定义有一个方法:public RequestDispatcher getRequestDispatcher(String path) ;

范例:实现服务器端跳转

request.getRequestDispatcher("/show.jsp").forward(request, response);

在实际开发之中,往往会在Servlet程序中取出数据,在jsp页面显示(一般只会显示一次),所以往往会选择request属性范围传递,因为它占用的内存空间更小,释放得更快。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值