Dev_Nick

导航

servlet编程

Servlet(Server Applet),全称Java Servlet,暂无中文译文。是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。
 
servlet部署步骤
(1)编写java类,并继承HttpServlet类。
(2)重写doGet和doPost方法。
(3)servlet类交给tomcat运行。
  (1) servlet程序的class码拷贝到WEB-INF/classes目录,一般这个过程有IDE自动完成。
  (2)在web.xml文件中进行配置<servlet></servlet>和<servlet-mapping></servlet-mapping>。
配置示例如下:
 1 <!-- 配置一个servlet -->
 2   <!-- servlet的配置 -->
 3   <servlet>
 4       <!-- servlet的内部名称,自定义。尽量有意义 -->
 5       <servlet-name>FirstServlet</servlet-name>
 6       <!-- servlet的类全名: 包名+简单类名 -->
 7       <servlet-class>com.nick.FirstServlet</servlet-class>
 8   </servlet>
 9   
10   
11   <!-- servlet的映射配置 -->
12   <servlet-mapping>
13       <!-- servlet的内部名称,一定要和上面的内部名称保持一致!! -->
14       <servlet-name>FirstServlet</servlet-name>
15       <!-- servlet的映射路径(访问servlet的名称) -->
16       <url-pattern>/first</url-pattern>
17   </servlet-mapping>

tomcat启动时,首先加载webapps中的每个web应用的web.xml配置文件,并根据web.xml配置文件中的信息来完成对应servlet类对象的创建。

创建流程如下:

(1)tomcat在web.xml中查找是否存在与请求URL匹配的url-pattern的内容

(2)如果存在,就去servlet标签下查找具有相同servlet-name的servlet-class标签,并通过反射机制来完成servlet类的创建。如果不存在就去加载tomcat中的defaultServlet类,defaultServelt会在应用的根目录下查找是否存在index.html的静态文件,如果存在就读取文件内容返回给浏览器。如果不存在则返回404错误页面。

servlet的映射路径--<url-pattern>映射路径</url-pattern>

映射路径分类两种类型:精确匹配和模糊匹配。

精确匹配:如

  /first: http://localhost:8080/FirstServlet/first

  /first/demo :http://localhost:8080/FirstServlet/first/demo

