【JavaEE】_servlet程序的编写方法

目录

1. 创建项目

2. 引入依赖

3. 创建目录结构

3.1 在main目录下创建一个webapp目录

3.2 在webapp目录下创建一个WEB-INF目录

3.3 在WEB-INF目录下创建一个web.xml文件

3.4 在web.xml中进行代码编写

4. 编写代码

4.1 在java目录下创建类

4.2 打印"hello world"

4.2.1 在服务器控制台上打印

4.2.2 在客户端打印

4.2.3 在新建类的首行添加注解

5. 打包程序

6. 部署程序

7. 验证

8. 总结

8.1 使用项目模板创建项目

8.2 使用IDEA的Tomcat插件自动打包

8.3 smart tomcat的工作原理

8.4 关于context path

8.5 404页面

8.6 405页面

8.7 500页面


Servlet是一种实现动态页面的技术,是一组tomcat提供的进行web开发API;

注:页面是分为动态页面与静态页面:

静态页面:页面内容始终固定不变,纯HTML;

动态页面:页面内容随输入参数的不同而改变,HTML+数据构成;

写一个Servlet程序,部署到tomcat上,通过浏览器访问得到一个"hello world"字符串:

该程序需要7个步骤:

1. 创建项目

此处需要创建一个maven程序了,maven是一个“工程管理”工具,其主要作用如下:

① 规范目录结构; ② 管理依赖(如处理使用的第三方库);③ 构建;④ 打包;⑤ 测试;

【JavaEE】_servlet程序的编写方法_第1张图片

注意查看maven的项目结构:

【JavaEE】_servlet程序的编写方法_第2张图片

2. 引入依赖

引入依赖即引入servlet对应的jar包;

首先进入maven仓库,搜索servlet:https://mvnrepository.com/

【JavaEE】_servlet程序的编写方法_第3张图片

选中maven,复制代码将其粘贴至pom.xml文件中:

【JavaEE】_servlet程序的编写方法_第4张图片

注意:

(1)复制粘贴的代码是不包含dependencies标签的,需要在project顶级标签下创建dependencies标签后,将复制来的代码粘贴至该标签内



    4.0.0

    org.example
    hello_servlet
    1.0-SNAPSHOT

    
        8
        8
    

    
        
        
            javax.servlet
            javax.servlet-api
            3.1.0
            provided
        

    


也把这一段配置称为该依赖在maven仓库的坐标; 

(2)首次使用时字体颜色为红色,说明尚未下载完成,一般只要粘贴进来,idea的maven就会自动刚出发依赖下载,下载结束后则不再是红色字体,如果长时间红色字体仍未变更,可在右侧面板进行强制刷新

【JavaEE】_servlet程序的编写方法_第5张图片

 【JavaEE】_servlet程序的编写方法_第6张图片

3. 创建目录结构

虽然maven已经帮助我们自动地创建了一些目录,但是还不够,此处需要使用maven开发一个web程序,还需要别的目录:

3.1 在main目录下创建一个webapp目录

(Directory)

【JavaEE】_servlet程序的编写方法_第7张图片

3.2 在webapp目录下创建一个WEB-INF目录

(方法同上)(Directory)

3.3 在WEB-INF目录下创建一个web.xml文件

(File)

创建完毕后的src目录结构如下:

【JavaEE】_servlet程序的编写方法_第8张图片

3.4 在web.xml中进行代码编写



    Archetype Created Web Application

这段代码可以视为固定代码,当前不需要进行调整;

注:(1)servlet程序和以往的代码相比,有一个非常大的区别:没有main方法;

servlet程序类似没有发动机的车厢,想要运行就要靠车头有带动,而tomcat就是车头;

将写好的servlet程序复制粘贴至webapps目录下,就相当于是把车厢挂到车头后了。

tomcat识别其webapps目录下哪些车厢需要靠车头带动,哪些不需要带动,就是靠目录下的WEB-INF/web.xml;

