java的servlet基础

概念

1.运行环境

JDK1.8
Tomcat 8.0
Intellij IDEA : http://www.jetbrains.com/idea/

写一个web项目时还需要一个jar包javax.servlet.-api.jar
要将其复制到JDK的扩展目录中去,角度看。D:jdk1.7/jre/lib/ext

2.工作原理

先附上代码吧嘻嘻嘻
这是web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>servlet1
        </servlet-name>
        <servlet-class>classes.myservlet.control.servlet1</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>servlet1</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>

好的,看到这个web.xml文件,我们就先来看看这几个标记代表的意思

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
        version="4.0">
   <servlet>
       <servlet-name>这里就是我们的servlet文件名
       </servlet-name>
       <servlet-class>这里时我们的servlet文件所在位置,一般是在项目的src目录下</servlet-class>
   </servlet>
   <servlet-mapping>
       <servlet-name>这里也是我们的项目名,一般web.xml中不止配置一个servlet,所以需要靠servlet的名字进行搜索匹配</servlet-name>
       <url-pattern>这里是浏览器上搜索需要加上的servlet文件的url片段</url-pattern>
   </servlet-mapping>
</web-app>
我们在浏览器上通过主机号和<servlet-mapping>的url片段找到servlet-name
然后通过<servlet>的servlet-name找到具体的servlet.class

这是servlet文件

package classes.myservlet.control;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class servlet1 extends HttpServlet
{
    public void init(ServletConfig config)throws ServletException{
        super.init(config);
    }
    public void service(HttpServletRequest request, HttpServletResponse response)throws IOException{
        request.setCharacterEncoding("gbk");

        String str=request.getParameter("moon");
        response.setContentType("text/html;charset=gbk");
        PrintWriter out=response.getWriter();
        String servletName=getServletName();
        out.println("<html><body bgcolor=#eeddff>");
        out.println("<b>请求的servlet的名字是"+servletName+"<br></b>");
        out.println("<b>servlet在WEB设计中非常重要<br></b>");
        if(str!=null&&str.length()>=1)
            out.println("<br><h2>"+str+"<h2>");
        out.println("</body></html>");
    }
}

我这里直接在response写完了页面

