记一次手动创建 servlet java web 项目

如果高手翻到这篇文章,请忽略它。内容很简单,可能还不太透彻,写的也很啰嗦。小白可以姑且看下,如果觉得谬论太多,也请忽略。

前几天在 zhi hu 上看到一个话题回答,观点是说:学习java web 不应该直接从 spring boot 等框架着手,而是先学习 Servlet,框架实则是对技术进行了封装,虽使初学者容易上手,但少了份明白。我当时挺有感触的,自己”打怪升级“正好遇到了”过滤器“和”拦截器“,自然扯出了 servlet,”IDEA + spring 框架 + 平时工作大多是业务逻辑“ 这样的场景下,即使我不懂 servlet,也能 hold 住绝大部分工作。但就个人技术积累而言,若只熟练使用框架写业务逻辑,虽然谈不上浪费时间,但也有温水煮青蛙的味道。

《Head first Servlet & jsp》很适合小白读一读,语言通俗,有上下文,还配有插图,有这些东西,就很容易理解场景了。目前的建议就是小白刚看的时候别怕麻烦,照着书上的代码动手敲敲。当然在网上也能找到别人已经敲好的工程,粘贴复制能节省很多功夫。这里衷心提醒下:别人的代码小心坑的你爹妈都不认识。 有个被坑惨的人正在写博客…。最后是从 《Java Server-Side Programming:Java Servlets》,完成了我的第一个手动 Servlet 工程。

1. Servlet 和 Tomcat

servlet 是什么?它是协议?还是个程序?这个问题在网上能搜到好多回答,看这些回答时还会扯出别的概念,有时候自己都快看糊涂了。我目前的理解是(当然后面可能会变,但不影响使用):Servlet 是个协议,是个规范,任何基于这个规范开发的程序就能作为”物理服务器“(物理主机)上的一个”服务器程序“(软件程序),用来接收客户端的请求并返回响应。这里解释下我描述的”服务器程序“和”普通程序“有什么区别:”服务器程序“是说这个软件程序可以接受 HTTP 请求并返回响应。在物理主机上执行 sleep(1000) ,这是个”普通程序“,它就不能响应 http 请求,同样的 vi 也是”普通程序“,不过经常把这些叫”命令“或”工具“。纠结这些有用么,个人觉得不应该深究,但稍微理解清楚一些,有助于后面的学习和实际开发。

tomcat 是 Apache 公司 java 语言开发的一款服务器程序并将其开源了。tomcat 专门用来与 java 应用程序”配合“起来处理浏览器的请求。(怎么”配合“,下面会讲)。tomcat 是 java 开发的,那有没有别的语言开发的?有!Python Servlet Engine 是基于 python 开发的并遵循 servlet 规范,同上,它是和 python 应用程序配合使用的,不过这个东西是内置在 Python 里的,不需要单独部署。

四个小问题,解释 servlet 和 tomcat 的关系。

2. 简单描述下 Tomcat 到底做什么用的

上面说道 tomcat 是个软件,它的安装和启动网上一大把资料,这里就不再赘述了。”服务器软件“、”服务器程序“、”Web服务器“这三个名词都可以理解为 tomcat。因为浏览器只认识 web 服务器。如果浏览器要简单地获取 tomcat 里面某个路径下的静态资源(文本文件、视频、图片),那浏览器通过指定对应的资源路径就可以直接 GET 拿到。但如果浏览器需要 tomcat 对请求做一些计算呢(获取动态资源,比如查数据库),此时 servlet 就满足不了了。因为 tomcat 会提供东西,但对提供的东西不做任何计算。

那这怎么办呢?

物理服务器上有另外一个 java 辅助应用程序,它能处理一些计算任务(这另外的应用,就是我们平时开发的程序)。tomcat 负责把请求”交给“(交给这个动作通过 tomcat 里面的 servlet 接口完成的)适合的辅助应用(这些辅助程序应用也有个名字,叫 java web 应用),然后在取得这个应用的响应,并把它发回给浏览器。实际上浏览器根本不知道有些工作是别人做的。

所以这里是 tomcat 和辅助应用两个程序 ”配合“ 处理了浏览器请求。Spring Boot 之所以能直接启动并且响应请求,是因为 Spring boot 里面内置了tomcat并且配置妥当。

