一、JavaWeb学习笔记之 Servlet (一)

[TOC]

Servlet

用户在浏览器中输入一个网址并回车,浏览器会向服务器发送一个HTTP请求,服务器端接收并且处理改请求,然后向浏览器发送响应,浏览器接收响应,在将服务器端响应的内容显示出来,这种请求-响应模式就是典型的Web应用程序访问过程。在JavaWeb应用程序中,处理请求和响应的过程就是由Servlet程序来完成的。

1. Servlet 概述

JavaWeb应用程序中所有的请求-响应都是由Servlet来完成的。Servlet没有main方法,当用户访问服务器时,服务器通过调用Servlet的某些方法来完成整个的处理过程。

1.1 Servlet 工作流程

浏览器提交的请求是遵循HTTP协议的,提交的请求通过服务器(Tomcat)接收解析,并且封装成为HttpServletRequest类型的reqeust对象,所有的HTTP头数据都可以通过request的相应方法查询到。

服务器(Tomcat)同时把输出流封装为HttpServletResponse类型的response对象,通过设置response属性,就可以控制输出的内容。服务器(Tomcat)把request和response作为参数,调用Servlet的相应方法,如doGet或者doPost方法。

1.2 Servlet 接口

Servlet 实现了javax.servlet.Servlet接口的类,Servlet接口规定了特定的方法来处理特定的请求,我们只需要实现Servlet的相关方法,用户访问Web应用程序的时候,服务器(Tomcat)会自动调用这些方法来完成业务处理。Servlet业务处理主要方法有一下两种:

  1. Get方法:表示查询信息,URL中可以附带少量的参数信息,但是URL的总长度不能超过255个字符,并且参数会显示在浏览器的地址栏中。
  2. Post方法:表示提交信息,一般用于调教大数据信息或者文件,提交的内容不受长度限制,并且不会显示在浏览器地址栏。

1.3 实现 Servlet

package com.servlet.demo;

import java.io.IOException;

import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

public class ServletDemo implements Servlet {

    private ServletConfig config;

    public void destroy() {
        System.out.println("执行destory()方法...");
    }

    public ServletConfig getServletConfig() {
        return this.config;
    }

    public String getServletInfo() {
        return this.config.getServletName();
    }

    public void init(ServletConfig config) throws ServletException {
        System.out.println("执行init()方法...");
        this.config = config;
    }

    public void service(ServletRequest request, ServletResponse response) 
            throws ServletException, IOException {
        System.out.println("执行Service()方法...");
    }
}

1.4 配置 Servlet

在JavaWeb应用程序中,Web容器还必须知道浏览器怎么访问这个Servlet。所以我们要配置Servlet的类文件与访问方式。这个配置在Web应用程序的描述文件web.xml文件中。



    servlet
    
        index.html
    
    
    
    
        ServletDemo
        com.servlet.demo.ServletDemo
         
        0
    
    
    
        ServletDemo
        /demo
    

1.4.1 配置 servlet 标签

分别为Servlet配置的开始与结束标签。中间部分为Servlet的配置信息,其中 属性是必须配置的。

  1. :配置servlet名称,可以为任意字符串,但是保证该名称在web.xml文件中唯一,该名称供等使用;
  2. :Servlet类所在包及类名;
1. 在容器启动时实例化 Servlet

:配置Servlet的加载模式,可选0和1,如果配置1,服务器会在启动时自动加载该Servlet;

2. 设置Servlet初始化参数

:可以在servlet中配置初始化参数,包括一个参数名称和参数值,servlet可以通过其ServletConfig对象的getInitParam(String paramName)方法来获取初始化参数值;

  • :配置初始化参数名称;
  • :配置初始化参数值;

1.4.2 配置 servlet-mapping标签

  1. :配置指明采用该访问方式Servlet的名称,与标签中的须一致;
  2. :配置该servlet的访问方式,该标签前面加上Web应用程序的路径,再加上服务器域名端口号信息就是访问该servlet的网址。
image

1.5 Servlet生命周期和生命周期方法

Servlet 生命周期可被定义为从创建直到毁灭的整个过程。以下是 Servlet 遵循的过程:

  • Servlet 通过调用 init () 方法进行初始化;
  • Servlet 调用 service() 方法来处理客户端的请求;
  • Servlet 通过调用 destroy() 方法终止(结束);

以上的init()service()destory() 三个方法属于Servlet的生命周期方法。

  1. init():被设计成只调用一次。它在第一次创建 Servlet 时被调用,在后续每次用户请求时不再调用。
  2. service(): 执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端的请求,并把格式化的响应写回给客户端。每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。
  3. destory():只会被调用一次,在 Servlet 生命周期结束时被调用。

