servlet

Servlet

一.Servlet接口定义了五个方法

1.void init(ServletConfig config) throws ServletException

当Servlet第一次被请求时,Servlet容器会调用这个方法,之后不会再调用

2. void service(ServletRequest request, ServletResponse response) throws ServletException, java.io.IOException

 除了第一次被请求时同时调用init()和dervice两个方法外,其余每次请求都只是调用service方法

3. void destroy()  

销毁servlet对象时调用

4. java.lang.String getServletInfo()

返回servlet描述

5. ServletConfig getServletConfig()

返回由Servlet容器传给init方法的ServletConfig

package app;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;

/*WebServlet 用来声明一个Servlet,命名servlet时,还可以暗示容器,
 * usrlPatterns 告诉容器,/my样式表示应该调用Servlet
 */
@WebServlet( name = "Myservlet", urlPatterns = {"/my"})
public class MyServlet implements Servlet 
{
    //transient变量不能被序列化
    private transient  ServletConfig servletConfig;

    //init方法只会调用一次,并接受servletConfig
    @Override
    public void init(ServletConfig servletConfig) throws ServletException{
        this.servletConfig = servletConfig;
    }
    @Override 
    public ServletConfig getServletConfig(){
        return servletConfig;
    }
    @Override
    public String getServletInfo(){
        return "My Servlet";
    }
    
    /*Service 发送字符串"hello from MyServlet"给浏览器 
    *对于每个http请求,Servlet容器都会创建一个ServletRequest实例,并将它传给Servlet的Service方法
    *
    */
    @Override
    public void service(ServletRequest request,ServletResponse response)
                            throws ServletException,IOException{
        String servletName = servletConfig.getServletName();
        response.setContentType("text/html"); //在发送任何HTML标签前,应该先调用setContentType()方法,设置响应的内容类型
        PrintWriter writer = response.getWriter();  //返回一个可以向客户端发送文本的printWriter
        String id = request.getParameter("id");//返回指定请求参数的值
        writer.print("<html><head></head>"
                + "<body>Hello from " + servletName + " id = " + id
                + "</body></html>"); //发送数据
    }

    @Override
    public void destroy(){
        
    }
    public static void main(String[] args){
        
    }
    
}

二.ServletRequest接口有一些方法

public int getContentLength() /返回请求主体的字节数,如果不知道字节长度,返回-1
public  java.lang.String getContentType() //返回请求主体的MIME类型,如果不知道类型返回null
public java.lang.String getParameter(java.lang.String name) //返回指定请求参数的值
public java.lang.String getProtocol() //返回这个HTTP请求协议名称和版本

public java.lang.String getParameter(java.lang.String name) 用法

  • String id = request.getParameter("id");
            writer.print("<html><head></head>"
                    + "<body>Hello from " + servletName + " id = " + id
                    + "</body></html>");

三.servletResponse

java.servlet.ServletResponse 接口表示一个Servlet响应,哎调用Servlet的service方法前,Servlet容器先创建一个ServletResponse,并将它作为第二个参数传给Service方法,ServletResponse隐藏了向浏览器发送响应的复杂过程

ServletResponse接口的方法

public java.io.PrintWriter getWriter() //返回一个可以向客户端发送文本的printWriter, 它就是getOutputStream,但这个方法只能发送二进制数据

使用方法

四.ServletConfig

 当Servlet 容器初始化 Servlet 时, Servlet 容器会给 Servlet 的 init 方法传入一个 ServletConfig, ServletConfig封装可以通过@WebServlet或者部署描述符传给Servlet的配置信息这样传入的每一条信息就叫一个初始参数,一个初始参数由key和value两个元件

 为了从Servlet内部获取到初始参数的值,要在Servlet容器传给Servlet的init方法的 ServletConfig中调用getInitParameter方法, getInitParameter的方法签名如下:

java.lang.String getInitParameter(java.lang.String name) //返回所有初始参数名称的一个Enumeration(目录)

java.util.Enumeration<java.lang.String> getInitParameterNames() 

  • Stirng contactName = servletConfig.getInitParameter("contactName"); //返回contactName参数的值

