本文纯属于个人观点,如果有不对的地方,还请各位看官多加批评指正,完善我的知识体系。
应用程序:包括 Web 应用程序 和 非 Web 应用程序。
- Web应用程序:是一种部署在服务器上,可以通过Web(浏览器)访问的应用程序。程序的最大好处是用户很容易访问应用程序,不需要再安装其他软件,客户端零维护。 又称 B/S 架构(browser / service)
- 非 Web 应用程序:是一种安装在电脑端的应用程序,客户端需要安装专用的客户端软件。又称 C/S 架构(Client/Server)。
今天着重说下 JavaWeb 应用程序。
Eclipse 分别创建两个应用程序:普通的 Java Project 和 Web Project
![]() |
|
|
| ![]() |
选择 Run on Server 程序启动报错。
- 浏览器地址栏有一个新的访问地址;
- 页面报 HTTP404;
带着这样的疑问进行接下来的学习。
首先介绍一个概念:Servlet
Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
![]() | Servlet 架构![]() ![]() |
其次介绍:web.xml
每个 JavaEE 项目都包含了 一个 web.xml 文件,但 web.xml 不是 JavaEE 项目必须依赖的文件。
web.xml 的作用:用来初始化配置信息:比如初始页面、servlet、servlet-mapping、filter、listener、启动加载级别等。
所以把工程的代码补完整
项目类代码 实现 Servlet 继承
package cn.hcg.test;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class J2EETest implements Servlet{
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("hello init");
}
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("hello service");
}
@Override
public void destroy() {
System.out.println("goodbye servlet");
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public String getServletInfo() {
return null;
}
}
因为 Web 服务一般用的都是 Http 请求 也可以直接 实现 HttpServlet,重写 service 方法。以避免后期 request 和 response 转换
public class HttpServletDemo extends HttpServlet{
private static final long serialVersionUID = 1L;
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) {
}
}
web.xml 注册
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>J2EETest</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!--注册自己要使用的(servlet)类 -->
<servlet>
<servlet-name>J2EETest</servlet-name>
<servlet-class>cn.hcg.test.J2EETest</servlet-class>
</servlet>
<!-- 向浏览器公布自己的 servlet 的访问路径 -->
<servlet-mapping>
<servlet-name>J2EETest</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
注意:
一:其中 servlet-name 是 mapping 中的 name 必须相同,且都是自定义的。
二:<url-pattern>
1.完全匹配路径:必须 ‘ / ’ 开头
例如:/hello 、/a/b/c/hello
访问路径和 web.xml配置路径一致,servlet将被调用。
2.不完全匹配(通配符匹配)' / '开头,以*结尾
例如:/* 、 /a/b/*
/a/b/* ,a目录下的b目录下的所有内容
/* 当前项目下所有内容
3.扩展名匹配 *开头
例如:*.do 、*.action 、 *.jsp
只处理某一类文件
4. 缺省路径 /
以上都没有匹配,将执行缺省
优先级:1 > 2 > 3 > 4
缺省servlet:如果一个servlet的对外访问路径被设置为/,则该servlet就是一个缺省servlet,其他servlet不处理的请求都由它来处理
~在conf/web.xml中配置了缺省servlet,对静态资源的访问和错误页面的输出就是由这个缺省servlet来处理的。
如果我们自己写一个缺省servlet把web.xml中的缺省servlet覆盖的话,会导致静态web资源无法访问。所以不推荐配置。
注意:错误写法 /*.jsp
浏览器输入路径: http://localhost:8080/J2EETest/
1. 启动WEB项目的时候,容器首先会去它的配置文件web.xml读取两个节点: <listener></listener>和<context-param></context-param>。
2. 紧接着,容器创建一个ServletContext(application),这个WEB项目所有部分都将共享这个上下文。
3. 容器以<context-param></context-param>的name作为键,value作为值,将其转化为键值对,存入ServletContext。
4. 容器创建<listener></listener>中的类实例,根据配置的class类路径<listener-class>来创建监听,在监听中会有contextInitialized(ServletContextEvent args)初始化方法,启动Web应用时,系统调用Listener的该方法,在这个方法中获得:
ServletContext application = ServletContextEvent.getServletContext();
context-param的值 = application.getInitParameter("context-param的键"); 得到这个context-param的值之后,你就可以做一些操作了。