Servlet——服务器端小型java应用程序

Servlet基本内容

Servlet通过Http协议接收和响应来自客户端的请求。

实际开发中我们创建Servlet类的话直接在eclipse中创建Servlet就很便捷,IDE工具会自动帮我们继承HttpServlet类,并且下面会给出覆写类的选项,根据需要选择需要覆写的类比较方便。

点击next会来到xml文件的配置选项页面:

可以看到我们可以填写Servlet名字、映射路径、web.xml文件路径等,这些eclipse会根据上一步的配置自动填写,我们可以根据需要更改,点击finish即完成Servlet的创建。

我们将上面Servlet文件创建完成并放到服务器上,本机访问地址为:

http://localhost:8080/session_test/servlet/SessionDemo1

http协议 本机地址:端口号  项目目录   Servlet自动生成的映射目录(因为我没有修改)

我们在访问的时候会经历一下步骤:

1.浏览器访问tomcat服务器

2.服务器找到session_test应用

3.在web.xml文件中找到映射路径/servlet/SessionDemo1

4.由映射路径找到对应的对应servlet对应java类

5.找到java类SessionDemo1,并实例化

6.调用init(ServletConfig config)方法

7.调用service(ServletRequest req, ServletResponse res)方法

8.将消息响应给客户端服务器

9.关闭服务器或者重新部署的时候时会调用destroy()方法

Servlet体系结构

Servlet是一个接口。其待实现方法如下:

 void destroy()
          Called by the servlet container to indicate to a servlet that the servlet is being taken out of service.
 ServletConfig getServletConfig()
          Returns a ServletConfig object, which contains initialization and startup parameters for this servlet.
 String getServletInfo()
          Returns information about the servlet, such as author, version, and copyright.
 void init(ServletConfig config)
          Called by the servlet container to indicate to a servlet that the servlet is being placed into service.
 void service(ServletRequest req, ServletResponse res)
          Called by the servlet container to allow the servlet to respond to a request.

创建Servlet的方法有三种:

①创建一个类实现Servlet接口并重写所有方法

②创建一个类继承GenericServlet抽象类。GenericServlet类实现了Servlet接口、ServletConfig接口以及java.io.Serializable接口。

③创建一个类继承HttpServlet类。这个类继承了GenericServlet类。

三个类之间的关系也可以从源码中看出:Servlet..源码粘贴   。

Servlet总体继承实现关系如下:

Servlet全靠这张图了,很重要!!!!!!!!!

自动生成的Servlet会带有很多说明和参数我们可以:找到MyEclipse\Common\plugins目录,找或在百度下载下面的jar包:com.genuitec.eclipse.wizards_9.0.0.me201108091322.jar复制到上面目录,可以让我们创建的Servlet更简洁。

Servlet映射

 访问步骤里已经给出了映射的基本模式——<Servlet-mapping>标签配置地址映射到<servlet>中的java类。

下面还要说的是多映射&&映射通配符:

多映射<servlet-mapping>拥有等同于一个<servlet>中的<servlet-name>的值,但是各个<servlet-mapping>的<url-pattern>内对应多个路径,即我们可以通过配置的不同路径来访问同一个Servlet。