即:web.xml文件的作用是让tomcat能够识别的当前代码为webapp,并进行加载

(2)pom.xml的标红才是插件下载问题,web.xml文件的标红很有可能是idea的误判,判定代码是否正确的唯一方法是运行后查看结果;

4. 编写代码

4.1 在java目录下创建类

此处以HelloServlet为例:

【JavaEE】_servlet程序的编写方法_第9张图片

注:① HttpServlet类是servlet api里提供的现成的类,写servlet代码一般都继承该类,继承的主要目的是可以令新建的类针对HttpServelt进行功能扩展,通过重写父类方法的方式实现;

② doGet方法就是一个根据请求计算响应的方法,我们写的这个doGet方法,不需要我们进行手动调用,而是交给tomcat调用,当tomcat收到get请求,就会触发doGet请求

tomcat会构造好两个参数:req和resp,其中:

req就是TCP socket中读出的字符串按照HTTP协议解析得到的对象,这个对象中的属性与HTTP请求报文格式相对应,是tomcat针对请求已经解析好,构造好了的。

resp对象是一个空对象(不是null,只是new了个对象),程序员的任务就是在doGet方法内部实现:根据请求(req)计算响应(resp),resp本质上是一个输出型参数;

③ 在新类继承HttpServlet类后,输入doget并按下Tab键会自动生成一个默认格式,此时在方法内部有super.doGet(req,resp)语句,父类的doGet方法没有实际作用,只是返回了一个错误页面,故而这句需要注释掉

4.2 打印"hello world"

4.2.1 在服务器控制台上打印

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("hello world");
    }

4.2.2 在客户端打印

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("hello world");
    }

注:(1)此处的resp.getWriter会获取到一个writer对象,此处的writer对象是从属于resp对象的,此时进行的write操作其实是在往resp的body部分进行写入,等resp对象整个构造好了,tomcat会统一转成HTTP响应的格式,再写socket;

(2)java中分字节流与字符流两类,writer属于字符流的写操作。

流对象不不一定要写入网卡或硬盘,也可以写入内存缓冲区,取决于代码实现的细节;

4.2.3 在新建类的首行添加注解

在新建类首行增加@WebServlet("/hello")注解;

整体编写完毕的完整代码如下:

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;
@WebServlet("/hello")
// 令当前的HelloServlet类继承自HttpServlet类:
public class HelloServlet extends HttpServlet {
    @Override
//    重写HttpServlet类的doGet方法:
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 该语句只能实现在服务器的控制台中打印:
        System.out.println("hello world");
        // 在客户端实现打印:
        resp.getWriter().write("hello world");
    }
}

 注:(1)注解是java中的特殊类,注解可以针对一个类或放阿飞进行额外的解释说明,赋予这个类或方法额外的功能或含义

(2)此处WebServlet注解的作用是:把当前的类和一个HTTP请求的路径关联起来

(3)之前“doGet是tomcat收到GET请求的时候就会调用”这种说法其实并不准确,具体是否要调用doGet,还是得看当前GET请求的路径,不同的路径可以触发不同的代码(即关联到不同的类上);

(4)一个Servlet程序中可以有很多Servlet类,每个Serlet类都可以关联到不同的路径(对应到不同资源),因此此处的多个Servlet就实现了不同的功能

(5)路径与Servlet之间是一一对应的;

5. 打包程序

(1)打包程序即:把程序编辑好,得到一些.class文件(此例中只有一个文件,一个.java文件对应一个.class文件),将这些.class文件打成压缩包即可;

注:jar就是一种.class构成的压缩包,但此处要打的是war包;

① jar包只是一个普通的java程序;

war则是tomcat专属的用来描述webapp的程序

(2)借助maven直接点击即可:

第一步:点击右侧maven展开maven面板选中package,直接双击或右键运行均可:

【JavaEE】_servlet程序的编写方法_第10张图片