2. 通过继承 HttpServlet 编写 Servlet

直接实现Servlet接口来编写Servlet不方便,需要实现的方法太多。javax.servlet.http.HttpServlet类实现了Servlet接口所有方法,通过继承HttpServlet编写Servlet,一般只需要覆盖doGet()和doPost()方法即可。

package com.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

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

public class FirstServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.log("执行 doGet 方法...");
        this.execute(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.log("执行 doPost 方法...");
        this.execute(request, response);
    }
    
    public long getLastModified(HttpServletRequest request) {
        this.log("执行 getLastModified 方法...");
        return -1;
    }

    private void execute(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setCharacterEncoding("utf-8");
        request.setCharacterEncoding("utf-8");
        //获取访问该 Servlet 的 URI
        String requestURI = request.getRequestURI();
        // 获取访问 Servlet 的方式
        String method = request.getMethod();
        
        String param = request.getParameter("param");
        
        response.setContentType("text/html");
        
        PrintWriter out = response.getWriter();
        
        out.println("");
        out.println("");
        out.println("");
        out.println("First Servlet");
        out.println("");
        out.println("");
        
        out.println("以 " + method +" 方式访问该页面,取得的 param 参数为:" + param+"。");
        out.println("
"); out.println("
"); out.println(""); out.println(""); out.println("
"); out.println("
"); out.println(""); out.println(""); out.println("
"); out.println(""); out.println(""); out.println(""); out.flush(); out.close(); } }



servlet

    index.html
    index.htm
    index.jsp
    default.html
    default.htm
    default.jsp



    FirstServlet
    com.servlet.FirstServlet



    FirstServlet
    /first


3. 请求和响应

客户端浏览器发送给一个请求,服务器接收并处理请求,最后向客户端浏览器发送响应,结束一次Web访问过程。

3.1 获取 request 的变量

客户端浏览器发出的请求被封装成为HttpServletRequest类型对象,所有的信息包括请求地址、请求参数、提交的数据、上传的文件,客户端的IP地址,甚至是客户操作系统都包含在HttpServletRequest类型的对象中。

package com.servlet;

import java.io.IOException;
import java.io.PrintWriter;

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

public class RequestServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html");
        
        PrintWriter out = response.getWriter();
        
        // 获取 user-agent 请求头        
        String userAgent = request.getHeader("user-agent");
        
        String os = getOS(userAgent);
        String navigator = getNavigator(userAgent);
        
        out.println("你使用的操作系统是: "+ os +" 系统");
        out.println("
"); out.println("你使用的浏览器是: "+ navigator +" 浏览器"); out.flush(); out.close(); } private static String getOS(String userAgent) { if (userAgent.indexOf("Ubuntu") > 0) { return "Ubuntu"; } return "未知"; } private static String getNavigator(String userAgent) { if (userAgent.indexOf("Firefox") > 0) { return "Mozllia Firefox"; } return "未知"; } }

RequestServlet配置:


    RequestServlet
    com.servlet.request.RequestServlet


    RequestServlet
    /request

3.2 使用 response 生成图片验证码

package com.servlet.response;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

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

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

public class IdentityServlet extends HttpServlet {

    public static final char[] CHARS = { '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
            'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };

    // 获取随机数
    public static Random random = new Random();

    // 随机获取6位验证码
    public StringBuffer getIdentityCode() {

        // 创建缓存字符串
        StringBuffer buffer = new StringBuffer();

        for (int i = 0; i < 6; i++) {
            buffer.append(CHARS[random.nextInt(CHARS.length)]);
        }

        return buffer;
    }

    public static Color getRandomColor() {
        return new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
    }

    public static Color getReverseColor(Color c) {
        return new Color(255 - c.getRed(), 255 - c.getGreen(), 255 - c.getBlue());
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("image/jpeg");

        String identityCode = getIdentityCode().toString();
        request.getSession(true).setAttribute("identityCode", identityCode);
        // 设置验证码图片的高度和宽度
        int width = 100;
        int height = 30;

        Color backColor = getRandomColor();
        Color frontColor = getReverseColor(backColor);

        BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        Graphics2D g = bi.createGraphics();
        g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 16));

        g.setColor(backColor);
        g.fillRect(0, 0, width, height);

        g.setColor(frontColor);
        g.drawString(identityCode, 18, 20);

        for (int i = 0; i < random.nextInt(100); i++) {
            g.drawRect(random.nextInt(width), random.nextInt(height), 1, 1);
        }

        ServletOutputStream out = response.getOutputStream();
        JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);

        encoder.encode(bi);
        out.flush();

    }

}

IdentityServlet配置信息:


    identity
    com.servlet.response.IdentityServlet


    identity
    /identity

4. 读取 web.xml 参数

在JavaWeb开发中,源码上微小的变动就需要重新编译class文件,然后重新部署,会带来大量的工作。现在,可以将一些常亮信息存放于配置文件中。当程序需求发生变化,只需修改配置文件即可。web.xml提供了设置初始化参数的功能,可以将这些信息配置在web.xml文件中。

4.1 初始化参数(init-param)

web.xml配置servlet时, 标签可以包含多个 来配置多个初始化参数。servlet中提供了如下的方法来操作来获取初始化参数的名称和值:

  1. String getInitParameter(String parameterName) : 获取指定初始化参数的值;
  2. Enumeration getInitParameterNames() : 获取所有初始化参数名称;

web.xml配置信息如下:



    InitParamServlet
    com.servlet.initParam.InitParamServlet
    
    
        admin
        martin0319
    
    
        adminPassword
        319517
    


    InitParamServlet
    /param

InitParamServlet

package com.servlet.initParam;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class InitParamServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {

        response.setCharacterEncoding("utf-8");
        request.setCharacterEncoding("utf-8");

        response.setContentType("text/html");

        PrintWriter out = response.getWriter();

        String requestURI = request.getRequestURI();

        out.println("");
        out.println("");
        out.println("");
        out.println("Test Init-Param");
        out.println("");
        out.println("");
        out.println("
"); out.println("账号:" + "
" + "密码:" + "
" + ""); out.println("
"); out.println(""); out.println(""); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("utf-8"); request.setCharacterEncoding("utf-8"); response.setContentType("text/html"); PrintWriter out = response.getWriter(); // 获取由表达提交的数据 String username = request.getParameter("loginName"); String password = request.getParameter("loginPassword"); /* * 获取web.xml中配置参数 * 1、获取ServletConfig对象 * 2、获取所有初始化参数名称 * 3、通过初始化参数名称获取初始化参数值 */ ServletConfig config = this.getServletConfig(); String initName = config.getInitParameter("admin"); String initPassword = config.getInitParameter("adminPassword"); if (username.equalsIgnoreCase(initName) && password.equalsIgnoreCase(initPassword)) { out.println("欢迎登陆..."); } else { out.println("用户名或密码错误..."); } } }

4.2 上下文参数(context-param)

由于 init-param 是配置在标签中的,只能由这个servlet类调用,不能被其他的servlet调用,不是全局参数。如果需要配置全局参数,需要用到上下文参数(文档参数),上下文参数使用标签配置。

上下文参数可以使用ServletConfig对象来获取。Servlet中通过getServletConfig().getServletContext()方法来获取一个ServletContext对象。

  1. String getInitParameter(String parameterName): 获取指定上下文参数的值;
  2. Enumeration getInitParameterNames() : 获取所有上下文参数名称;

ContextParamServlet配置信息:


    upload folder
    attachment


    allowed file type
    .jpg, .gif, .bmp



    ContextParamServlet
    com.contextParam.ContextParamServlet


    ContextParamServlet
    /context

ContextParamServlet类:

package com.contextParam;

import java.io.IOException;
import java.io.PrintWriter;

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

public class ContextParamServlet extends HttpServlet {
    
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        response.setCharacterEncoding("utf-8");
        request.setCharacterEncoding("utf-8");
        
        response.setContentType("text/html");
        
        PrintWriter out = response.getWriter();
        //  获取ServletContext对象
        ServletContext context = this.getServletConfig().getServletContext();
        //  获取上下文参数
        String uploadFolder = context.getInitParameter("upload folder");
        String allowFileType = context.getInitParameter("allowed file type");
        //  获取实际磁盘路径
        String realPath = context.getRealPath(uploadFolder);
        
        out.println("");
        out.println("");
        out.println("");
        out.println("读取上下文参数");
        out.println("");
        out.println("");
        
        out.println("");
        out.println("");
        out.println("");
        out.println("");
        out.println("");
        
        out.println("");
        out.println("");
        out.println("");
        out.println("");
        
        out.println("");
        out.println("");
        out.println("");
        out.println("");
        out.println("
上传文件夹:" + uploadFolder + "
实际磁盘路径:" + realPath + "
允许上传类型:" + allowFileType + "
"); out.println(""); out.println(""); out.flush(); out.close(); } }

你可能感兴趣的:(一、JavaWeb学习笔记之 Servlet (一))