映射通配   写在url-pattern标签   *代表通配任意字符串        /*任意字符串都可以访问            /action/*以/action开头的请求都可以访问            *.do    以*.字符串的请求都可以访问

通配优先级:绝对匹配> /开头匹配> 扩展名方式匹配

Servlet安全

Servlet是多线程的,存在线程安全问题,如果需要定义变量我们最好不要定义全局变量,这样可以避免使用公共条件,使用局部变量就不存在安全问题了。

ServletConfig接口——Servlet获取配置信息

 String getInitParameter(String name)
          

返回包含指定初始化参数值的String,如果参数不存在,则返回null。

 Enumeration getInitParameterNames()
        以Enumeration of String对象的形式返回servlet的初始化参数的名称,如果servlet没有初始化参数,则返回空的Enumeration。
 ServletContext getServletContext()
          返回对调用者正在执行的ServletContext的引用。
 String getServletName()
         返回此servlet实例的名称。

我们定义一个全局变量和init(ServletConfig config)方法中的config对应。

作用一:可以在doGet方法中取出初始化的配置对象,通过调用上面的方法获取需要的配置参数参数。

作用二:可以获取ServletContext对象

ServletContext接口——代表整个应用

ServletContext对象包含在ServletConfig对象中,ServletConfig对象在初始化servlet时由Web服务器提供给servlet。ServletContext是单实例,一个应用只能有一个此对象。

常用方法
void setAttribute(String name,object value)

向ServletContext对象的map中添加数据

Object getAttribute(String name);

从ServletContext对象的map中取数据

void removeAttribute(String name);

根据name去移除数据

获取全局配置信息

首先在web.xml文件中设置全局信息:

  <!-- 配置当前应用的全局信息 -->
  <context-param>
  	<param-name>encoding</param-name>
  	<param-value>UTF-8</param-value>
  </context-param>

在doGet方法中获取全局信息encoding的值UTF-8,并打印:

String encoding = this.getServletContext().getInitParameter("encoding");
System.out.println(encoding);

说明:getInitParameter(String name)这个方法来自于ServletContext接口,返回值是枚举字符串类型。

获取资源路径

getRealPath(String path) 返回包含给定虚拟路径的实际路径的String

虚拟路径:应用目录的下一个目录WEB-INF后,如:/WEB-INF/classes/b.properties。可以得到当前应用任何位置的任何资源。

请求转发

getRequestDispatcher(String path)

注意:这里的String必须以“/”开始

返回一个RequestDispatcher对象,请求转发,将请求传递
		ServletContext application = this.getServletContext();
		//将请求向下传递
		application.getRequestDispatcher("/servlet/demo6").forward(request, response);

Response和Request

response是服务器给客户端的响应对象,request是客户端给服务器的请求对象。

请求和响应消息分为三种:消息头、消息行、消息正文。

HttpServletResponse继承自ServletResponse

设置响应消息头:

//告诉服务器应用使用UTF-8解析文本
response.setCharacterEncoding("UTF-8");
//告诉客户端要使用什么编码
response.setHeader("content-type", "text/html;charset=UTF-8");

setCharacterEncoding(String)这个方法来自于ServletResponse接口。

setHeader(String name,String value)这个方法来自于HttpServletResponse类。可以用于设置消息头

//告诉服务器应用使用UTF-8解析文本,告诉客户端要使用什么编码
response.setContentType("text/html; charset=UTF-8");

下面是一个下载图片的demo:

package com.itheima.servlet;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;

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

public class ServletDemo3 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//通过路径得到一个输入流
		String path = this.getServletContext().getRealPath("/WEB-INF/classes/美女.jpg");
		FileInputStream fis = new FileInputStream(path);
		//创建字节输出流
		ServletOutputStream sos = response.getOutputStream();
		
		//得到要下载的文件名
		String filename = path.substring(path.lastIndexOf("\\")+1);//字符串切割。从最后一个“/”+1的位置作为开始分割到完
		
		//设置文件名的编码
		filename = URLEncoder.encode(filename, "UTF-8");//将不安全的文件名改为UTF-8格式
		
		//设置相应消息头,告知客户端要下载的文件名,文件类型
		response.setHeader("content-disposition", "attachment;filename="+filename);
		response.setHeader("content-type", "image/jpeg");
		
		//执行输出操作
		int len = 1;
		byte[] b = new byte[1024];
		while((len=fis.read(b))!=-1){
			sos.write(b,0,len);
		}
		
		sos.close();
		fis.close();
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

下面是一个基于Servlet的验证码demo:

验证码demo

下面是一个刷新跳转的demo的主要部分代码:

		response.getWriter().write("注册成功!3秒钟跳到主页");
		//设置3秒钟跳转
		response.setHeader("refresh", "3;url=/day09_00_HttpServletResponse/servlet/demo6");

url是跳转的另一个Servlet的url。

重定向

HTTPServletResponse类中有一个方法:sendRedirect(String location)可以设置请求重定向。重定向的特点是不会保存表单数据,需要访问两个Servlet,有别于请求转发。参数location是重定向的资源的全路径。执行顺序是先执行完当前Servlet中的内容再进入到重定向的Servlet执行里面的内容。

演示demo:

package com.itheima.servlet;

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 ServletDemo7 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		System.out.println("A:我要借钱!");
		System.out.println("B:我不有,但是我可以告诉你谁有");
		/*//告诉客户端要重新定向新的资源
		response.setStatus(302);
		//告诉浏览器要去访问哪个URL
		response.setHeader("location", "/day09_00_HttpServletResponse/servlet/demo8");*/
		
		//请求重定向
		response.sendRedirect("/day09_00_HttpServletResponse/servlet/demo8");
		
		System.out.println("A: 我去了");
		
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

执行结果:

我有钱,我借你!    这句话是来自转发的servlet的。验证了执行顺序。

HttpServletRequset继承自ServletRequest

response对象大多执行set和add方法,request对象大多执行get类方法,是客户端获取来自服务器端的http协议传输内容的方法。

常用重要get方法:

//		getMethod(); 获得请求方式
//		***getRequestURL();返回客户端发出请求时的完整URL。
//		***getRequestURI(); 返回请求行中的资源名部分。
//		*****getContextPath(); 当前应用的虚拟目录 /day09_01_HttpServletRequest
//		getQueryString() ; 返回请求行中的参数部分。
		
		System.out.println(request.getMethod());//  GET
		System.out.println(request.getRequestURL()); // http://localhost:8080/day09_01_HttpServletRequest/servlet/demo1
		System.out.println(request.getRequestURI()); //   /day09_01_HttpServletRequest/servlet/demo1
		System.out.println(request.getContextPath()); //  /day09_01_HttpServletRequest
		System.out.println(request.getQueryString()); //  username=tom

还有一个重要的是获取消息头:getHeader(String name)      getHeaders(String name)

getHeaders方法返回的是枚举字符串类型,我们需要遍历显示,主要代码如下:

	Enumeration headers = request.getHeaders("accept-language");
		while(headers.hasMoreElements()){
			String e = (String) headers.nextElement();
			System.out.println(e+":"+request.getHeader(e));
		}

Servlet的作用:

1.获取表单数据

2.处理业务逻辑

3.分发转向

Servlet写html页面需要很多的代码,是个体力活,所以下面引入jsp——既可以写静态内容又可以嵌套java代码。但是jsp虽然适合编写输出动态内容,但是不适合编写java逻辑。

猜你喜欢

转载自blog.csdn.net/weixin_38930706/article/details/81282434
今日推荐