美文网首页
JavaEE学习笔记Day2

JavaEE学习笔记Day2

作者: Juvemace | 来源:发表于2018-08-28 21:34 被阅读0次

    JavaEE学习笔记day2

    理解Servlet的编写和访问过程
    掌握Servlet父子类之间的继承关系
    理解Servlet处理、解析请求以及返回响应的过程
    Servlet页面跳转

    Servlet的编写和访问过程

    servlet的运行过程

    servlet程序是由web服务器调用,web服务器收到客户端的发起的http访问请求后:

    1. HTTP服务器(Apache)收到HTTP请求以后,转发给Web容器(Tomcat),此时Web容器会解析HTTP请求的内容,web容器通过请求的URL来选择需要用哪个Servlet来处理请求(这个就是web.xml中配置的或者@webServlet注解的作用了)
    2. web服务器首先检查是否已经装载并创建了该servlet的实例对象。如果是,则执行第5步,否则执行第3步
    3. 装载并创建给servlet的一个实例对象
    4. 调用servlet实例对象的init()方法。
    5. 创建一个用于封装HTTP请求的HttpServletRequest对象和一个代表HTTP响应消息的HttpServletResponse对象,然后调用Servlet的service()方法并将请求和和响应对象作为参数传递出去。
    6. web应用程序被停止或重启之前Servlet引擎将卸载Servlet,并在卸载之前的调用Servlet的destory()方法。

    在整个servlet程序中最重要的是Servelt接口,在此接口下定义了一个GenericServlet的子类,但一般不会直接继承此类,而是根据所使用的协议选项GenericServlet的子类继承。(后面会介绍几个servlet的区别)

    例如:采用HTTP协议处理,一般而言需要使用HTTP协议操作,用户自定义的Servlet类要继承HttpServlet类。

    开发一个可以处理Http请求的Servlet类,则肯定需要继承HttpServlet类,该类提供了不同的方法用于响应客户端请求,常见的方法有:

    1. doGet(HttpServletRequest req, HttpServletResponse resp)
    2. doPost(HttpServletRequest req, HttpServletResponse resp)
    3. service(HttpServletRequest req, HttpServletResponse resp)

    在自定义的Servlet类中,根据实际需要重写HttpServlet类中提供的方法,Servlet程序本身也是按照请求响应的方式进行的,所以在方法中定义了两个参数,即HttpServletRequestHttpServletResponse ,用来接收和回应用户的请求。

    servlet的编写

    1. 实现Servlet接口,然后实现接口中的五个方法
      1. init(ServletConfig parm1) //该函数用于初始化servlet,类似于类的构造函数,该函数只会被调用一次
      2. getServletConfig()
      3. service(ServletRequest req, ServletResponse res) //这个函数用于处理业务逻辑
        //当用户每访问servlet时,都会调用
        //req:用于获得客户端(浏览器)信息
        //res:用于向客户端(浏览器)返回信息
      4. getServletInfo()
      5. destroy() //销毁,释放内存,三种方式会触发destroy
        //1. reload该servlet(webApps) 2. 关闭tomcat 3.关机
    2. 继承GenericServlet,只需要实现一个方法:service
    3. 继承HttpServlet,复写doGet和doPost方法

    Servlet父子类之间的继承关系

    三种访问方式的区别

    • 可以看到Servlet接口是定义在javax.servlet包中,该接口定义了5个方法。
      • init() :在Servlet实例化之后,Servlet容器会调用init()方法,来初始化该对象,主要是为了让Servlet对象在处理客户请求之前可以完成一些初始化工作,比如:建立数据库的连接,获取配置信息。
      • service():容器调用service()方法来处理客户端的请求。
      • destroy():当容器检测到一个Servlet对象应该从服务器中被移除的时候,容器会调用该对象的destroy方法,以便让Servlet对象可以释放它所使用的资源,保存数据到持久化存储设备中,例如:将内存中的数据保存到数据库中,关闭数据库的连接。
    • GenericServlet
      直接通过实现Servlet接口来编写一个Servlet类,就需要实现Servlet接口中定义的5种方法,为了简化Servlet的编写,在javax.servlet包中,给我们提供了一个抽象的类GenericServlet,它提供了除service()方法外的其他4种方法的简单实现。GenericServlet类定义了一个通用的,不依赖具体协议的Servlet
    • HttpServlet 由于大多数网络应用中,都是浏览器通过HTTP协议去访问服务器资源,而通常编写的Servlet也主要是应用于HTTP协议的请求和响应,为了快速开发应用于HTTP协议的Servlet,Sun公司在javax.servlet.http包中给我们提供了一个抽象的类HttpServlet,他继承自GenericServlet类,用于创建适合Web站点的HTTP Servlet。
      比如,doPost() doGet()这些方法,从request解析请求信息开始,将根据http协议的格式进行解析,分发到不同的请求方法处理中,doPost() doGet()也肯定是被service方法调用的。

    Servlet中的请求与响应

    get请求和post请求的异同

    • 生成方式:
      • get方式有四种: 1)直接在URL地址栏中输入URL。2)网页中的超链接。3)form中method为get。4)form中method为空时,默认是get提交。
      • post方式:form中method属性为post。
    • 数据传送方式
      • get方式:表单数据存放在URL地址后面。所有get方式提交时HTTP中没有消息体。表单数据存放在URL地址后面。所有get方式提交时HTTP中没有消息体。
      • post方式:表单数据存放在HTTP协议的消息体中以实体的方式传送到服务器。表单数据存放在HTTP协议的消息体中以实体的方式传送到服务器。
    • 服务器获取数据方式
      • GET方式:服务器采用request.QueryString来获取变量的。
      • POST方式:服务器采用request.Form来获取数据。
    • 传送的数据量
      • GET方式:数据量长度有限制,一般不超过2kb。因为是参数传递,且在地址栏中,故数据量有限制。
      • POST方式:适合大规模的数据传送。因为是以实体的方式传送的。
    • 安全性
      • GET方式:安全性差。因为是直接将数据显示在地址栏中,浏览器有缓冲,可记录用户信息。所以安全性低。
      • POST方式:安全性高。因为post方式提交数据时是采用的HTTP post机制,是将表单中的字段与值放置在HTTP HEADER内一起传送到ACTION所指的URL中,用户是看不见的。

    servlet请求处理过程

    1. Web Client 向Servlet容器(Tomcat)发出Http请求;
    2. Servlet容器接收Web Client的请求;
    3. Servlet容器创建一个HttpRequest对象,将Web Client请求的信息封装到这个对象中;
    4. Servlet容器创建一个HttpResponse对象;
    5. Servlet容器调用HttpServlet对象的service方法,把HttpRequest对象与HttpResponse对象
    6. 为参数传给 HttpServlet对象;
    7. HttpServlet调用HttpRequest对象的有关方法,获取Http请求信息;
    8. HttpServlet调用HttpResponse对象的有关方法,生成响应数据;
    9. Servlet容器把HttpServlet的响应结果传给Web Client;

    servlet处理请求

    处理get请求

    • HelloForm servlet代码(只修改doGet方法其他不需要动):
    
    public class HelloForm extends HttpServlet {
        private static final long serialVersionUID = 1L;
    
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
    //      response.getWriter().append("Served at: ").append(request.getContextPath());
            
            // 设置响应内容类型
                    response.setContentType("text/html;charset=UTF-8");
    
                    PrintWriter out = response.getWriter();
                    String title = "使用 GET 方法读取表单数据";
                    // 处理中文
                    String name =new String(request.getParameter("name").getBytes("ISO8859-1"),"UTF-8");
                    String docType = "<!DOCTYPE html> \n";
                    out.println(docType +
                        "<html>\n" +
                        "<head><title>" + title + "</title></head>\n" +
                        "<body bgcolor=\"#f0f0f0\">\n" +
                        "<h1 align=\"center\">" + title + "</h1>\n" +
                        "<ul>\n" +
                        "  <li><b>站点名</b>:"
                        + name + "\n" +
                        "  <li><b>网址</b>:"
                        + request.getParameter("url") + "\n" +
                        "</ul>\n" +
                        "</body></html>");
        }
    
    }
    
    

    使用表单的 POST 方法实例

    • HelloPostForm servlet代码(只展示doGet和都Post方法其他不需要动):
        /**
         * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            // 设置响应内容类型
                    response.setContentType("text/html;charset=UTF-8");
    
                    PrintWriter out = response.getWriter();
                    String title = "使用 POST 方法读取表单数据";
                    // 处理中文
                    String name =new String(request.getParameter("name").getBytes("ISO8859-1"),"UTF-8");
                    String docType = "<!DOCTYPE html> \n";
                    out.println(docType +
                        "<html>\n" +
                        "<head><title>" + title + "</title></head>\n" +
                        "<body bgcolor=\"#f0f0f0\">\n" +
                        "<h1 align=\"center\">" + title + "</h1>\n" +
                        "<ul>\n" +
                        "  <li><b>站点名</b>:"
                        + name + "\n" +
                        "  <li><b>网址</b>:"
                        + request.getParameter("url") + "\n" +
                        "</ul>\n" +
                        "</body></html>");
        }
    
        /**
         * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
         */
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            // TODO Auto-generated method stub
            doGet(request, response);
        }
    
    • 在WebContent下创建post.html代码如下:
    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>post</title>
    </head>
    <body>
        <form action="servlet/hellopostform" method="POST">
            网址名:<input type="text" name="name"> <br /> 网址:<input
                type="text" name="url" /> <input type="submit" value="提交" />
        </form>
    </body>
    </html>
    
    • 运行post。html并输入点击提交可观察到 servlet处理结果;

    HttpServletResponse 响应

    • getWriter()方法,返回的是一个输出流
    • response.setContentType("text/html");
    • 编码:response.setCharacterEncoding("UTF-8");

    form表单提交到servlet的两种方法(action= “”)

    1. 相对路径

      1. action="servlet/helloform"输入web中配置的相对路径 (注意:开头没有/)
        image
      2. action="HelloForm"输入servlet中注解的相对路径 (注意:开头没有/) image
    2. 绝对路径 :action="test/servlet/helloform" 即:/项目名/相对路径

    Servlet中请求数据的传递、请求转发与页面跳转

    request的转向

    • RequestDispatcher.forward()方法:

      • forward是服务器请求资源,服务器直接访问目标地址的URL,把那个URL的响应内容读取过来,然后把这些内容再发给浏览器,浏览器根本不知道服务器发送的内容是从哪儿来的,所以它的地址栏中还是原来的地址。

      • 服务方(如:servlet)将请求转发到同一个WEB应用程序中另一个Servlet(或:JSP)--第三方 进行处理(该过程浏览器方-客户方并不知道),让这个第三方直接将结果返回给浏览器方

      • 通常在servlet中使用的代码是:
        request.getRequestDispatcher(跳转页面的Url).foward(request,response);

    • 有三种方法可以得到Request Dispatcher对象。

      • javax.servlet.ServletRequest的getRequestDispatcher(String path)方法;
        其中path可以是相对路径,但不能越出当前Servlet上下文。如果path以“/”开头,则解析为相对于当前上下文的根。

      • javax.servlet.ServletContext的getRequestDispatcher(String path)方法,其中path必须以“/”开头,路径相对于当前的Servlet上下文。
        可以调用ServletContext的getContext(String uripath)得到另一个Servlet上下文,并可以转向到外部上下文的一个服务器资源链接。

      • 使用javax.servlet. ServletContext的getNamedDispatcher(String name)得到名为name的一个Web资源,包括Servlet和JSP页面。这个资源的名字在Web应用部署描述文件web.xml中指定。

    使用:
    下面是一个应用的配置文件web.xml:

    其中定义了两个Servlet,名字分别为FirstServlet和SecondServlet,对应的类分别为org.javaresearch. redirecttest.ServletOne和org. javaresearch.redirecttest.ServletTwo。可以在浏览器中通过类似于下面的链接访问:
    http://localhost:8080/servlet/firstservlet/

    使用1中方法,例如在firstservlet可以写入下面的代码:
    RequestDispatcher rd = request.getRequestDispatcher("secondservlet");
    rd.forward(request, response);
    此时控制权将转向到第二个Servlet了。

    使用2中的方法,可以从Servlet Context中得到RequestDispatcher代码如下:

    RequestDispatcher rd = getServletContext().getRequest
    Dispatcher("/servlet/secondservlet");
    rd.forward(request, response);

    使用3中的方法,从上面的web. xml配置文件可以看到定义了两个Servlet,名字分别为FirstServlet和SecondServlet,所以可以得到命名的Dispatcher:
    RequestDispatcher rd = getServletContext().getNamedDispatcher("SecondServlet");
    rd.forward(request, response);
    这样也可以重定向到SecondServlet了。

    • sendRedirect()方法:
      • response.sendRedirect(跳转页面URL)

    就是服务端根据逻辑,发送一个状态码(Location ,状态码320),告诉浏览器重新去请求那个地址,一般来说浏览器会用刚才请求的所有参数重新请求,所以session,request参数都可以获取。

    服务方(如:servlet)直接将目标URL发回浏览器,让浏览器自己自动重新向目标URL发出HTTP请求。

    重定向是作为不同请求来看待的。

    • 区别比较:
    image image

    RequestDispatcher.forward()方法和HttpServletResponse.sendRedirect()方法的区别是:
    前者仅是容器中控制权的转向,在客户端浏览器地址栏中不会显示出转向后的地址;后者则是完全的跳转,浏览器将会得到跳转的地址,并重新发送请求链接。这样,从浏览器的地址栏中可以看到跳转后的链接地址。
    所以,前者更加高效,在前者可以满足需要时,尽量使用Request Dispatcher.forward()方法,并且,这样也有助于隐藏实际的链接。
    在有些情况下,比如,需要跳转到一个其它服务器上的资源,则必须使用HttpServletResponse.sendRequest()方法。

    servlet数据传递

    静态变量
    HttpServletResponse的sendRedirect()方法
    HttpServletRequest的getRequestDispatch()方法
    HttpServletRequest的getSession()方法
    HttpServletRequest的setAttribute()方法

    • 静态变量
      通过建立一个数据类来进行传递。

    案例:

    public class MyData{
    
        public static String data; //通过使用该类来实现数据传递
    
    } 
    
    • HttpServletResponse的sendRedirect()方法
      基本语法:
      response.sendRedirect("/Web应用名/资源名?uname="+username+"&pwd="+password);
      response.sendRedirect(“servlet的地址?参数名=参数值&参数名=参数值...”);

    • HttpServletRequest的getRequestDispatch()方法
      getRequestDispatch()方法是使WEB服务器从当前Servlet转发到当前应用下的另一个Servlet。
      基本语法:
      request.getRequestDispatcher(资源地址).forward(request,response);

    • HttpServletRequest的getSession()方法
      基本语法:
      1、放入session:request.getSession.setAttribute("loginUser",username);
      2、取出session:request.getSession.getAttribute("loginUser");
      PS:该方法可以传递对象

    相关文章

      网友评论

          本文标题:JavaEE学习笔记Day2

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