模糊匹配:如

  /*:http://localhost:8080/FirstServlet/任意路径

  /first/*:http://localhost:8080/FirstServlet/first/任意路径

  *.后缀名:http://localhost:8080/day10/任意路径.后缀名

注意事项:

  1)url-pattern要么以 / 开头,要么以*开头。

  2)不能同时使用两种模糊匹配,例如 /first/*.do是非法路径

  3)当有输入的URL有多个servlet同时被匹配的情况下:

    3.1 精确匹配优先。(长的最像优先被匹配)

    3.2 以后缀名结尾的模糊url-pattern优先级最低!!!

servlet的缺省路径:

  servlet的缺省路径(<url-pattern>/</url-pattern>)是在tomcat服务器内置的一个路径。该路径对应的是一个DefaultServlet(缺省Servlet)。这个缺省的Servlet的作用是用于解析web应用的静态资源文件。

servlet类的声明周期

(1)四个生命周期函数

  构造方法: 创建servlet对象的时候调用。默认情况下,第一次访问servlet的时候创建servlet对象只调用1次。servlet对象在tomcat是单实例的。

      init方法: 创建完servlet对象的时候调用。只调用1次。--public void init(ServletConfig config);

      service方法: 每次发出请求时调用。调用n次。--public void service(ServletRequest req, ServletResponse res);

      destroy方法: 销毁servlet对象的时候调用。停止服务器或者重新部署web应用时销毁servlet对象。只调用1次。--public void destroy();

(2)应用的生命周期时序图

servlet自动加载

默认情况下,第一次访问servlet的时候创建servlet对象。如果servlet的构造方法或init方法中执行了比较多的逻辑代码,那么导致用户第一次访问sevrlet的时候比较慢。通过在servlet的web.xml配置信息中,加上一个<load-on-startup>1</load-on-startup>来改变servlet对象在web应用加载的时候就进行创建。

配置示例如下:

<servlet>
    <servlet-name>LifeDemo</servlet-name>
    <servlet-class>com.nick.LifeDemo</servlet-class>
    <!-- 让servlet对象自动加载 -->
    <load-on-startup>1</load-on-startup>  注意: 整数值越大,创建优先级越低!!
  </servlet>

注意:在启动servlet的时候进行的逻辑处理应该重写无参的init方法中写,而不用有参的init方法。

servlet线程安全问题

servlet对象在tomcat服务器是单实例多线程的。当多个线程同时访问共享资源的时候,如成员变量等就汇引发线程安全问题。

解决办法:

  1)把使用到共享数据的代码块进行同步(使用synchronized关键字进行同步)。

      2)建议在servlet类中尽量不要使用成员变量。如果确实要使用成员,必须同步。而且尽量缩小同步代码块的范围。(哪里使用到了成员变量,就同步哪里!!),以避免因为同步而导致并发效率降低。

servlet中的对象

(1)HttpServletRequest

(2)HttpServletResponse

(3)ServletConfig

(4)ServletContext

其中HttpServletRequest和HttpServletResponse对象的使用在上一篇博客有介绍,下面主要来看一下ServletConfig和ServletContext对象。

ServletConfig对象

作用:主要是用于加载servlet的初始化参数。在一个web应用可以存在多个ServletConfig对象(一个Servlet对应一个ServletConfig对象)。

web应用servlet初始化参数的配置方式:在web.xml中对应的<servlet></servlet>标签下添加初始化参数,配置示例如下:

1  <servlet>
2     <servlet-name>ConfigDemo</servlet-name>
3     <servlet-class>com.nick.ConfigDemo</servlet-class>
4     <!-- 初始参数: 这些参数会在加载web应用的时候,封装到ServletConfig对象中 -->
5     <init-param>
6         <param-name>path</param-name>
7         <param-value>e:/b.txt</param-value>
8     </init-param>
9   </servlet>

获取servletConfig的API:

  ServletConfig getServletConfig()

servletConfig常用API:

  java.lang.String getInitParameter(java.lang.String name)  根据参数名获取参数值

  java.util.Enumeration getInitParameterNames()    获取所有参数

  ServletContext getServletContext()     得到servlet上下文对象

  java.lang.String getServletName()       得到servlet的名称

servletContext对象

ServletContext对象 ,叫做Servlet的上下文对象。表示一个当前的web应用环境。一个web应用中只有一个ServletContext对象。

servletContext对象的核心API:

  java.lang.String getContextPath()   --得到当前web应用的路径

  java.lang.String getInitParameter(java.lang.String name)  --得到web应用的初始化参数

  java.util.Enumeration getInitParameterNames() 

  void setAttribute(java.lang.String name, java.lang.Object object) --域对象有关的方法

  java.lang.Object getAttribute(java.lang.String name) 

  void removeAttribute(java.lang.String name)

  RequestDispatcher getRequestDispatcher(java.lang.String path)   --转发(类似于重定向)

  java.lang.String getRealPath(java.lang.String path)     --得到web应用的资源文件

  java.io.InputStream getResourceAsStream(java.lang.String path)

(1) 获取web应用路径(其实就是项目的名称)--常用于重定位时,代码如下:

 1 public void doGet(HttpServletRequest request, HttpServletResponse response)
 2             throws ServletException, IOException {
 3         //1.得到ServletContext对象
 4         ServletContext context = this.getServletContext(); //(推荐使用)
 5         
 6         
 7         //2.得到web应用路径  /day10
 8         /**
 9          * web应用路径:部署到tomcat服务器上运行的web应用名称
10          */
11         String contextPath = context.getContextPath();
12         System.out.println(contextPath);
13         
14         /**
15          * 案例:应用到请求重定向
16          */
17         response.sendRedirect(contextPath+"/index.html");
18     }
View Code

(2) 得到web应用的初始化参数

在web.xml中配置web应用参数代码如下:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app version="2.5" 
 3     xmlns="http://java.sun.com/xml/ns/javaee" 
 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
 6     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 7     
 8     <!-- 配置web应用参数 -->
 9     <context-param>
10         <param-name>AAA</param-name>
11         <param-value>AAA's value</param-value>
12     </context-param>
13     <context-param>
14         <param-name>BBB</param-name>
15         <param-value>BBB's value</param-value>
16     </context-param>
17     <context-param>
18         <param-name>CCC</param-name>
19         <param-value>CCC's value</param-value>
20     </context-param>
21 
22 </web-app>

注意:

  (1)web应用参数可以让当前web应用的所有servlet获取。

   (2)  web应用的参数放在<web-app>标签的第一层,每个<context-param></context-param>就是一个web应用的参数。

获取web应用的代码示例如下:

 1 public void doGet(HttpServletRequest request, HttpServletResponse response)
 2             throws ServletException, IOException {
 3         //得到SErvletContext对象
 4         ServletContext context = this.getServletContext();
 5         
 6         System.out.println("参数"+context.getInitParameter("AAA"));
 7         
 8         Enumeration<String> enums = context.getInitParameterNames();
 9         while(enums.hasMoreElements()){
10             String paramName = enums.nextElement();
11             String paramValue  =context.getInitParameter(paramName);
12             System.out.println(paramName+"="+paramValue);
13         }
14     }
View Code

(3) 域对象

域对象的作用:用于保存数据,获取数据。可以在不同的动态资源之间共享数据。

常见的域对象:

  HttpServletRequet 域对象

      ServletContext域对象

      HttpSession 域对象

     PageContext域对象

