• feitian
    2019-05-20
    既然是纯手工,就应该把servlet那套完整的写出来,不应该再用tomcat容器而应该手写实现tomcat的核心代码。最核心的应该是类似HttpServlet功能的实现,把这个从最初的servlet接口实现了才算讲透,不然还是有点和稀泥的感觉。我觉得应该按照这种思路讲会更好,请参考我写的mytomcat,https://github.com/feifa168/mytomcat
     9
     115
  • darren
    2019-05-18
    发现xml与注解不能同时起作用,那在用xml方式的老项目中就没办法使用注解的方式了吗?

    作者回复: web.xml 和注解可以同时工作的。

    例子里的web.xml和注解不能同时工作的原因是web.xml中的配置metadata-complete="true", 你需要把它设置成metadata-complete="false"。

    metadata-complete为true的意思是,告诉Tomcat不要去扫描Servlet注解了。

    
     11
  • 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

    
     10
  • Amanda
    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不包括中文字符。

    
     9
  • allean
    2019-05-18
    IDE和框架诞生之初是为了让程序员从繁琐的底层配置中抽离出来专注于业务开发,然而大多数人在享受IDE和框架带来的便捷时,也成了温水里的青蛙,对于实现原理认识模糊,渐渐沦落为一个CRUD,这不是一件好事,啊~幡然醒悟
    
     9
  • youknowmjj
    2019-05-19
    @Amanda 不知道怎么直接回复你,我跟你一样也是遇到乱码的问题。我也设置了response.setCharacterEncoding(utf8),在getWriter之前,但依然是一样的乱码。
    原因在与javac编译生成的class文件是用的gbk的编码。换句话说,你生成的class源文件就已经是中文乱码了。
    所以在javac的时候加上 -encoding UTF-8就好了。
    ps:我是Windows的环境。
    
     5
  • 今夜秋风和
    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。

    
     5
  • 风翱
    2019-05-18
    可以利用工具,例如postman。 也可以编写代码,利用http的post方法去调用。 或者像楼上所说的不管通过get还是post都通知转发到doPost中。
    
     4
  • 吃饭饭
    2019-09-26
    分享一个编译源码的帖子:https://mp.weixin.qq.com/s/wp1LZcdK2eLRZU3HlubW9w
    
     2
  • Geek_0db340
    2019-05-18
    表单提交method=post 就可以啦
    
     2
  • KL3
    2019-05-18
    把业务逻辑写在dopost里,然后doget方法调用dopost方法
    
     2
  • 熊斌
    2019-11-17
    按老师的步骤操作,结果一致,开心!
    整个过程遇到以下几个问题,记录一下,如果有遇到同样问题的小伙伴可以借鉴下解决问题的思路(大神可以略过):

    首先说明一下我的运行环境:
    操作系统:win10
    Tomcat版本:apache-tomcat-9.0.27(免安装版本)
    JDK版本:jdk-13.0.1(免安装版)

    问题1:javac失败
    原因&解决方案:未配置系统环境变量,在系统环境变量path中,加入E:\xxx\jdk-13.0.1\bin,问题解决;

    问题2:脱离IDE,新建MyServlet.java,执行文章中的javac命令失败
    原因&解决方案:按文章中的命令原封不动执行的话,java源文件需要建到tomcat的lib目录下,否则会导包失败。然后在lib目录下,shift+右键(在此处打开命令窗口)打开cmd窗口,执行成功,生成了MyServlet.class

    问题3:tomcat startup.bat执行一闪而过(如果一闪而过,说明没启动成功,拿文中的http://localhost:8080/MyWebApp/myservlet 访问的话什么都没有)
    原因&解决方案:按照https://blog.csdn.net/scau_lth/article/details/83218335 文章中,第二点方案得以解决。

    问题4:访问http://localhost:8080/ 成功跳转tomcat主页,访问http://localhost:8080/MyWebApp/myservlet 404(这种情况一般就是容器启动加载你的应用失败,需要根据日志具体分析是哪块的问题)

    原因&解决方案:查看apache-tomcat-9.0.27\logs 目录下的日志发现,17-Nov-2019 22:19:40.620 信息 [main] org.apache.catalina.startup.HostConfig.deployDirectory 把web 应用程序部署到目录 [F:\workspace\apache-tomcat-9.0.27\webapps\MyWebApp]
    17-Nov-2019 22:19:40.674 严重 [main] org.apache.tomcat.util.digester.Digester.fatalError Parse fatal error at line [2] column [6]
        org.xml.sax.SAXParseException; systemId: file:/F:/workspace/apache-tomcat-9.0.27/webapps/MyWebApp/WEB-INF/web.xml; lineNumber: 2; columnNumber: 6; 不允许有匹配 "[xX][mM][lL]" 的处理指令目标。

    Context [/MyWebApp] startup failed due to previous errors
    我的web.xml是直接从文章中拷贝的,复制粘贴时多了空格,修改后启动成功

    修改后保存,容器会重新加载,看日志你会发现Context with name [/MyWebApp] is completed
    再次使用http://localhost:8080/MyWebApp/myservlet 浏览器访问时会看到结果 MyServlet
    展开
     1
     1
  • 业余爱好者
    2019-06-18
    “javac -cp ./servlet-api.jar MyServlet.java”执行报错:
    "MyServlet.java:16: 错误: 编码GBK的不可映射字符
            System.out.println("MyServlet 鍦ㄥ鐞? get锛堬級璇锋眰...");"
    换成:“javac -encoding UTF-8 -cp ./servlet-api.jar MyServlet.java”解决。百度搬运工。。
    
     1
  • 桔子
    2019-05-31
    李老师,doGet方法的request和response的初始化代码在哪里呢,只知道是servlet容器创建的,但是去哪里可以看到容器初始化response的源码呢。

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

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

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

    
     1
  • kmmshmily
    2019-05-23
    这个demo 大学期间一直这样写啊 最后才用Spring的
    
     1
  • 清风
    2019-05-22
    注解是高版本的Servlet才支持的吧,好像是2.5以上

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

    
     1
  • Howard
    2019-05-22
    代码放在github上需要注意开源协议,像apache这种协议明确说明受美国出口管制的
     1
     1
  • 张济增
    2019-05-20
    看着前几章跟 head first servlet jsp差不多,先来个基础
    
     1
  • Geek_bde3dc
    2019-05-18
    最简单的办法就是在doGet里调用doPost😁
    
     1
我们在线,来聊聊吧