用Java写完servlet文件和前端页面之后,配置好web.xml,启动tomcat服务器
在浏览器中用local host:8080(端口号)/页面或servlet名?参数1=value&参数2=value(例如:http://localhost:8080/hello?moon=ajie)

(1)servlet的生命周期

每个servlet文件都要继承HttpServlet
在这里插入图片描述
生命周期分为三个过程
初始化Servlet,调用init方法完成必要的初始化工作
新诞生的Servlet调用service方法响应用户请求
当服务器关闭时,调用destroy方法销毁servlet

通过jsp页面访问servlet

jsp的位置
在这里插入图片描述
可以在页面中通过用表单的形式向servlet提交数据

<form action="accountBill?side=4&side1=5">
这里的accountBill就是servlet文件,
用这种方法把表单信息传给servlet文件。
这里还传了两个参数值
<input type="submit" value="提交">
form里面需要有一个提交按钮
<form>
还可以用超链接
<a href="accountBill?side=4&side1=5">

再来讲讲共享变量,照例贴代码

package classes.myservlet.control;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class servlet2 extends HttpServlet
{
    double sum=0,i=1,j=1;
    int number=0;
    public void init(ServletConfig config)throws ServletException{
        super.init(config);
    }
    public void service(HttpServletRequest request, HttpServletResponse response)throws IOException{
        request.setCharacterEncoding("gbk");


        response.setContentType("text/html;charset=gbk");
        PrintWriter out=response.getWriter();
        String servletName=getServletName();
        out.println("<html><body>");
        number++;
        sum=sum+i/j;
        j=j+2;
        i=-i;
        out.println("servlet:"+getServletName()+"已经被请求了"+number+"次");
        out.println("现在的PI值是:");
        out.println(4*sum);
        out.println("</body></html>");
    }
}

从代码里面可以知道,我们把变量sum等设成全局变量,每一次对servlet的访问,都对service方法进行调用,而sum的值的变化永远在上一次被浏览的基础上进行改变。

好的,接下来我们讲一下请求方式,也就是method标记

package classes.myservlet.control;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class servlet1 extends HttpServlet
{
    public void init(ServletConfig config)throws ServletException{
        super.init(config);
    }
    public void doGet(HttpServletRequest request, HttpServletResponse response)throws IOException{
    request.setCharacterEncoding("gbk");

    String str=request.getParameter("name");
    response.setContentType("text/html;charset=gbk");
    PrintWriter out=response.getWriter();
    String servletName=getServletName();
    out.println("<html><body bgcolor=#eeddff>");
    out.println("<b>请求的servlet的名字是"+servletName+"<br></b>");
    out.println("<b>servlet在WEB设计中非常重要<br></b>");
    if(str!=null&&str.length()>=1)
        out.println("<br><h2>"+str+"<h2>");
    out.println("</body></html>");
    }
    public void service(HttpServletRequest request, HttpServletResponse response)throws IOException{
        request.setCharacterEncoding("gbk");

        String str=request.getParameter("name");
        response.setContentType("text/html;charset=gbk");
        PrintWriter out=response.getWriter();
        String servletName=getServletName();
        out.println("<html><body bgcolor=#eeddff>");
        out.println("<b>请求的servlet的名字是"+servletName+"<br></b>");
        out.println("<b>servlet在WEB设计中非常重要<br></b>");
        if(str!=null&&str.length()>=1)
            out.println("<br><h2>"+str+"<h2>");
        out.println("</body></html>");
    }
    public void doPost(HttpServletRequest request, HttpServletResponse response)throws IOException{
        request.setCharacterEncoding("gbk");

        String str=request.getParameter("name");
        response.setContentType("text/html;charset=gbk");
        PrintWriter out=response.getWriter();
        String servletName=getServletName();
        out.println("<html><body bgcolor=#eeddff>");
        out.println("<b>请求的servlet的名字是"+servletName+"<br></b>");
        out.println("<b>servlet在WEB设计中非常重要<br></b>");
        if(str!=null&&str.length()>=1)
            out.println("<br><h2>"+str+"<h2>");
        out.println("</body></html>");
    }
}

可以看到,其中有三个方法,doget(),dopost(),service()

<form action="/hello?name=name"method="post">
      <input type="text" name="name">
  </form>

当我用post方法访问时
在这里插入图片描述
在这里插入图片描述

当我用get访问时
在这里插入图片描述
在这里插入图片描述
可以看出,当有service方法时,不管请求方式是post还是get,都直接执行service方法

那么如果没有service方法呢?嗯~~好问题
我们来看看
把代码中的service()方法去掉
用post方法调用

在这里插入图片描述
当用get方法调用时
在这里插入图片描述
嗯嗯,原来是这样滴,这里有service()方法时,所有通过hello进到servlet.java的都执行service方法,如果没有,再按照method标记的方式去找doGet()或者doPost()方法。
这是我们自己实验得到的结果,那么到底是不是百分之百准确呢?
怎么验证呢,哦吼。
还记不记得servlet的生命周期,小编早就知道你看过就忘了,要好好记得原理的东西。
这张详细的生命周期图收好了

  1. init()方法

    在Servlet的生命周期中,仅执行一次init()方法,它是在服务器装入Servlet时执行的,可以配置服务器,以在启动服务器或客户机首次访问Servlet时装入Servlet。无论有多少客户机访问Servlet,都不会重复执行init();

  2. service()方法

    它是Servlet的核心,每当一个客户请求一个HttpServlet对象,该对象的Service()方法就要调用,而且传递给这个方法一个“请求”(ServletRequest)对象和一个“响应”(ServletResponse)对象作为参数。在HttpServlet中已存在Service()方法。默认的服务功能是调用与HTTP请求的方法相应的do功能。

  3. destroy()方法

    仅执行一次,在服务器端停止且卸载Servlet时执行该方法,有点类似于C++的delete方法。一个Servlet在运行service()方法时可能会产生其他的线程,因此需要确认在调用destroy()方法时,这些线程已经终止或完成。

该去看看源码了。

有心的可以自己找出来看看,自己找总是好的,了解更多,小编给你们的也是小编自己的理解,得到新理解大家可以互相讨论
HttpServlet

    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getMethod();
        long lastModified;
        if (method.equals("GET")) {
            lastModified = this.getLastModified(req);
            if (lastModified == -1L) {
                this.doGet(req, resp);
            } else {
                long ifModifiedSince = req.getDateHeader("If-Modified-Since");
                if (ifModifiedSince < lastModified) {
                    this.maybeSetLastModified(resp, lastModified);
                    this.doGet(req, resp);
                } else {
                    resp.setStatus(304);
                }
            }
        } else if (method.equals("HEAD")) {
            lastModified = this.getLastModified(req);
            this.maybeSetLastModified(resp, lastModified);
            this.doHead(req, resp);
        } else if (method.equals("POST")) {
            this.doPost(req, resp);
        } else if (method.equals("PUT")) {
            this.doPut(req, resp);
        } else if (method.equals("DELETE")) {
            this.doDelete(req, resp);
        } else if (method.equals("OPTIONS")) {
            this.doOptions(req, resp);
        } else if (method.equals("TRACE")) {
            this.doTrace(req, resp);
        } else {
            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[]{method};
            errMsg = MessageFormat.format(errMsg, errArgs);
            resp.sendError(501, errMsg);
        }

    }

由此可知,如果我们没写service()方法时,它会到我们继承的这个类中找到这个方法,然后去找doGet()等等。
请求方法的问题就说到这,接下来轮到另一个point了。
在过程中我们除了超链接或者提交信息给某个页面,还有另外一个方法,通过转发的方式

这是第一个请求页面
在这里插入图片描述
然后就跳到servlet3.java控制跳转

package classes.myservlet.control;

import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;

public class servlet3 extends HttpServlet {
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }

    public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        String number=request.getParameter("number");
        try{
            double n=Double.parseDouble(number);
            if(n<0)
                response.sendRedirect("example5_6.jsp");
            else{
                RequestDispatcher dispatcher=request.getRequestDispatcher("example5_6.jsp");
                dispatcher.forward(request,response);
            }
        }
        catch (NumberFormatException e){
            response.sendRedirect("example5_6.jsp");
        }
    }
}

response.sendRedirect(“要跳转的页面”)

这是重定向,由方法即可看出,是要把页面调用过来而已
在这里插入图片描述

RequestDispatcher dispatcher=request.getRequestDispatcher(“要跳转的页面”) ;dispatcher.forward(request,response);

这是转发,由方法可知,它还将request的内容传过去了
在这里插入图片描述
对比之后,即见分晓。
说到这里,顺便提一下很少见到的include,这也是request.getRequestDispatcher()的一个方法,与forward不同的是request是将跳转页面的response作为response,而include是将后者作为申请页面response的补充
在这里插入图片描述
接下来轮到另外一个重要的概念了

session

许多时候,我们需要服务器为我们保存一个value,所以我们会用到session,可以确保在这个会话中保持不变,除非我们主动更改
照例贴代码讲解

package classes.myservlet.control;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class servlet4 extends HttpServlet {
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }
    public void service(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException{
        HttpSession session=request.getSession(true);
        String str=request.getParameter("clientGuessLetter");
        Character guessLetter=str.trim().charAt(0);
        Character savedLetter=(Character)session.getAttribute("savedLetter");
        char realLetter=savedLetter.charValue();
        if(Character.isUpperCase(guessLetter)){
            guessLetter=Character.toLowerCase(guessLetter);
        }
        if(guessLetter<realLetter){
            session.setAttribute("message","您猜小了");
            response.sendRedirect("example5_7input.jsp");
        }
        if(guessLetter>realLetter){
            session.setAttribute("message","您猜大了");
            response.sendRedirect("example5_7input.jsp");
        }
        if(guessLetter==realLetter){
            session.setAttribute("message","您猜对了");
            response.sendRedirect("example5_7input.jsp");
        }

    }

}

<%--
  Created by IntelliJ IDEA.
  User: 57765
  Date: 2019/11/23
  Time: 10:04
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body bgcolor="eeffdd">
    <%session.setAttribute("message","请您猜字母");
    char a[]=new char[26];
    int m=0;
    for(char c='a';c<='z';c++){
        a[m]=c;
        m++;
    }
    int randomIndex=(int)(Math.random()*a.length);
    char ch=a[randomIndex];
    session.setAttribute("savedLetter",new Character(ch));%>
访问或刷新该页面可以随机得到一个英文字母
<br>单击超链接去猜这个字母:<a href="example5_7input.jsp">去猜字母</a>
</body>
</html>

<%--
  Created by IntelliJ IDEA.
  User: 57765
  Date: 2019/11/23
  Time: 10:11
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%String message=(String)session.getAttribute("message");
    %>
<table border="1">
    <form action="guessLetter" method="post">
        <tr>
            <td>
                输入您的猜测(a~z之间的字母:</td>
            </td>
            <td>
                <input type="text"name="clientGuessLetter" size="4">
                <input type="submit" value="提交">
            </td>
        </tr>
        <tr>
            <td>
                提示信息
            </td>
            <td>
                <%=message%>
            </td>
        </tr>
    </form>
    <form action="example5_7.jsp" method="post">
        <tr>
            <td>
                单击按钮重新开始
            </td>
            <td>
                <Input type="submit" value="随机得到一个字母">
            </td>
        </tr>
    </form>

</table>
</body>
</html>

<servlet>
        <servlet-name>servlet4
        </servlet-name>
        <servlet-class>classes.myservlet.control.servlet4</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>servlet4</servlet-name>
        <url-pattern>/guessLetter</url-pattern>
    </servlet-mapping>

可以看到,我们通过进入example5_7.jsp后,得到一个随机英文字母
接着我们就提交进行跳转页面到example5_7input.jsp进行猜字母
在这个过程中,我们没有对session保存的字母进行改变,除非我们按下“重新猜字母”的按钮
session在request.getSession(true)中得到。

嗯~~,好的,算作这两天重新看servlet的总结了,有什么问题可以和小编进行讨论

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值