至于 tomcat 是怎么把请求 ”交给“ 辅助程序的,这里有个视频,简单描述了”交给“ 的实现过程,刷一遍,不吃亏。

建议全刷一遍,时间少的,可以刷后面三节

3. 创建 hello world 辅助应用

3.1 目录结构介绍

安装好 tomcat 后,所有的 java web 应用都放在 tomcat下的 webapps 目录下。java web 标准的文件目录结构如下图所示。
在这里插入图片描述

这是最全乎的模样,其中 WEB-INFsrclibclasses 三个目录分别存放,java 程序源文件依赖的 jar 包编译后的 class 文件web.xml 这个是配置文件、也叫 DD 文件(Deployment Descriptor file)META-INFO 可以没有,其他的都是静态文件,需要什么自己添。

hello world 项目的目录结构长这个样子:

helloservlet
└── WEB-INF
    ├── classes
    │   └── mypkg
    │       └── HelloServlet.class
    ├── src
    │   └── mypkg
    │       └── HelloServlet.java
    └── web.xml

3.2 创建 HelloServlet.java

package mypkg;
 
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
 
public class HelloServlet extends HttpServlet {
   @Override
   public void doGet(HttpServletRequest request, HttpServletResponse response)
               throws IOException, ServletException {
      // Set the response message's MIME type
      response.setContentType("text/html;charset=UTF-8");
      // Allocate a output writer to write the response message into the network socket
      PrintWriter out = response.getWriter();
 
      // Write the response message, in an HTML page
      try {
         out.println("<!DOCTYPE html>");
         out.println("<html><head>");
         out.println("<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>");
         out.println("<title>Hello, World</title></head>");
         out.println("<body>");
         out.println("<h1>Hello, world!</h1>");  // says Hello
         // Echo client's request information
         out.println("<p>Request URI: " + request.getRequestURI() + "</p>");
         out.println("<p>Protocol: " + request.getProtocol() + "</p>");
         out.println("<p>PathInfo: " + request.getPathInfo() + "</p>");
         out.println("<p>Remote Address: " + request.getRemoteAddr() + "</p>");
         // Generate a random number upon each request
         out.println("<p>A Random Number: <strong>" + Math.random() + "</strong></p>");
         out.println("</body>");
         out.println("</html>");
      } finally {
         out.close();  // Always close the output writer
      }
   }
}

3.3 编译 .java 文件

这里将编译后的 class 文件放到 classes 路径下,两种方式:第一种,在 .java 文件目录下编译好再拷贝过去,第二种,编译时直接指定到 classes 目录下。这里采用第二种。

# 站在 WEB-INFO 路径下执行这条命令
javac -cp ~/Documents/servlet/apache-tomcat-9.0.40/lib/servlet-api.jar -d classes src/mypkg/HelloServlet.java
  • -cp : 指定 java 程序源文件依赖的库,javax.servlet.http.* 依赖的 jar 包在 servlet 的 lib 中。
  • -d: 指定编译后的 class 文件输出的路径。指定到 classes,编译时会自动补齐包路径。
  • src/mypkg/HelloServlet.java : 最后指定原文件所在路径。

3.4 配置 web.xml 文件

配置这个的目的是为了将浏览器上特定的 url 和 java web 程序对应的类映射起来。这里将 url:/sayhellomypkg.HelloServlet.class 映射起来,通过http://hostname:port/helloservlet/sayhello 就可以访问到 HelloServlet。

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app version="3.0"
  xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
 
  <!-- To save as <CATALINA_HOME>\webapps\helloservlet\WEB-INF\web.xml -->
 
   <servlet>
      <servlet-name>HelloWorldServlet</servlet-name>
      <servlet-class>mypkg.HelloServlet</servlet-class>
   </servlet>
 
   <!-- Note: All <servlet> elements MUST be grouped together and
         placed IN FRONT of the <servlet-mapping> elements -->
 
   <servlet-mapping>
      <servlet-name>HelloWorldServlet</servlet-name>
      <url-pattern>/sayhello</url-pattern>
   </servlet-mapping>
</web-app>

在这里插入图片描述

3.5 启动 tomcat 测试效果

在 tomcat 的 bin 路径下执行 ./startup.sh 命令。

在浏览器出入:http://localhost:8080/helloservlet/sayhello

效果:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值