示例

package app;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;

@WebServlet(name = "ServletConfigDemoServlet",
        urlPatterns =  {"/servletConfigDemo"},
        initParams = {         //给Servlet 传入两个参数(admin和email)
                @WebInitParam(name="admin", value="Harry Taciak"), 
                @WebInitParam(name="email", value = "admin@example.com")
})
public class ServletConfigDemoServlet  implements Servlet{
        private transient ServletConfig servletConfig;
        
        @Override
        public void destroy() {
            // TODO Auto-generated method stub
            
        }

        @Override
        public ServletConfig getServletConfig() {
            return servletConfig;
        }

        @Override
        public String getServletInfo() {
            return "ServletConfig Demo1";
        }

        @Override
        public void init(ServletConfig servletConfig) throws ServletException {
            this.servletConfig = servletConfig;  //接受servletConfig
        }

        @Override
        public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
            ServletConfig servletConfig = getServletConfig();// 
            String admin = servletConfig.getInitParameter("admin"); //得到admin的value
            String email = servletConfig.getInitParameter("email"); //的到Email的value
            response.setContentType("text/html");
            PrintWriter writer = response.getWriter();
            writer.print("<html><head></head><body>" +
                    "Admin: " + admin + "<br /> Eamil: " + email +
                    "</body></html>");
        }
        
}

浏览器查看结果

五.ServletContext

ServletContext 表示Servlet 应用程序,每个Web应用程序只有一个上下文, 在将一个应用程序同时部署到多个容器的分布式环境中,每台Java虚拟机上的 Web应用都会由一个ServletContext对象.

通过在ServletConfig 中调用getServletContext方法, 可以获得ServletContext.

有了ServletContext, 就可以共享从应用程序的所有资料处访问到的信息,并且可以动态注册Web对象,前者将对象保存在ServletContext中的一个内部Map中,保存在Servlet中对象被称为属性

ServletContext中的下列方法负责处理属性:

java.lang.Object get.Attribute(java.lang.String name)//attribute(属性)
java.util.Enumeration<java.lang.String> getAttributeNames() //Enumeration(数目)
void setAttribute(java.lang.String name, java.lang.Objetc object);//

六. GenericServlet 抽象类

抽象类GenericServlet 实现了Servlet和ServletConfig接口,并完成了以下任务

  • 将init方法中的ServletConfig赋给了一个类级变量,以便通过调用getServletConfig获取
  • 未Servlet接口中的所有方法提供默认的实现
  • 提供默认方法,包围ServletConfig中的方法
package app;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.GenericServlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebServlet;
import javax.servlet.annotation.WebInitParam;

@WebServlet(name = "GenricServletDemoServlet",
        urlPatterns = { "/generic" },
        initParams =  {
                @WebInitParam(name="admin", value="jiangfeilong"), 
                @WebInitParam(name="email", value="admin@example.com")
        }
        )
public class GenericServletDemoServlet  extends GenericServlet{
    
    /**
     * 
     */
    private static final long serialVersionUID = 62500890L; //版本id

    @Override
    public void service(ServletRequest request, ServletResponse response) throws ServletException, IOException {
        ServletConfig servletConfig = this.getServletConfig();
        String admin = servletConfig.getInitParameter("admin");
        String email = servletConfig.getInitParameter("email");
        response.setContentType("text/html");
        PrintWriter writer = response.getWriter();
        writer.print("<html><head></head><body>" +
                    "Admin: " + admin + "<br /> Eamil: " + email +
                    "</body></html>");
        
    }

}

运行

七: HttpServlet

java.servlet.http中的许多类继承了javax.servlet中的类型

从左至右为继承关系
HttpServlet javax.servlet.GenericServletServlet javax.servletServlet(接口)
HttpSession(接口) httpservletRequest(接口) javax.servlet.ServletRequset(接口)
Cookie HttpServletResponse(接口) javax.servlet.ServletResponse(接口)

1.HttpServlet

HttpServlet覆盖了GenericServlet中的Service方法,并通过下列签名再添加了一个Service方法,参数链表都是http开头