如果出现错误,则页面会显示具体的错误信息,如果运行一切顺利,则页面如下:

【JavaEE】_servlet程序的编写方法_第11张图片

第二步:打包完毕后,包会生成在target目录下,可在左侧目录栏查看:

【JavaEE】_servlet程序的编写方法_第12张图片

(3)默认情况下,maven打的是jar包,此处需要打war包,故而需要微调一下pom.xml:

点击pom.xml,在project顶级标签下,增加一个packaging标签和一个build标签:



    4.0.0

    org.example
    hello_servlet
    1.0-SNAPSHOT

    
        8
        8
    

    
        
        
            javax.servlet
            javax.servlet-api
            3.1.0
            provided
        

    

    war
    
        hello_servlet
    

其中,packaging标签就是描述打哪种包

build标签中嵌套一个finalName标签,该标签描述的是war包的名字,(可不指定,但默认生成的名字会较复杂);

此时重新操作maven的package选项,在左侧目录栏可见一个新生成的war包:

【JavaEE】_servlet程序的编写方法_第13张图片

注:这种手动打包和手动部署的操作也体现了开发与运行分离的思想,直接使用IDEA的三角符号进行运行是本地运行,而不是在另一个服务器上运行;

6. 部署程序

部署程序即:把刚打包好的war包拷贝到tomcat的webapps目录中即可

无论tomcat是在本机还是跨服务器,都是这样拷贝,拷贝完毕后启动tomcat即可;

注:(1)在windows环境下,如果tomcat正在运行,直接拷贝,tomcat也能识别,但是有可能存在bug。实际开发中,tomcat基本都是在linux上运行的,在linux上不存在bug。

(2)tomcat可以自动识别war包并进行解压缩

7. 验证

启动tomcat后,在浏览器中输入url,注意路径的写法:

【JavaEE】_servlet程序的编写方法_第14张图片

访问成功后页面如图:

【JavaEE】_servlet程序的编写方法_第15张图片

注:(1)在浏览器中输入url后,浏览器就偶早了一个对应的HTTP GET请求,发给了tomcat,tomcat根据第一级路径,确定了具体的webapp,根据第二级路径,确定了调用哪个类,再通过GET / POST方法确定调用HelloServlet的哪个方法:doGet或doPost等等;

(2)也可以在服务器代码处看到日志(tomcat处):

【JavaEE】_servlet程序的编写方法_第16张图片

8. 总结

上述步骤是使用Servlet最朴素的步骤,也可以通过一些操作来简化上述过程:

8.1 使用项目模板创建项目

时可以使用项目模板,后续则不必手动创建目录结构了;

但网络限制可能会导致模板下载不完整;

8.2 使用IDEA的Tomcat插件自动打包

1. 打包与部署程序可以使用IDEA的Tomcat插件,把Tomcat集成到IDEA中,省去手动打包与部署的过程,只需点击运行即可自动打包部署;

基于tomcat插件自动打包部署适用于开发阶段,频繁修改代码频繁验证;

手动打包手动部署适用于上线阶段,发布程序;

2. IDEA提供了一些API,可以让程序员开发插件,对IDEA的功能进行扩展;

3. tomcat插件的安装方式如下:

【JavaEE】_servlet程序的编写方法_第17张图片

4. 首次使用smart tomcat需要配置:

(1)点击页面右上角的Add Configuration新增一个配置:

【JavaEE】_servlet程序的编写方法_第18张图片

(2)设置tomcat所在路径:

【JavaEE】_servlet程序的编写方法_第19张图片

确定后可看到右上角界面新增的配置:

【JavaEE】_servlet程序的编写方法_第20张图片

(3)点击三角符号运行即可;

注:(1)IDEA社区版按照上述方式即可安装tomcat插件,IDEA专业版内置了Tomcat Server插件,和Smart Tomcat功能差不多,但不是一个插件,但Smart Tomcat使用更方便;

