设为首页 收藏本站
查看: 919|回复: 0

[经验分享] 图解 & 深入浅出 JavaWeb:Servlet必会必知

[复制链接]

尚未签到

发表于 2017-3-1 10:26:42 | 显示全部楼层 |阅读模式
  Writer      :BYSocket(泥沙砖瓦浆木匠)
  微         博:BYSocket
  豆         瓣:BYSocket
  FaceBook:BYSocket
  Twitter    :BYSocket
  “眨眼间,离上一篇写技术博文时隔1个月。怕自己真的生疏了,都是备案太慢惹得。哈哈,继续high~ ”
  从[JavaEE 要懂的小事] Http相关 ,一直想写点Web开发相关的。最近项目接口开发紧,还有准备新的九月份战斗。JDK IO源码就隔一段落,温故知新看看Servlet & JSP 相关。把自己基础累积回顾一遍,并和大家分享分享一些心得和代码。这里应该涉及到一部分源码,开发思想和一些手工做出的图。喜欢java,或者有一定Java开发经验的多提宝贵意见。
一、Web服务器
  从事web开发的人,会很清楚一个东西叫HTTP服务器,比如JEE开发—TomcatJetty,.NET开发—ISS等。HTTP服务器是使用 HTTP(超文本传输协议) 与客户机浏览器进行信息交流。下面就是HTTP服务器简单交互图:(来自[JavaEE 要懂的小事] Http相关 博客)
   DSC0000.png
  HTTP服务器Web服务器的一种,也是开发最常见的,自然还有其他方式进行信息交互,比如FTP文件服务器
  Web服务器是可以向发出请求的浏览器提供文档的程序。其核心过程为
  连接过程 — 请求过程 —应答过程 — 关闭连接
  这让我想到了Tomcat架构的一张图:
DSC0001.gif

二、Tomcat 简单说几句
  如图,Tomcat 包含了核心服务模块:Connector连接模块 和 Container 容器。Tomcat Server 核心是一个Servlet/JSP Container。对每一个HTTP请求,过程如下
  — 获取连接
  — Servlet来分析请求HttpServletRequest
  — 调用其service方法,进行业务处理
  — 产生相应的响应HttpServletResponse
  — 关闭连接
  如图:
DSC0002.png

  蓝色线指向过程是请求,绿色线指向过程是响应过程。也就是上面Web服务器核心过程:“连接过程 — 请求过程 — 应答过程 — 关闭连接
三、我第一个Servlet
  什么是Servlet?(每次都会不停的问自己,这是什么“What”?紧接着应该是什么用“How”吧)
  在 JavaEE 6文档中,介绍如下
  “Servlet 是运行在Web服务器的Java小程序。Servlet可以获取并针对Web客户端的请求作出响应。一般情况下,通过HTTP,即超文本传输协议,进行传输通信。”



?


A servlet is a small Java program that runs within a Web server. Servlets receive and respond to requests from Web clients, usually across HTTP, the HyperText Transfer Protocol.
  所以,Servlet 是Web服务器核心工作的抽象。它不单单只是实现HttpServlet,可能实现有FtpServlet(这个我猜的)等。相对较多的Web开发,知道的肯定是HttpServlet。
  在 JavaEE 6文档中,是这样介绍HttpServlet
  “HttpServlet 提供了一个能被继承后创建一个适应Web网站的Http Servlet的抽象类。”



?


Provides an abstract class to be subclassed to create an HTTP servlet suitable for a Web site.
  光说不练假把式,练一个“Hello,Servlet/JSP World!”:



?


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;
/*
* Copyright [2015] [Jeff Lee]
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* @author Jeff Lee
* @since 2015-6-25 19:46:45
*  HelloWrold案例
*/
@WebServlet(urlPatterns = "/helloWorld.html")
public class HelloWorldServletT extends HttpServlet{
     
    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException{
        // 获取输出打印对象
        PrintWriter out = resp.getWriter();
        out.println("Hello,Servlet/JSP World!");
    }
}
  右键该HelloWorldServletT.java文件 — Run As — Run On Server — 选择Tomcat服务器 — Finish即可
   DSC0003.png
   DSC0004.png
  等待片刻,你可看到网页上如下输出。这就是客户端从HttpServlet获取到的响应:
DSC0005.png

  休息一下吧~ 看看小广告:
  开源代码都在我的gitHub上哦 — https://github.com/JeffLi1993
三、分析源码



?


