在开发 Java Web 应用程序时,除了常见的 Servlet
和 Filter
等逻辑组件外,还需要处理诸如 JSP
这样的视图文件和一些静态资源文件,如 CSS
、JS
等。合理组织 Web 应用的文件结构至关重要,它能够提升开发效率,方便后期维护,并确保应用在生产环境中的高效运行。
1. Web 应用程序的文件结构设计
一个标准的 Java Web 应用程序通常包含如下几个核心部分:
css
webapp
├── pom.xml
└── src
└── main
├── java
│ └── com
│ └── itranswarp
│ └── learnjava
│ ├── Main.java
│ ├── filter
│ │ └── EncodingFilter.java
│ └── servlet
│ ├── FileServlet.java
│ └── HelloServlet.java
├── resources
└── webapp
├── WEB-INF
│ └── web.xml
├── favicon.ico
└── static
└── bootstrap.css
1.1 pom.xml
该文件是 Maven 构建工具的配置文件,包含了项目依赖、插件等信息,方便管理项目构建和依赖。
1.2 src/main/java
此目录下存放的是 Java 源代码文件,包括 Servlet、Filter 等 Java 类。
1.3 src/main/resources
存放的是一些资源文件,诸如配置文件、日志文件等。
1.4 src/main/webapp
这是 Web 应用程序的核心目录,包含了 WEB-INF
配置文件和静态资源文件。
-
WEB-INF/web.xml
:Web 应用的配置文件,用于定义 Servlet、Filter、Listener 等组件。 -
favicon.ico
:浏览器访问应用时显示的图标。 -
static
:用于存放静态资源(如 CSS、JS、图片等)。
2. 处理静态资源
在开发阶段,我们通常将所有的静态资源文件放入 /static
目录。在某些 Web 服务器中,可能会有专门的 Servlet 来处理静态文件的请求,但如果 IndexServlet
映射路径为 /
,它就会屏蔽掉静态文件的处理逻辑。因此,我们需要编写一个自定义的 FileServlet
来处理静态文件。
2.1 FileServlet 示例
下面是一个简单的 FileServlet
实现:
java
@WebServlet(urlPatterns = "/static/*")
public class FileServlet extends HttpServlet {
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext ctx = req.getServletContext();
// RequestURI包含ContextPath,需要去掉:
String urlPath = req.getRequestURI().substring(ctx.getContextPath().length());
// 获取真实文件路径:
String filepath = ctx.getRealPath(urlPath);
if (filepath == null) {
// 无法获取到路径:
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
Path path = Paths.get(filepath);
if (!path.toFile().isFile()) {
// 文件不存在:
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
// 根据文件名猜测Content-Type:
String mime = Files.probeContentType(path);
if (mime == null) {
mime = "application/octet-stream";
}
resp.setContentType(mime);
// 读取文件并写入Response:
OutputStream output = resp.getOutputStream();
try (InputStream input = new BufferedInputStream(new FileInputStream(filepath))) {
input.transferTo(output);
}
output.flush();
}
}
2.2 解释
在这个例子中,FileServlet
监听 /static/*
路径,并读取 static
目录下的静态资源文件。doGet()
方法从请求中获取文件路径,读取文件并写入响应中。ServletContext
用于获取 Web 应用的真实路径,Files.probeContentType()
用于根据文件类型设置 Content-Type
。
3. 生产环境的静态资源处理
3.1 静态资源的生产部署
类似 Tomcat
的 Web 服务器通常用于运行 Web 应用程序,它们并不擅长处理静态文件。因此,在生产环境中,通常会使用 Nginx 作为反向代理服务器,来专门处理静态文件的请求,减轻 Tomcat 的负担。
3.2 使用 Nginx 作为反向代理
在生产环境中,我们通常采用以下架构:
markdown
┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┐
│ /static/* │
┌───────┐ ┌──────────▶ file
│Browser├────┼─┤ │ ┌ ─ ─ ─ ─ ─ ─ ┐
└───────┘ │/ proxy_pass
│ └─────────────────────┼───▶│ Web Server │
Nginx
└ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ └ ─ ─ ─ ─ ─ ─ ┘
3.3 Nginx 配置示例
以下是一个配置文件示例,展示了如何使用 Nginx 配合 Tomcat 处理静态资源:
nginx
server {
listen 80;
server_name www.local.liaoxuefeng.com;
# 静态文件根目录:
root /path/to/src/main/webapp;
access_log /var/log/nginx/webapp_access_log;
error_log /var/log/nginx/webapp_error_log;
# 处理静态文件请求:
location /static {
}
# 处理favicon请求:
location /favicon.ico {
}
# 不允许请求/WEB-INF:
location /WEB-INF {
return 404;
}
# 其他请求转发给Tomcat:
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
3.4 配置说明
-
location /static
:Nginx 负责直接处理静态资源请求。 -
location /favicon.ico
:处理浏览器的 favicon 请求。 -
location /WEB-INF
:禁止访问WEB-INF
目录。 -
location /
:将其他请求转发给 Tomcat 处理。
4. 练习
-
使用 Nginx 配合 Tomcat 部署一个 Java Web 应用,确保静态资源能够由 Nginx 直接处理,其他动态请求交由 Tomcat 处理。
5. 小结
在开发 Java Web 应用时,合理组织文件结构对于开发和维护至关重要。开发模式下,需要便捷的静态资源处理方式,而生产模式下,需要高效的静态资源处理能力和反向代理配置。通过 Nginx 和 Tomcat 的组合,可以充分利用 Nginx 高效的静态资源处理能力,同时将动态请求交给 Tomcat 处理,极大提升 Web 应用的性能和可靠性。
标签:Web,Java,处理,文件,静态,Day21,Nginx,static From: https://blog.csdn.net/max202011161630/article/details/144857176