protected void service(HttpServletRequest, HttpServletResponse response) throws ServletException, java.io.IOException

Servlet容器调用javax.servlet.Servlet中原始的Service方法,HttpServlet中的编写方法如下:

public void service(ServletRequset req,ServletResponse res) throws ServletException, IOException{
HttpServletRequset requset;
HtttpServletResponse response;
try{
request = (HtppServletRequest) req;
response = (httpServletResponse) res;
}catch (ClassCastException e){
throw new ServletException("non--Http request or response");
}
service(request,response);
}

HttpServlet特性是GenericServlet所不具备的,不用覆盖方法,而是覆盖doGet或这doPost,在少数情况下花卉覆盖以下任意方法: doHead, doPut , doTrace, doOptions 和 doDelete

2.HttpServletRequest

HttpServletRequest 表示Http环境中的Servlet请求,它扩展javax.servlet.ServletRequest接口,并增加了下列几个方法

java.lang.String getContextPath()//放回表示请求上下文的URI部分

Cookie[] getCookies(); //返回Cookie对象数组

java.lang.String getHeader(java.lang.String name)//返回指定HTTP标题的值

java.lang.String.getMethod() //返回生成这个请求的http方法的名称

java.lang.String getQueryString() //返回请求URL中的查询字符

HttpSession getSession() //返回与这个请求相关的会话对象,如果没有,将会创建一个新的会话对象

HttpSession getSession(boolean create) //返回与这个请求相关的会话对象,如果没有,并且create参数为true,将会创建一个新的会话对象

3.HttpServletResponse

HttpServletResponse 表示HTTP环境中的Servlet响应,下面是它里面定义的部分方法:

void addCookie(Cookie cookie) /给一个响应对象添加一个cookie

void addheader(java.lang.String name, java.lang.String value) //给一个响应对象添加一个header

void sendRedirect( java.lang.String location)//发送一条响应码,将浏览器跳转到指定的位置

4.处理HTTP表单

包含多个知道select元素(<select multiple>表示的select元素)发出一个字符串数组,必须通过ServletRequest.getParameterValues处理

复选框比较奇特,核查过的复选框会发送字符串"on"到服务器,未经核查的复选框不向服务器发送任何数据

单选框将被选择的值发送到服务器,如果没有选择任何值,将不会发送任何内容到服务器

如果一个表单中包含多个输入同名的元素,那么所有值都会被提交,并且必须利用ServletRequest.getParameterValues来获取它们,ServletRequest.getParameter将只返回最后一个值

 当浏览器发送请求时,会调用ServletHttp 的doGet方法,当有表单提交时会调用doPost()方法

HttpServlet类

package app;