(2)如果由于网络问题在IDEA中无法直接安装插件,可以去IDEA官网进行下载:

【JavaEE】_servlet程序的编写方法_第21张图片

5. 正常情况下,点击运行后IDEA就会调用tomcat来运行程序了,但是当前代码启动失败:

【JavaEE】_servlet程序的编写方法_第22张图片

可通过cmd查看端口情况:

【JavaEE】_servlet程序的编写方法_第23张图片

可通过任务管理器(ctrl+shift+esc)查看进程Pid:

【JavaEE】_servlet程序的编写方法_第24张图片

关闭tomcat后再通过cmd查看8080端口情况:

即8080端口当前没有进程占用;

此时再运行smart tomcat,即可运行成功:

【JavaEE】_servlet程序的编写方法_第25张图片

按照原路径打开,即可显示hello world:

【JavaEE】_servlet程序的编写方法_第26张图片

注:(1)不要通过IDEA控制台上的地址访问页面:

【JavaEE】_servlet程序的编写方法_第27张图片

该链接不包含servlet path,直接点击访问是404页面

8.3 smart tomcat的工作原理

1. 查看tomcat的webapps目录下,并没有因为使用smart tomcat就重新生成一个war 包,原目录下的war包是先前使用tomcat打包的。

smart tomcat的工作原理不是自动拷贝war包,即webapps目录内不变,而是通过另一种方式启动tomcat。

2. tomcat支持启动时显式指定一个特定的webapp目录,相当于让tomcat加载单个webapp运行

tomcat直接调用tomcat,让tomcat加载当前项目中的webapp目录

这个过程没有打war包、拷贝、解压缩的过程。

3. 此时程序是可以正常运行,但像之前一些webapps下的一些已有的内容(如欢迎页面)就不存在了:

【JavaEE】_servlet程序的编写方法_第28张图片

8.4 关于context path

访问页面时在127.0.0.1:8080/后增加的第一级路径,

如果是使用tomcat,即直接拷贝war包的方式部署,context path就是war包名(目录名);

如果是smart tomcat的方式部署,context path是可以进行配置的,默认是项目名:

【JavaEE】_servlet程序的编写方法_第29张图片

8.5 404页面

布置servlet程序的过程较为繁琐,任何一步出现差错都会导致404页面,易错点有:

(1)url 的 context path 缺失或不匹配;

(2)url 的 servlet path 缺失或不匹配;

(3)web.xml文件内容错误;

(4)webapp没有正确部署;

(5)目录结构以及目录名、文件名错误;

8.6 405页面

405页面表示对应的HTTP方法未实现:

第一种情况:

比如浏览器发了GET请求,但代码中没有重写doGet,就会出现405页面;

在当前HelloServlet.java中注释掉doGet方法后运行,再输入url访问页面就会出现405页面:

【JavaEE】_servlet程序的编写方法_第30张图片

第二种情况:

super.doGet()没有注释掉,运行后再按照原url访问页面,也会出现405页面:

【JavaEE】_servlet程序的编写方法_第31张图片

因为super.doGet方法的内部实现就是返回405页面:

【JavaEE】_servlet程序的编写方法_第32张图片

8.7 500页面

500页面常常是由于Servlet程序抛异常导致的,出现500页面时,日志会明确说明异常调用栈;

比如运行以下代码:

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;

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String s = null;
        System.out.println(s.length());
    }
}

刷新页面:

【JavaEE】_servlet程序的编写方法_第33张图片

注:还有一些其他的出错情况,如:

(1)空白页面:

如果没有写resp.getWriter().writre()方法,即没有给前端返回任何东西,就会出现空白页面;

(2)无法访问此网站:

没有启动tomcat,按原url访问页面就会提示无法访问此网站;

你可能感兴趣的:(JavaEE,java-ee,servlet,java,intellij-idea,maven,tomcat)