Servlet

Posted 李小未

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Servlet相关的知识,希望对你有一定的参考价值。

 

servlet 是运行在 Web 服务器中的小型 Java 程序(即:服务器端的小应用程序)servlet 通常通过 HTTP(超文本传输协议)接收和响应来自 Web 客户端的请求。

先写一个java 类,实现Servlet 接口

下面配置下web.xml

访问地址:

http://locahost:8080/day08_servlet/demo1

Servlet 的生命周期

实例化-->初始化-->服务->销毁

出生:(实例化-->初始化)第一次访问Servlet就出生(默认情况下)

活着:(服务)应用活着,servlet就活着

死亡:(销毁)应用卸载了servlet就销毁。

 

 

 init第一次访问的时候被调用,service 多次被调用

小知识:让servlet在服务器启动的时候就被调用

 

 

 

servlet 创建的三种方式

1.

实现javax.servlet.Servlet接口(参见:编写一个servlet程序:)

2.

继承javax.servet.GenericServlet(适配器模式)

 例子:

public class ServletDemo2 extends GenericServlet{

@Override
public void service(ServletRequest arg0, ServletResponse arg1)
throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("servletDemo2");
}

}

 3.

继承javax.servlet.http.HttpServlet类(模板方法设计模式)开发中常用的方式

public class ServletDemo4 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("************ServletDemo4************");
}

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

 

它们之间的关系:

Servlet --> GenericServlet --> HttpServlet  (继承HttpServlet)

 

Servlet的线程安全

 

单实例:每次访问多线程

 

解决线程安全问题的最佳办法,不要写全局变量,而写局部变量。

当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息。

这样做的好处是:如果将数据库信息、编码方式等配置信息放在web.xml中,如果以后数据库的用户名、密码改变了,则直接很方便地修改web.xml就行了,避免了直接修改源代码的麻烦

主要方法:

  • String getServletName()  -- 获取当前Servlet在web.xml中配置的名字
  • String getInitParameter(String name) -- 获取当前Servlet指定名称的初始化参数的值
  • Enumeration getInitParameterNames()  -- 获取当前Servlet所有初始化参数的名字组成的枚举
  • ServletContext getServletContext()  -- 获取代表当前web应用的ServletContext对象

 

 在Web.xml中配置信息

<servlet>
<servlet-name>ServletConfigDemo1</servlet-name>
<servlet-class>com.itcast.servletConfig.ServletConfigDemo1</servlet-class>
<init-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</init-param>
</servlet>

有三种方式获取:

第一

private ServletConfig config;

public void init(ServletConfig config) throws ServletException {
this.config = config;
}

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String encoding = config.getInitParameter("encoding");//获得配置文件中的信息的
System.out.println(encoding);
}

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

第二种方式

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String encoding = this.getServletConfig().getInitParameter("encoding");
System.out.println(encoding);
}

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

第三种方式

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String encoding = super.getInitParameter("encoding");
System.out.println(encoding);
}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {
doGet(request, response);
}

 

 

 

 

二、ServletContext:代表当前web应用(非常重要

WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用

ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象。

由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象

ServletContext的应用:

1.做为域对象可以在整个web应用范围内共享数据。

这里涉及到一些概念:

  • 域对象:在一个可以被看见的范围内共享数据用到对象
  • 作用范围:整个web应用范围内共享数据
  • 生命周期:当服务器启动web应用加载后创建出ServletContext对象后,域产生。当web应用被移除出容器或服务器关闭,随着web应用的销毁域销毁。

常用方法:

void setAttribute(String name,object value);//ServletContext对象的map中添加数据

Object getAttribute(String name);//ServletContext对象的map中取数据

void rmoveAttribute(String name);//根据name去移除数

 

 

 

 举例: servletDemo1

public class ServletDemo1 extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//通过调用GenericServlet的getServletContext方法得到ServletContext对象
ServletContext application = this.getServletContext();
//向ServletContext添加一个键值对
application.setAttribute("name", "tom");
System.out.println(application.getClass().getName());

}

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

}

 

 

 

 

ServletDemo2

public class ServletDemo2 extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String name = (String) this.getServletContext().getAttribute("name");
if(name==null){
System.out.println("你不能直接访问这个类");
}
System.out.println(name);
}

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

}

我们在ServletDemo1中给Context加一个参数name,然后就能在ServletDemo2中得到这个参数了

 

 

代码部分:

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

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String encoding = this.getServletContext().getInitParameter("encoding");
System.out.println(encoding);
}

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

获取多个配置

<!-- 配置当前应用的全局信息 -->
<context-param>
<param-name>username</param-name>
<param-value>lily</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>123</param-value>

public class ServletDemo7 extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
ServletContext s = this.getServletContext();
Enumeration e = s.getInitParameterNames();
while (e.hasMoreElements()) {
String name = (String) e.nextElement();
String value = s.getInitParameter(name);
System.out.println(name + " " + value);
}
}

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

}

结果:

username lily
password 123

获取资源路径: 

创建配置文件a.properties 中key=abc

String  getRealPath(String path);//根据资源名称得到资源的绝对路径.

 

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

private void test1() throws IOException, FileNotFoundException {
String path = this.getServletContext().getRealPath("a.properties");//参数一定要以/开头
//创建一个Properties
Properties pro = new Properties();
pro.load(new FileInputStream(path));
System.out.println(pro.getProperty("key"));
}

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

结果为:abc

 

三、实现Servlet的转发

这里涉及到一些概念要区分:

  • 请求重定向:302+Location(两次请求两次响应)
  • 请求转发:服务器内不进行资源流转 (一次请求一次响应,来实现资源流转)

注:上方括号中的内容是二者的区别。打个比方,假如你找我借钱,如果是请求重定向的话,那你再去找别人借;如果是请求转发的话,那我去找别人借,然后再借给你。

例子;ServletDemo5 请求转发

public class ServletDemo5 extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("我要办事");
System.out.println("你的事我办不了,我可以帮你找人办");
ServletContext application = this.getServletContext();
RequestDispatcher rd = application.getRequestDispatcher("/servlet/demo6");
rd.forward(request, response);
System.out.println("事办完了");
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}

}

ServletDemo6接收

public class ServletDemo6 extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
System.out.println("这个事我能办!。。。。");
}

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

 

以上是关于Servlet的主要内容,如果未能解决你的问题,请参考以下文章

ServletServlet 详解(使用+原理)

ServletServlet容器等内容讲解

web.xml servletservlet-mapping配置

ServletServlet学习之基础篇

ServletServlet学习之基础篇

ServletServlet学习之基础篇