import java.io.*;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.regex.*;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(name = "FormServlet", urlPatterns = "/form")
public class FormServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;
    private static final String[] nReplace = { "NAME", "ADDRESS", "COUNTRY", "DELMETHOD", "CATALOG",
            "INSTRUCTIONS", "PARAMETERNAMES" };
    private static final String[] names = { "name", "address", "country", "delivery", "catalog", "instruction",
            "parameternames" };
    private static final String[] nValue = new String[7];
    //当html页面的标签<form method ="get" >是get方法时会调用此方法
    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter writer = response.getWriter();
        String path = this.getServletContext().getRealPath("/WEB-INF/form.html");
        String s = null;
        s = read(path);
        writer.print(s);

    }

    //当html页面的标签<form method ="post" >是post方法时会调用此方法
    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter writer = response.getWriter();

        StringBuilder INSTRUCTIONS = new StringBuilder();
        StringBuilder PARAMETERNAMES = new StringBuilder();
        for (int i = 0; i < 4; i++)
            nValue[i] = request.getParameter(names[i]); // 得到元素的值

        String[] instructions = request.getParameterValues("instruction");
        if (instructions != null) {
            for (String instruction : instructions)
                INSTRUCTIONS.append(instruction + "<br>");
            nValue[5] = INSTRUCTIONS.toString();
        }
        if (request.getParameter("catalog") == null)
            nValue[4] = "No";
        else
            nValue[4] = "Yes";
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String parameterName = parameterNames.nextElement();
            PARAMETERNAMES.append(parameterName + "<br />");
            nValue[6] = PARAMETERNAMES.toString();
        }

        String path = this.getServletContext().getRealPath("/WEB-INF/order_form.html");
        String s = null;
        s = read(path);
        for (int i = 0; i < nReplace.length; i++)
            s = replace(s, nReplace[i],nValue[i]);
        writer.print(s);
    }

    public static String replace(String html, String nReplace, String nameValue) {
        String str = html;
        Pattern pattern = Pattern.compile(">" + nReplace);
        Matcher matcher = pattern.matcher(html);
        if(nameValue !=null )
            str = matcher.replaceAll(">" +nameValue);
        else
            str = matcher.replaceAll(">");

        return str;
    }

    public static String read(String path) throws IOException {
        StringBuilder sb = new StringBuilder();

        try (BufferedReader in = new BufferedReader(new FileReader(new File(path).getAbsoluteFile()))) {
            try {
                String s = null;
                while ((s = in.readLine()) != null) {
                    sb.append(s + "
");
                }
            } finally {
                if (in != null)
                    try {
                        in.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return sb.toString();
    }
}

get页面(html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Order Form</title>
</head>
<body>
    <h1>Order Form</h1>
    <form method='post'>
    <table>
        <tr>
            <td>Name:</td><td><input  name='name' /></td>
        </tr>
        <tr>
            <td>Address:</td>
            <!--文本区域  会将文字发送给服务器,如若没有任何内容,则会发送空字符""给服务器 -->
            <td><textarea name="address" id="" cols="40" rows="5"></textarea></td>
        </tr>
        <tr>
            <td>Country:</td>
            <!--  下拉框select 如果被选择,会将option选项的文字发送给服务器,不会向服务器返回任何值,  getParameter()为null -->
            <td><select name='country'>
            <option>Canada</option>
            <option>United States</option>
            </select></td>
        </tr>
        <tr>
            <td>Delivery Method:</td>
            <!--  radio 如果没有选择,不会向服务器返回任何值,  getParameter()为null-->
            <td><input type="radio" name="delivery" id="" value="First Class" />First Class
            <input type="radio" name="delivery" value="Second" />Second Class
            </td>
        </tr>
        <tr>
            <td>Shipping Instructions:</td>
            <!--  多个区域不输入内容,默认发送个<br> -->
            <td><textarea name="instruction" id="" cols="40" rows="5"></textarea></td>
        </tr>
        <tr>
            <td>&nbsp;</td>
            <td><textarea name="instruction" id="" cols="40" rows="5"></textarea></td>
        </tr>
        <tr>
            <td>P    lease send me the latest product catalog:</td>
            <!--  单选框checkbox 将被选中按钮的值发送到服务器,如果没有选择任何按钮,将没有任何内容被发送到服务器
              getParameter()为null-->
            <td><input type="checkbox" name="catalog" /></td>
        </tr>
        <tr>
            <td>&nbsp;</td>
            <td><input type="reset" /> <input type="submit" /></td>
        </tr>
    </table>
    </form>
</body>
</html>

post页面(html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Order Form</title>
</head>
<body>
    <h1>Order Form</h1>
    <table>
        <tr>
            <td>Name:</td><td>NAME</td>
        </tr>
        <tr>
            <td>Address:</td>
            <td>ADDRESS</td>
        </tr>
        <tr>
            <td>Country:</td>
            <td>COUNTRY</td>
        </tr>
        <tr>
            <td>Shipping Instructions:</td>
            <td>INSTRUCTIONS</td>
        <tr>
            <td>Delivery Method:</td>
            <td>DELMETHOD</td>
        </tr>
        <tr>
            <td>Catalog Request: </td>
            <td>CATALOG </td>
        </tr>
    </table>
    <div style="border:1px solid #ddd; margin-top:40px;font-size:90%">
    Debug info<br />PARAMETERNAMES
    </div>
</body>
</html>
原文地址:https://www.cnblogs.com/jiangfeilong/p/10640120.html