搭建 Java Web 开发环境需要以下部分
Tomcat 由于其免费、开源、效率较高,是目前最受欢迎的中小型 web 项目的服务器。还有一个很重要的原因是 Tomcat 实现了 Servlet 和 JSP。既然 Tomcat 实现了 J2EE 的部分规范,那不同的 Tomcat 版本支持的规范的版本是什么样的呢?可见 whichversion(下文也有截图)。相应的 Servlet 、JSP 不同版本的规范具体内容可见 Specifications。
The Apache Tomcat software is an open source implementation of the Java Servlet, JavaServer Pages, Java Expression Language and Java WebSocket technologies. The Java Servlet, JavaServer Pages, Java Expression Language and Java WebSocket specifications are developed under the Java Community Process.
from https://github.com/apache/tomcat
MAC 安装 Tomcat
安装完成后可看到 mac 中的 Tomcat 目录:
Tomcat 目录内容:
其实在没有 IDE 之前,程序员都是通过文本编辑器直接开发的(未做真实考证,大概率是这样,仅用来帮助大家抓住本质,理解包含源代码的项目目录结构和可在 Tomcat 上部署运行的项目目录结构之间的区别及联系,下文会介绍),开发的项目也是直接放在 Tomcat 安装目录下的 webapps 目录的。具体创建 Java web 项目的过程可见如下视频:
文本编辑器创建 web 项目
最终创建的 Java web 项目的目录结构如下所示。从视频也可以看出,这个项目是可以直接在 Tomcat 上部署运行的,页面也可以访问。
不知道看到这里大家是不是和我有一样的疑问:
问题一:为什么我在 tomcat 安装目录下创建一个项目就可以成功部署,项目结构有什么要求吗?可以随便写吗?
项目结构肯定是有要求的,其实这种可直接部署运行的项目结构是在 Servlet 3.1 规范中定义的(Tomcat 官网 也有介绍)。规范要求可直接部署运行的项目结构要包含以下内容:
WEB-INF 的目录内容包括:
只要按照这个结构创建,Tomcat 就可以成功部署运行项目。
问题二:写完的项目放置的位置有什么要求吗?是不是可以随便放?有什么区别吗?
其实在项目创建完后,为了保证 Tomcat 部署项目后可成功访问,在部署前每个项目都要分配一个唯一的上下文路径,作为项目的访问前缀。比如端口号为 8080 的 Tomcat 服务器成功部署了项目 test,为其分配的上下文路径为 /web,那么访问项目 test 根目录下的 index.html 文件的请求 URL 则为:http://localhost:8080/web/index.html。
那么怎么设置项目的上下文路径呢?取决于你的项目放在哪里。
默认情况下项目是放在 Tomcat 安装目录的 webapps 目录下的,此时项目的上下文路径取决于项目所在子目录的目录名称。
比如对于 webapps 目录下的文件名为 myjsp 的项目来说,/myjsp 就是这个项目的上下文路径。要访问 index.html 对应的请求 URL 为 http://localhost:8080/myjsp/index.html。
出于服务器和项目隔离的想法,也随着项目越来越复杂且繁多,更多的情况是项目并不放在 webapps 项目下。而是放在一个其他的位置,再将上下文路径与真实的路径关联,这样项目就可以根据真实路径找到项目并部署,同时可以根据上下文路径访问项目内的资源。
比如我有一个项目路径为 /Users/xxxxxxx/web,想要指定它的上下文路径为 /test,那么需要在 Tomcat 安装目录下 /conf/Catalina/localhost 下创建一个 xml 文件,文件名为想要指定的上下文路径 test。然后打开 test.xml 文件,编辑内容如下:
<!-- Context 表示一个工程上下文 ;docBase 表示你的工程目录在哪里 -->
<Context docBase="/Users/xxxxxxx/web" />
除此之外,也可以在 conf 目录下的 server.xml 文件的 Host 标签下添加如下 Context 标签:
<Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">
<Context path="/a" docBase="/Users/xxxxxxx/web"/>
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" prefix="localhost_access_log" suffix=".txt" pattern="%h %l %u %t "%r" %s %b" />
</Host>
这样在 Tomcat 启动后会扫描 /conf/Catalina/localhost 文件夹、/conf/Catalina/server.xml 文件和 webapps 文件夹,部署扫描到的项目。
以上都是基于直接在 Tomcat 下使用文本编辑器创建 web 项目并进行一些答疑解惑。随着项目越来越复杂,文本编辑器肯定是不能满足需求了,所以出现了 IDE。又因为种种原因,需要在可直接部署运行的项目结构基础上,增加一种包含源代码的目录结构,也就是开发时的目录结构。原因可见 Source Organization。
首先两种目录结构肯定是不一致的,并且包含源代码的目录结构并没有明确的规范约定要长成什么样。而是随着发展,有了一种大家普遍认可的目录结构。之后在 IDE 中创建 web 项目的方式越来越多,比如可以使用 maven 创建、可以通过 gradle 创建、可以通过其他脚手架创建等等。每一种因为工具的不同生成的包含源代码的目录结构都略有不同,但大体上都差不多。这里列出一种目录结构,仅供参考。
上文提到,开发时使用的是包含源代码的目录结构,项目部署时使用的是可直接部署的目录结构,那么在开发完成时怎么快速生成可部署的目录结构呢?使用自动构建工具,比如现在常用的 maven、gradle 等。
对于 web 项目,会打包成 war 包;对于普通 java 项目,会打包成 jar 包。解压缩后的项目结构与规范要求一致。但无论是 war 包还是 jar 包解压缩后会多一个文件夹 : META-INF。META-INF 存储了项目的元信息,其中的文件 manifest.mf 仅此一份,描述了程序的基本信息、Main-Class的入口、jar依赖路径Class-Path等。并且 META-INF 是在项目构建时自动生成的,一般开发人员不需要过多关心。
打开 Tomcat 安装目录中 conf/server.xml 文件,找到 Server 标签下的 Connector 标签,属性 port 就是用来设置 Tomcat 服务器的端口号。修改后重启服务器可生效。
将可运行的 web 项目打包生成 war 包,将 war 包放到远程服务器上的 Tocmat 安装目录的 webapps 目录下,或者放到其他位置并关联上下文路径,参见 项目上下文路径的配置。
启动Tomcat 服务器,此时 Tomcat 会解压 webapps 目录下的 first-maven-web.war 包并生成 first-maven-web 目录文件。
最后浏览器输入 url 地址即可访问。注意,访问地址格式为 ip:端口/资源路径 ,资源路径是相对 Tomcat 安装目录的相对路径。比如这里访问 index.html 的 url 为 http://localhost:8080/first-maven-web/index.html。成功访问页面说明 war 包已经部署并运行在 web 服务器上。
创建 Java Web 项目
项目集成 tomcat 并本地运行
创建新项目,选择 Java Enterprise,选择 JDK、服务器、项目类型、构建工具、语言。
按照默认选择 Servlet,其他的为项目的扩展组件,在这里不需要选择。
设置项目信息,点击 Finish,即可成功创建 Java Web 项目。
补充一个文件系统中的 war 内容,WEB-INF 中同样有 classes 和 lib 文件夹、web.xml 配置文件。
当然在 IDEA 中同样也可以修改项目的上下文路径,修改方式见下图。另外很多文档中也把上下文路径叫做虚拟路径。
上文提到,在 tomcat 上配置上下文路径,可以在 /conf/Catalina/localhost 下创建一个 xml 文件关联上下文路径和真实的项目路径,那么在 IDEA 中配置好上下文路径后会生成这样一个关联文件吗?怎么生成呢?其实也会生成一个 xml 文件。
在 IDEA 启动要部署在 tomcat 上的 web 项目时:
最后创建的文件夹内容如下,文件夹结构是不是与 Tomcat 安装目录结构极其相似呢。
当我们修改 jsp 文件,刷新访问路径时,发现 jsp 文件的修改在页面上无法更新,必须重启项目才可以看到变更。这时可以使用热部署,在文件变更时可以立即反应到页面上,无需重启项目。
配置界面如下: On ‘Update’ action 和 On frame deactivation 都选择 Update resources 或者 Update classes and resources。
Update resources 表示只监听资源文件的变化并更新,比如 html 、css 等。
Update classes and resources 表除了监听资源文件的变化外,还会监听 java 文件的变化并更新。
而要能设置热加载,必须要设置项目部署方式为 war exploded。
war 模式:表示将 web 项目以 war 的形式上传到服务器,服务器基于 war 包进行部署。
war exploded 模式:表示将 web 项目以当前文件夹的位置关系上传到服务器,即直接把 html、css、classes 等移到 tomcat 部署文件夹内,服务器是基于文件夹进行项目部署。所以这种方式支持热部署,一般开发时常使用。
使用 IDEA 创建项目时,可以发现产生了两个文件,HelloServlet.java
和 index.jsp
。这两类文件都是 Java web 中重要文件,是动态响应 HTTP 请求的关键,后面会详细介绍。这里提前放出来,让大家有个印象。
@WebServlet(name = "helloServlet", value = "/hello-servlet")
public class HelloServlet extends HttpServlet {
private String message;
@Override
public void init() {
message = "Hello World!";
}
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html");
// Hello
PrintWriter out = response.getWriter();
out.println("");
out.println(""
+ message + "");
out.println("");
}
@Override
public void destroy() {
}
}
<%@ page import="java.util.*" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<title>Hello</title>
</head>
<body>
<h1><%= "Hello World!" %></h1>
<br/>
<a href="hello-servlet">Hello Servlet</a>
</body>
</html>
参考资料: