Servlet

作者: 赵小莹 | 来源:发表于2018-03-18 20:13 被阅读0次

    Servlet 简介
    Java Servlet是和平台无关的服务器端组件,它运行在Servlet容器中。Servlet容器负责Servlet和客户的通信以及调用Servlet的方法,Servlet和客户的通信采用“请求/响应”的模式。

    Servlet可完成如下功能:
    创建并返回基于客户请求的动态HTML页面。
    与其它服务器资源(如数据库或基于Java的应用程序)进行通信。


    Servlet本质上就是一个运行在Servlet容器中的Java类,现在充当Servlet容器的就是安装的Tomcat

    第一个Servlet——HelloWorld
    1.创建一个Java类实现Servlet接口,并实现其中所有的方法;

    package servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    /**
     * Created by ttc on 2018/3/6.
     */
    @WebServlet("/hello")
    public class HelloServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        }
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("HelloServlet");
        }
    }
    

    @WebServlet("/hello")
    表示的是为helloServlet映射一个访问路径/hello,我们在浏览器上输入http://localhost:8080/hello,代码执行程序流会进入到HelloServlet 的doGet方法。

    3.运行Tomcat,在浏览器中输入http://localhost:8080/hello,可以发现控制台输出了一些内容,首先是构造器,然后是init,再然后是service,然后每次刷新,每次都只出现了service,然后关闭服务,发现出现destory。

    Servlet的生命周期

    package servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * Created by ttc on 2018/3/6.
     */
    @WebServlet("/hello")
    public class HelloServlet extends HttpServlet {
        @Override
        public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
            System.out.println("service");
            HttpServletRequest request = (HttpServletRequest)req;
            System.out.println(request.getMethod());
            super.service(req, res);
        }
    
        @Override
        public void destroy() {
            System.out.println("destroy");
            super.destroy();
        }
    
        @Override
        public void init() throws ServletException {
            System.out.println("init");
            super.init();
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("doPost");
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("doGet");
        }
    }
    
    

    ①服务器加载Servlet,服务器启动之后,但不是创建Servlet

    ②创建Servlet实例
    --只有第一次请求Servlet时,创建Servlet实例,调用构造器也就是和类名一样的构造方法,没写的话自动生成

    ③初始化init()
    --只被调用一次,在创建好实例后立即被调用,用于初始化当前Servlet

    ④service()处理用户请求
    --可以被多次调用,每次请求都会调用service方法,实际用于响应请求的,根据用户请求的类型(get或者post),调用doGet或者doPost方法。

    ⑤destory()销毁
    --只被调用一次,在当前Servlet所在的WEB应用被卸载前调用,用于释放当前Servlet所占用的资源


    load-on-startup

    可以指定Servlet被创建的时机

    package servlet;
    
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    /**
     * Created by ttc on 2018/3/6.
     */
    @WebServlet(value = "/hello",loadOnStartup = 1)
    public class HelloServlet extends HttpServlet {
        @Override
        public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
            System.out.println("service");
            HttpServletRequest request = (HttpServletRequest)req;
            System.out.println(request.getMethod());
            super.service(req, res);
        }
    
        @Override
        public void destroy() {
            System.out.println("destroy");
            super.destroy();
        }
    
        @Override
        public void init() throws ServletException {
            System.out.println("init");
            super.init();
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("doPost");
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("doGet");
        }
    }
    
    

    在加载完Servlet后直接就创建了Servlet实例,并进行了初始化,在此期间我们并没有提出请求。
    如果配置了多个Servlet, load-on-startup的值越小越先启动(包括0,负数不会被启动,还是需要发出请求才创建实例并初始化);


    Servlet映射细节

    在Servlet映射到的URL中也可以使用 * 通配符,但是只能有两种固定的格式:
    一种格式是“* .扩展名”

    @WebServlet(value = "*.do")
    public class HelloServlet extends HttpServlet
     {
    }
    
    

    另一种格式是以正斜杠(/)开头并以“/ * ”结尾。

    @WebServlet(value = "/*")
    public class HelloServlet extends HttpServlet
     {
    }
    
    

    注意:既带 / 又带 * 的,又带扩展名的,是不合法的(例如:/.do)。*
    urlPatterns = "/" 比urlPatterns = ".do"的优先级高

    HTTP简介

    WEB浏览器与WEB服务器之间的一问一答的交互过程必须遵循一定的规则,这个规则就是HTTP协议。
    HTTP是 hypertext transfer protocol(超文本传输协议)的简写,它是 TCP/IP 协议集中的一个应用层协议,用于定义WEB浏览器与WEB服务器之间交换数据的过程以及数据本身的格式。

    HTTP 的会话方式

    四个步骤:

    浏览器与WEB服务器的连接过程是短暂的,每次连接只处理一个请求和响应。对每一个页面的访问,浏览器与WEB服务器都要建立一次单独的连接。
    浏览器到WEB服务器之间的所有通讯都是完全独立分开的请求和响应对。

    HTTP请求消息(了解即可)

    请求消息的结构:
    一个请求行、若干消息头、以及实体内容,其中的一些消息头和实体内容都是可选的,消息头和实体内容之间要用空行隔开。

    HTTP响应消息(了解即可)

    响应消息的结构:
    一个状态行、若干消息头、以及实体内容 ,其中的一些消息头和实体内容都是可选的,消息头和实体内容之间要用空行隔开。
    这里举个小实例:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
    
        <form action="/loginServlet" method="post">
            user:<input type="text" name="user">
            password:<input type="password" name="password">
            <input  type="submit" value="Submit">
        </form>
    
    </body>
    </html>
    
    

    运行服务器,在浏览器中打开这个网页,开发者工具,提交表单,提示404(申请资源不存在),在chrome network中查看请求及响应消息。

    POST和GET请求

    post请求方式我们可以看到请求参数在请求体里面
    将请求方式改为get后再运行观察

    <form action="/loginServlet" method="get">
            user:<input type="text" name="user">
            password:<input type="password" name="password">
            <input  type="submit" value="Submit">
    </form>
    
    

    可以观察到地址栏是这样的:http://localhost:8080/loginServlet?user=123&password=123
    get请求把请求参数附着在url后面,中间以"?”分割。

    使用GET方式传递参数

    ①在浏览器地址栏中输入某个URL地址或单击网页上的一个超链接时,浏览器发出的HTTP请求消息的请求方式为GET。
    ②如果网页中的<form>表单元素的method属性被设置为了“GET”,浏览器提交这个FORM表单时生成的HTTP请求消息的请求方式也为GET。
    ③使用GET请求方式给WEB服务器传递参数的格式:
    http://www.neusoft.net/counter.jsp?name=yzn&password=123
    ④使用GET方式传送的数据量一般限制在1KB以下。

    使用POST方式传递参数

    ①POST请求方式主要用于向WEB服务器端程序提交FORM表单中的数据。
    ②POST方式将各个表单字段元素及其数据作为HTTP消息的实体内容发送给WEB服务器,传送的数据量要比使用GET方式传送的数据量大得多。
    3.如果网页中的<form>表单元素的method属性被设置为了“POST”,浏览器提交这个FORM表单时生成的HTTP请求消息的请求方式也为POST。


    如何在Servlet中获取信息

    这里我们可以新建一个Servlet。

    @WebServlet("/loginServlet")
    public class LoginServlet extends HttpServlet { 
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("get");
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            System.out.println("post");
        }
    
    }
    
    

    其中,方法的参数HttpServletRequest requestHttpServletResponse response封装了请求和响应信息

    一.如何获取请求信息

    HttpServletRequest常用的方法:
    String getParameter(String name)
    --根据请求参数的名字,返回参数值,特别常用

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String user = request.getParameter("user");
            String password = request.getParameter("password");
            System.out.println(user+"   "+password);
    }
    
    

    String[] getParameterValues(String name)
    --根据请求参数的名字,返回请求参数对应的字符串数组(例如:一组复选框-->名字是一样的)
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String intrests[] = request.getParameterValues("hobby");
            for(String str:intrests) {
                System.out.println(str);
            }
    }
    
    

    获取请求的URI
    获取请求方式

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
            String method = request.getMethod();
            System.out.println(method);
    
            String servletPath = request.getServletPath();
            System.out.println(servletPath);
    }
    
    

    解决请求中的中文乱码问题:

    request.setCharacterEncoding("utf-8");

    二.如何返回响应信息

    HttpServletResponse常用的方法:
    ①getWriter()方法
    --返回PrintWriter对象,调用这个对象的println()方法可以将信息直接打印在客户的浏览器上

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
    
            PrintWriter out = response.getWriter();
            out.println("hello...");
    
    }
    
    

    解决回应中的中文乱码问题

    //1.设置response的编码为utf-8
    response.setCharacterEncoding("utf-8");
    //2.通知浏览器,以UTF-8的编码打开
    response.setContentType("text/html;charset=UTF-8");

    练习

    定义一个login.html,里面定义一个表单,表单中包含2个请求字段user,password,发送请求到loginServlet,再创建一个LoginServlet,在其中获取请求的user,password,比对其是否是zhangsan,123,若一致,响应Hello:xxx;若不一致,响应Sorry:xxx;xxx为user

    <html>
      <head>
        <title>$Title$</title>
      </head>
      <body>
      <a href="login.html">login</a>
      </body>
    </html>
    
    import javax.servlet.ServletException;
    import javax.servlet.annotation.WebServlet;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.PrintWriter;
    
    @WebServlet(name = "loginServlet",urlPatterns = "/login")
    public class loginServlet extends HttpServlet {
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
            String username = request.getParameter("username");
            String password = request.getParameter("password");
            PrintWriter printWriter =response.getWriter();
            if(username.equals("zhangsan")&&password.equals("123")){
                printWriter.println("hello"+username);
            }
            else {
                printWriter.println("sorry"+username);
            }
        }
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        }
    }
    
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <form method="post" action="login">
        <input type="text" name="username">
        <input type="text" name="password">
        <input type="submit">
    </form>
    </body>
    </html>
    

    上面的输入中文会乱码,改进措施

    相关文章

      网友评论

          本文标题:Servlet

          本文链接:https://www.haomeiwen.com/subject/radsqftx.html