@WebServlet(urlPatterns = "/helloWorld.html")
  @WebServlet 注解用于声明一个HttpServlet的配置。其中,urlPatters = “/helloWorld.html”,urlPatterns复数形式,说明至少一个URL必须被申明。它和另一个value必须存在一个,但不能同时存在。如果要匹配多个URL路径的话,如下:



?


@WebServlet(urlPatterns = { "/helloWorld01.html", "/helloWorld02.html" }
  下面有个@Override,重写了父类HttpServletdoGet方法。我们先看看父类HttpServlet。HttpServlet是一个抽象类,它提供了以下方法:
  — doGet  , 服务于 HTPP GET 请求
  — doPost , 服务于 HTTP POST 请求
  — doPut  , 服务于 HTTP PUT 请求
  — doDelete,服务于 HTTP DELETE 请求
  …
  如图:
DSC0006.png

  对于不同请求,HttpServlet的子类必须相应的实现至少一个方法,通常来说,会是其中一个,这样代码比较清晰。那父类的doGet方法做了什么工作呢?



?


protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException
    {
        String protocol = req.getProtocol();
        String msg = lStrings.getString("http.method_get_not_supported");
        if (protocol.endsWith("1.1")) {
            resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, msg);
        } else {
            resp.sendError(HttpServletResponse.SC_BAD_REQUEST, msg);
        }
    }
  这里就简单的获取了下HTTP协议及Http Local信息,然后可以协议是否是1.1,做出分别是405或者400HTTP状态码的响应。
  回到HelloWorldServletT.java 这里:



?


@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
    // 获取输出打印对象
    PrintWriter out = resp.getWriter();
    out.println("Hello,Servlet/JSP World!");
}
  表示该HelloWorldServletT会接受Http GET请求,并OOM到HttpServletRequest,并执行里面的逻辑代码和返回响应。 这里从HttpServletResponse对象中获取到输出打印对象PrintWriter,然后输出了“Hello,Servlet/JSP World!”。
  完毕!哦还有一点补充补充补充:
  print,这里还好一句话。如果打印个table会很麻烦,因此有一个JSP的东西出现了,是Servlet的HTML化身。
五、深入Servlet 具体过程
  又回到这个简单的 Get Servlet代码:



?


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

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException{
        // 获取输出打印对象
        PrintWriter out = resp.getWriter();
        out.println("Hello,Servlet/JSP World!");
    }
}
  这过程总结如下:
  — 从浏览器(Client)获取连接”/helloWorld.html”
  — Tomcat Connector模块将请求(Request)传递给 Container模块
  — Container 模块会做以下事情
  —— 分析HTPP请求信息,组装成HttpServletRequest对象
  —— 创建新的HttpServletResponse对象
  —— 根据路由配置,搜索相应的Servlet,并创建一个线程用于处理本次请求。此时线程会将上面RequestResponse对象的索引传递给Servlet
  — 新线程中的Servlet处理逻辑
  — 线程结束后,通过HttpServletResponse对象的PrintWriter,返回浏览器一个信息
  过程图如下:
DSC0007.png

  蓝色线指向过程是请求,绿色线指向过程是响应过程,橙色线指向过程是内部处理过程。
  有些面试题会这样问:
  Servlet是线程安全的吗?
  不是,一个servlet实现类只会有一个实例对象,多个线程是可能会访问同一个servlet实例对象的,线程安全问题都是由全局变量静态变量引起的。
  因此,Servlet对象实例化是在以第一次请求此Servlet时,如果访问后,实例对象存在内存中,只会在服务器停止时,它才会消失。它不会随着各个线程结束而结束。因此下次访问Servlet时,Servlet Container会搜索相应的Servlet,如果不存在Container新建相应的Servlet。这也是我们想要的结果。
六、小结
  发现这一博客写的太多,回头一看。可以写成三个文章了。言归正传本文要点如下
  1、简单介绍Web服务器 及 Tomcat容器
  2、第一个Sevlet的开发及使用
  3、深入源码及api介绍使用
  4、总结一次请求及响应的真实过程
5、欢迎点击我的博客及GitHub — 博客提供RSS订阅哦

———- http://www.bysocket.com/ ————- https://github.com/JeffLi1993 ———-


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-348699-1-1.html 上篇帖子: 如何快速掌握一门新技术/语言/框架... 下篇帖子: Nodejs课堂笔记-第四课 Dynamodb为何物
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表