1 Java Web
本文将从最基础的HTTP协议开始讲起,介绍如何徒手搭建Web应用,内容如果比较多的话,后面会分成多篇逐步介绍。
2 皇冠上的明珠-Apache
不知道Apache的研发不是好的研发,若你的主语言是Java则更是如此。Apache事实上是很多技术标准的制定者和践行者。比如我们现在要说的Maven和Tomcat。
Tomcat是Web容器的一种,那什么是Web容器呢?
在上一篇文章中,我们提到Servlet。Servlet其实是Java语言的一部分,其给出了一个Web应用该如何处理HTTP请求并给出正确HTTP响应的框架。但Java本身并未给出一套完整的实现(至少在业界没有流行起来Java版本的Web容器),因此有很多公司和组织便根据Servlet标准开发了具体的实现。因为这些软件都是为Web应用服务,形形色色的Web应用都是运行在这些软件之上的,所以他们便被叫做Web容器。著名的有Tomcat、Jetty、GlassFish、JBoss、Resin、WebLogic、WebSphere……这些当中,有的好用,有的不好用;有的收费,有的不收费。我们所采纳的是Tomcat,因为它:1.由Apache基金会运营、2.免费、3.应用极其广泛;4.好用。
除了Tomcat之外,Java研发过程不可避免需要使用到Maven。Maven是一个仓库系统,你可以把你写好的代码编译成工具包丢上去供他人使用,也可以在上面找别人提供的工具包用在自己的工程中。对了,Maven也是Apache基金会运营的。
3 新建工程
到目前为止,徒手创建Web应用需要介绍的背景知识基本结束了。下面你可以选择你喜欢的IDE(IDEA或Eclipse)创建一个Maven工程,然后我们就可以开始了。
新建一个Maven工程
工程中创建的pom.xml文件,需要调整/新增部分内容。
<?xml version="1.0" encoding="UTF-8"?>
<project ...>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
</properties>
</project>
<packaging>war</packaging>
配置会强制工程按照WAR包结构进行打包编译,否则会被当成普通的Java工程,那么和Web应用相关的特性都将不会起效。另外在properties中增加编码格式约束以及编译相关信息。
4 Tomcat Maven Plugin
Tomcat Maven Plugin是Apache为Tomcat提供的一个Maven插件,方便开发人员直接在开发环境中调用Web容器,而不需要进行打包发布的操作。这样的好处是方便调试,而方便调试其实是提升开发效率的核心因素(但大家往往忽视它)。
修改工程中的pom.xml文件,引入Tomcat Maven Plugin插件:
<?xml version="1.0" encoding="UTF-8"?>
<project ...>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
</plugin>
</plugins>
</build>
</project>
5 调整目录结构
新建的Maven工程中,只包含了java和resources文件夹。java目录下面放的是源代码文件,resources文件夹下放的是配置文件。Web工程中还需要增加webapp文件夹,存放Web应用特有的相关文件。
调整目录结构
6 web.xml
web容器启动时,会扫描Web-INF下的web.xml文件,web.xml文件是web应用和web容器的沟通桥梁,容器会在该文件的指导下完成应用的加载。首先在webapp/WEB-INF文件夹中创建一个空的web.xml文件。
<?xml version="1.1" encoding="UTF-8"?>
<web-app 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"
version="3.0">
</web-app>
7 开发Web应用
在上一篇文章中提到,Web应用需要接收浏览器提交的HTTP请求并正确返回HTTP响应。所以需要编写一个Servlet
接口的具体实现。
在pom.xml文件中增加servlet-api的依赖,这样在源代码中就可以继承/实现Servlet
接口或其子类/子接口了。
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
引入了servlet-api包之后,创建一个名为MyServlet的类,用于处理HTTP请求。这个类直接获取response的writer对象,并写入字符串Hello Servlet!
。基于我们上一篇文章的分析,Web容器会将该字符串序列化到HTTP协议的报文体中,并返回给浏览器。浏览器在收到该响应后,会在页面上展示该字符串。
public class MyServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.print("Hello Servlet!");
}
}
8 最后的配置
下面我们修改下web.xml,将MyServlet类注入到Web容器中,这样Web容器就可以在收到特定请求后,调用我们的逻辑开始处理了。
<?xml version="1.1" encoding="UTF-8"?>
<web-app ...>
<servlet>
<servlet-name>web-application</servlet-name>
<servlet-class>org.example.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>web-application</servlet-name>
<url-pattern>/hello.do</url-pattern>
</servlet-mapping>
</web-app>
9 测试
启动应用,然后在浏览器中输入地址http://localhost:8080/WebApplication/hello.do,页面显示Hello Servlet!
字符串。
正常返回结果
使用抓包工具,可以看到服务器返回的HTTP响应报文的报文体中,Hello Servlet!
字符串。
HTTP协议中返回的信息
至此,简单的Web应用搭建完成,一切均和预想的一样!
10 结论
Web应用的处理流程比较复杂,但仔细梳理后,发现其实核心的逻辑很是清晰,用两篇文章的篇幅就能完成介绍。
虽然整个框架简单,但配合脚本执行、页面渲染等功能后,最终呈现的效果依然可以做到非常酷炫。这说明保持简单确实是设计的核心理念,而简单功能的叠加往往会达到出乎意料的效果。