04 | 实战:纯手工打造和运行一个Servlet

2019-05-18 李号双
《深入拆解 Tomcat & Jetty 》
课程介绍


讲述:李号双

时长:大小8.16M


作为 Java 程序员,我们可能已经习惯了使用 IDE 和 Web 框架进行开发,IDE 帮我们做了编译、打包的工作,而 Spring 框架在背后帮我们实现了 Servlet 接口,并把 Servlet 注册到了 Web 容器,这样我们可能很少有机会接触到一些底层本质的东西,比如怎么开发一个 Servlet?如何编译 Servlet?如何在 Web 容器中跑起来?
今天我们就抛弃 IDE、拒绝框架,自己纯手工编写一个 Servlet,并在 Tomcat 中运行起来。一方面进一步加深对 Servlet 的理解;另一方面,还可以熟悉一下 Tomcat 的基本功能使用。
主要的步骤有:
1. 下载并安装 Tomcat。
2. 编写一个继承 HttpServlet 的 Java 类。
3. 将 Java 类文件编译成 Class 文件。
4. 建立 Web 应用的目录结构,并配置web.xml。
5. 部署 Web 应用。
6. 启动 Tomcat。
7. 浏览器访问验证结果。
8. 查看 Tomcat 日志。
下面你可以跟我一起一步步操作来完成整个过程。S...

展开全文
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。

精选留言

  • darren
    2019-05-18
    发现xml与注解不能同时起作用,那在用xml方式的老项目中就没办法使用注解的方式了吗?

    作者回复: web.xml 和注解可以同时工作的。 例子里的web.xml和注解不能同时工作的原因是web.xml中的配置metadata-complete="true", 你需要把它设置成metadata-complete="false"。 metadata-complete为true的意思是,告诉Tomcat不要去扫描Servlet注解了。

    
    57
  • 不负
    2019-05-18
    老师,实践中发现个问题:虽然response.setContentType("text/html;charset=utf-8"),但是out.println中有输出中文还是乱码的

    作者回复: 调下顺序,像下面这样: response.setContentType("text/html; charset=utf-8"); PrintWriter out = response.getWriter(); getWrite的源码如下: ------ public PrintWriter getWriter() throws IOException { if (usingOutputStream) { throw new IllegalStateException (sm.getString("coyoteResponse.getWriter.ise")); } if (ENFORCE_ENCODING_IN_GET_WRITER) { /* * If the response's character encoding has not been specified as * described in <code>getCharacterEncoding</code> (i.e., the method * just returns the default value <code>ISO-8859-1</code>), * <code>getWriter</code> updates it to <code>ISO-8859-1</code> * (with the effect that a subsequent call to getContentType() will * include a charset=ISO-8859-1 component which will also be * reflected in the Content-Type response header, thereby satisfying * the Servlet spec requirement that containers must communicate the * character encoding used for the servlet response's writer to the * client). */ setCharacterEncoding(getCharacterEncoding()); } usingWriter = true; outputBuffer.checkConverter(); if (writer == null) { writer = new CoyoteWriter(outputBuffer); } return writer; } ----- 你看注释里它说:如果调这个方法之前没有指定Response的字符编码,就用默认的ISO-8859-1,ISO-8859-1不包括中文字符。

    共 2 条评论
    32
  • Monday
    2019-05-18
    1、postman 2、curl 命令发送post 3、用HttpClient发送 周六早上坚持打卡,本章节绝大多数知识以前有接触过,只有@WebServlet注解是新知识,现在业务开发一般都是写SpringMVC容器中的Controller来代替类似文中的Servlet类。 问题:基于Spring+SpringMVC+Mybais的框架搭建的项目,平常开发的都是写Controller与Service、DAO。 1、请问Servlet容器只管理DispatchServlet这一个Servlet吗? 2、有什么可视化工具可以直接查看各种容器中管理的对象吗? 谢谢!

    作者回复: 1. 你可以向Servlet容器注册多个Servlet。 2. 你看这个有没有帮助 https://github.com/spring-projects/spring-framework/issues/14296

    共 2 条评论
    18
  • 蓝士钦
    2019-06-13
    课后思考: 访问doPost()方法有两种方式 1. 使用postMan等工具发起post请求 2. 在代码中doGet()方法去调用doPost() 疑问: doGet和doPost其实在网络层没有任何区别,通过浏览器地址栏中发起的是get请求,get请求其实也能携带像post请求一样的请求体参数,具体区别其实是不同浏览器和服务器实现方式的区别。 常见的面试题很喜欢考post和get的区别,之所以区分get和post是为了http协议更加解耦吗?就像业务拆分一样专职专工

    作者回复: get和post的重要区别是,前者不能改变服务端的数据,是幂等;而Post可以改变服务端数据。

    
    11
  • 今夜秋风和
    2019-05-18
    老师,验证的时候默认增加了 super.doGet(req, resp);在http1.1写一下不能工作,查看httpServlet 源码里面 对协议做了限制,http 1.1 协议默认不支持。这个为什么是这样设计的呢? 源代码: 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); } 第二个是如果是那个注解访问的,可以不用删除web.xml,把web.xml里面的url-pattern 改成注解同样的路由,也可以支持;如果web.xml 路由自定义一个的话,测试发现自定义的会有404,是不是注解的路由优先级会更高呢? 3.如果把web.xml删除,servlet容器启动的时候是不是会自动扫描注解类,将它注册到容器中?
    展开

    作者回复: super.doGet(req, resp); 调的是HttpServlet的doGet方法,但是这个doGet需要你去实现的。 HttpServlet的service方法会调doXXX方法,并且HttpServlet里的各种doXXX方法的默认实现都是直接返回错误。 为什么HttpServlet要这样设计呢?这是因为它需要做一个限制:程序员要么重写HttpServlet的service方法,要么重写HttpServlet的doXXX方法。 web.xml和注解可以同时工作,你需要把web.xml中的metadata-complete="true"设置成false。 Tomcat启动时会扫描注解,同时记下Servlet的名字和映射路径,如果你设置了延迟记载Servlet,通过浏览器访问时Tomcat才会加载和实例化Servlet。

    
    9
  • 桔子
    2019-05-31
    李老师,doGet方法的request和response的初始化代码在哪里呢,只知道是servlet容器创建的,但是去哪里可以看到容器初始化response的源码呢。

    作者回复: 在Tomcat中CoyoteAdapter类的service方法里

    
    5
  • Geek_ebda96
    2019-05-23
    李老师,请教一个问题,你这里所说的servlet和spring mvc里面的controller是什么关系,servlet里面可以直接接收请求,处理请求业务,controller只是通过dispatch servlet再接入进来的?

    作者回复: 你说的没错,具体是这样的 Tomcat的Wrapper组件-Filter-DispatcherServlet-Controller

    
    5
  • 清风
    2019-05-22
    注解是高版本的Servlet才支持的吧,好像是2.5以上

    作者回复: Servlet3.0开始支持

    
    4
  • 郑童文
    2019-05-20
    请问老师: 我们在servlet的实现类中import的是javax.servlet.http.HttpServlet 请问为什么需要Tomcat的servlet-api.jar呢?难道javax.servlet.http.HttpServlet这个类不是jdk中的吗?谢谢!

    作者回复: JDK不带Servlet Jar包。

    
    4
  • 逆流的鱼
    2019-05-18
    用Tomcat实现servlet,总感觉哪里不对

    作者回复: 😑

    
    2