ServletContext作为域对象的使用代码示例如下:

保存对象的java类:

 1 class Student{
 2     private String name;
 3     private int age;
 4     public String getName() {
 5         return name;
 6     }
 7     public void setName(String name) {
 8         this.name = name;
 9     }
10     public int getAge() {
11         return age;
12     }
13     public void setAge(int age) {
14         this.age = age;
15     }
16     public Student(String name, int age) {
17         super();
18         this.name = name;
19         this.age = age;
20     }
21     @Override
22     public String toString() {
23         return "Student [age=" + age + ", name=" + name + "]";
24     }
25     
26 }
View Code

ServletContext作为域对象保存数据

 1 public void doGet(HttpServletRequest request, HttpServletResponse response)
 2             throws ServletException, IOException {
 3         //1.得到域对象
 4         ServletContext context = this.getServletContext();
 5         
 6         //2.把数据保存到域对象中
 7         //context.setAttribute("name", "eric");--普通字符串保存
 8         context.setAttribute("student", new Student("jacky",20));
 9         System.out.println("保存成功");
10     }
View Code

ServletContext作为域对象获取数据

1 public void doGet(HttpServletRequest request, HttpServletResponse response)
2             throws ServletException, IOException {
3         //1.得到域对象
4         ServletContext context = this.getServletContext();
5         
6         //2.从域对象中取出数据
7         Student student = (Student)context.getAttribute("student");
8         System.out.println(student);
9     }
View Code

注意:ServletContext域对象的作用于为整个web工程。

(4) 转发

一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理,称之为请求转发。

一个web资源收到客户端请求后,通知浏览器去访问另外一个web资源,称之为请求重定向。

转发的代码示例如下:

1 public void doGet(HttpServletRequest request, HttpServletResponse response)
2             throws ServletException, IOException {
3             this.getServletContext().getRequestDispatcher("/GetDateServlet").forward(request, response);
4     }
View Code

转发和重定向的区别:

1)转发

  a)地址栏不会改变。

  b)转发只能转发到当前web应用内的资源。

  c)可以在转发过程中,可以把数据保存到request域对象中。

2)重定向                             

     a)地址栏会改变,变成重定向到地址。

     b)重定向可以跳转到当前web应用,或其他web应用,甚至是外部域名网站。

     c)不能在重定向的过程,把数据保存到request中。

(5) 得到web应用中的资源文件

web应用中用到路径先写上/。

web应用中常用的路径符号:
/:在不同的使用环境下代表不同的含义
  给服务器使用:表示在当前的web应用的根目录(webRoot或者webContent下)。
  给浏览器使用:表示在webapps的根目录下。
区别代码如下:
 1 public void doGet(HttpServletRequest request, HttpServletResponse response)
 2             throws ServletException, IOException {
 3         response.setContentType("text/html;charset=utf-8");
 4         //目标资源: target.html
 5         /**
 6          * 1.转发
 7          */
 8         //request.getRequestDispatcher("/target.html").forward(request, response);
 9         
10         
11         /**
12          * 2.请求重定向
13          */
14         //response.sendRedirect("/day11/target.html");
15         
16         /**
17          * 3.html页面的超连接href
18          */
19         response.getWriter().write("<html><body><a href='/day11/target.html'>超链接</a></body></html>");
20         
21         /**
22          * 4.html页面中的form提交地址
23          */
24         response.getWriter().write("<html><body><form action='/day11/target.html'><input type='submit'/></form></body></html>");
25     }
View Code

.:代表java命令行目录,即tomcat/bin目录。

使用ServletContext加载资源文件的方法示例如下:

 1 public void doGet(HttpServletRequest request, HttpServletResponse response)
 2             throws ServletException, IOException {
 3         
 4         //读取文件。在web项目下不要这样读取。因为.表示在tomcat/bin目录下
 5         /*File file = new File("./src/db.properties");
 6         FileInputStream in = new FileInputStream(file);*/
 7         
 8         /**
 9          * 使用web应用下加载资源文件的方法
10          */
11         /**
12          * 1. getRealPath读取,返回资源文件的绝对路径
13          */
14         /*String path = this.getServletContext().getRealPath("/WEB-INF/classes/db.properties");
15         System.out.println(path);
16         File file = new File(path);
17         FileInputStream in = new FileInputStream(file);*/
18         
19         /**
20          * 2. getResourceAsStream() 得到资源文件,返回的是输入流
21          */
22         InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
23         
24         
25         Properties prop = new Properties();
26         //读取资源文件
27         prop.load(in);
28         
29         String user = prop.getProperty("user");
30         String password = prop.getProperty("password");
31         System.out.println("user="+user);
32         System.out.println("password="+password);
33         
34     }
View Code

 

 

 

 

 

 

posted on 2017-03-07 16:24  Dev_Nick  阅读(242)  评论(0编辑  收藏  举报