父工程 Maven artifactId: gpt-web。多模块 Servlet / Spring Web MVC 练习,含两个可独立部署的 WAR:
| 模块目录 | Maven artifactId |
说明 |
|---|---|---|
gpt-web-app/ |
gpt-web-app |
主示例;打包 finalName → gpt-web.war(部署上下文常见 gpt_web_app_war) |
gpt-web-capture/ |
gpt-web-capture |
抓站示例;finalName → web-capture |
文档里的完整 URL 使用固定前缀,若与你本机不一致请整体替换:
- 主 WAR:
http://localhost:8080/gpt_web_app_war(由gpt-web.war解压名决定) - gpt-web-capture:
http://localhost:8080/web-capture(见gpt-web-capture/pom.xml)
| # | URL | 说明 |
|---|---|---|
| 1 | http://localhost:8080/gpt_web_app_war/ | 欢迎页指向 hello.html |
| 2 | http://localhost:8080/gpt_web_app_war/hello.html | 静态 HTML |
| 3 | http://localhost:8080/gpt_web_app_war/favicon.ico | default servlet 映射的静态资源 |
web.xml:url-pattern为/gpengtao/*- 子容器配置:
WEB-INF/gpt-mvc-dispatcher-servlet.xml
除上表标明 GET 的接口外,若 @RequestMapping 未写 method,Spring 会接受 所有 HTTP 方法;若只想开放 GET,需在代码里加 method = RequestMethod.GET 等。
web.xml:/gpengtao2/*- 子容器:
AnnotationConfigWebApplicationContext,只加载com.gpengtao.web.config.MyWebConfig(其中无@EnableWebMvc、无 Controller 扫描),没有注册任何请求映射。例如 http://localhost:8080/gpt_web_app_war/gpengtao2/anything 一般为 404。
| # | url-pattern |
示例 URL | 说明 |
|---|---|---|---|
| 1 | /time/* |
http://localhost:8080/gpt_web_app_war/time/任意片段 | ShowTimeServlet;* 表示一级或多级子路径均可 |
| 2 | /index-gpt |
http://localhost:8080/gpt_web_app_war/index-gpt | IndexServlet |
| 3 | /testServlet/ |
http://localhost:8080/gpt_web_app_war/testServlet/ | TestServlet(注意末尾 /) |
| 4 | /lbClassicStatus |
http://localhost:8080/gpt_web_app_war/lbClassicStatus | Logback ViewStatusMessagesServlet |
| # | 条件 | 浏览器可直接访问的 JSP |
|---|---|---|
| 1 | HTTP 404 | http://localhost:8080/gpt_web_app_war/404.jsp |
| 2 | HTTP 500(及其它未单独声明的异常) | http://localhost:8080/gpt_web_app_war/500.jsp |
| 3 | NullPointerException 且被容器按类型匹配 |
http://localhost:8080/gpt_web_app_war/nullPointerError.jsp |
说明: 访问不存在的路径会触发 404 映射。/gpengtao/testError 随机抛 NPE 时可能进入 nullPointerError.jsp;若抛的是 RuntimeException,则走 500 映射(500.jsp),不会进 NPE 专用页。
web.xml:url-pattern/mvc/*,DispatcherServlet名mvc- 默认配置:
WEB-INF/mvc-servlet.xml(未在web.xml里写contextConfigLocation时,约定为/WEB-INF/mvc-servlet.xml)
| # | URL | 说明 |
|---|---|---|
| 1 | http://localhost:8080/web-capture/mvc/time/date?date=2020-01-01 | TimeController:InitBinder 注册 yyyy-MM-dd 的 Date 编辑器;参数名 date |
| 2 | http://localhost:8080/web-capture/mvc/time/now | 当前时间,JSON |
| 3 | http://localhost:8080/web-capture/mvc/time/yesterday | 昨天日期,HTML |
| 4 | http://localhost:8080/web-capture/mvc/time/china | 纯文本 |
| 5 | http://localhost:8080/web-capture/mvc/time/say?message=hello | 查询参数 message |
| 6 | http://localhost:8080/web-capture/mvc/time/test | 偶数次请求返回字符串,奇数次返回 JSON(由时间戳模 2 决定) |
| 7 | http://localhost:8080/web-capture/mvc/time/encoding?name=test | 查询参数 name(原样回显) |
| 8 | http://localhost:8080/web-capture/mvc/capture?url=www.example.com | CaptureController:参数 url,视图名 capture(补全 http:// 逻辑见代码) |
| 9 | http://localhost:8080/web-capture/mvc/download?url= | CaptureController:url 需按 CaptureUtil.parseTag 约定补全 |
拦截器: mvc-servlet.xml 中 <mvc:mapping path="/time/*"/> 绑定 TimeUrlInterceptor。该 pattern 是 Dispatcher 内部路径(已剥掉 context-path 与 /mvc 前缀之后、与 @RequestMapping("/time") 对齐),因此上表中所有 …/mvc/time/… 会先过 TimeUrlInterceptor。AccessInterceptor 直接注册在 <mvc:interceptors> 下、未配 mvc:mapping,对本 Servlet 映射下的 全部 请求生效(含 /mvc/capture 等)。
web.xml 里 CharacterEncodingFilter 整块注释,当前 没有 生效的编码 Filter。