public class HelloServlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("调用doGet()");
}
// @Override
// protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// System.out.println("调用doPost()");
// }
}
使用这种方法创建,创建完后,会自动生成< servlet>的配置文件,只需要配置< servlet-mapping>即可。
java.servlet中的Interface Servlet
Servlet接口,只是负责定义程序的访问规范。
java.sevlet中的class GenericServlet
GenericServlet抽象类实现了Servlet接口,做了很多空实现。并持有一个ServletConfig类的引用,并对ServletConfig的使用做了一些方法。
java.sevlet.http中的class HttpServlet
HttpServlet抽象类继承了GenericServlet抽象类,实现了service()方法,并实现了请求的分发处理,根据请求方式的不同,提供了doGet()和doPost()方法,在HttpServlet中,这两个方法内部负责抛异常(sendError(),说不支持GET或者POST请求)。
创建一个类,继承HttpServlet类,然后我们只需要根据业务需要去重写doGet()或者doPost()方法即可。
- ServletConfig从类名来看,就知道是Servlet程序的配置类。
- Servlet程序和ServletConfig对象都是由Tomcat创建的,我们只负责使用。
- Servlet程序是第一次访问的时候创建的,ServletConfig是每个Servlet程序创建时,就创建一个对应的ServletConfig对象。
ServletContext servletContext = getServletConfig().getServletContext();
// 其实可以直接getServletContext
getServletContext(){
return getServletConfig().getServletContext();
}
web.xml配置文件:
<servlet>
<servlet-name>HelloServlet1servlet-name>
<servlet-class>com.solve.servlet.HelloServlet1servlet-class>
<init-param>
<param-name>usernameparam-name>
<param-value>adminparam-value>
init-param>
<init-param>
<param-name>passwordparam-name>
<param-value>123456param-value>
init-param>
servlet>
Servlet程序:
public class HelloServlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("调用HelloServlet1的doGet()");
// 通过servlet的servletConfig对象获取配置文件中sevlet-name的
ServletConfig config = getServletConfig();
String servletName = config.getServletName();
System.out.println("servlet-name的值为:" + servletName);
// 获取配置文件中init-param的值
String username = config.getInitParameter("username");
String password = config.getInitParameter("password");
System.out.println("初始化用户名为:" + username);
System.out.println("初始化密码为:" + password);
}
运行结果:
ServletContext servletContext = getServletContext();
实际创建的是一个实现了ServletContext接口的类的对象,就相当于父类的引用指向子类的对象,即多态。
- ServletContext是一个接口,它表示上下文对象。
- 一个web工程,只有一个ServletContext对象实例。
- ServletContext对象是在web工程部署启动的时候创建,在web工程停止工作的时候销毁。
- ServletContext对象是一个域对象,可以像集合中的Map一样,存取数据,这里的域指的是存取数据的操作范围。
存数据 | 取数据 | 删除数据 | |
---|---|---|---|
Map | put() | get() | remove() |
域对象 | setAttribute() | getAttribute() | removeAttribute() |
web.xml配置文件:
<context-param>
<param-name>sexparam-name>
<param-value>boyparam-value>
context-param>
<context-param>
<param-name>ageparam-name>
<param-value>twenty-oneparam-value>
context-param>
Servlet程序:
public class HelloServlet2 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("我是HelloServlet2的doGet()");
// 获取ServletContext实现类的对象
ServletContext servletContext = getServletContext();
// servletContext.getInitParameter(String s)获取context-param
String sex = servletContext.getInitParameter("sex");
String age = servletContext.getInitParameter("age");
System.out.println("项目下的sex为" + sex);
System.out.println("项目下的age为" + age);
// 获取当前的项目路径
String contextPath = servletContext.getContextPath();
System.out.println(contextPath);
// 获取当前项目部署后在服务器硬盘上的绝对路径
String realPath = servletContext.getRealPath("/");
System.out.println(realPath);
String beautifulGirl_jpg_realPath = servletContext.getRealPath("/images/beautifulGirl.jpg");
System.out.println(beautifulGirl_jpg_realPath);
}
}
/ 斜杠会被服务器解析为http://ip/port/项目名,映射到IDEA代码的web目录。
运行结果:
我们注意一下Tomcat启动时,这里的CATALINA_BASE:
这个路径是IDEA整合Tomcat之后,Tomcat被拷贝的一些副本内容,配置文件,日志之类的,里面有个conf\Catalina\localhost目录下就有我们当前项目(整个module)的一个xml配置文件。(G盘就是这个Project的存放位置)
<Context path="/servletStudy" docBase="G:\SummerWeb\servletStudy\target\servletStudy.war" />
一个工程对应一个ServletContext实例对象,所以当前工程中的某一个Servlet程序获取了ServletContext对象,并用这个对象存取数据时,在当前工程下的另一个Servlet程序中,即使没有存取过数据,依旧可以通过ServletContext这唯一的一个实例对象对存取过的数据进行访问。
示例:
// HelloServlet2
public class HelloServlet2 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("我是HelloServlet2的doGet()");
// 获取ServletContext实现类的对象
ServletContext servletContext = getServletContext();
// 像Map一样存取对象
System.out.println("HelloServlet2中,未设置key1之前,key1对应的值为:" + servletContext.getAttribute("key1"));
servletContext.setAttribute("key1","value1");
System.out.println("HelloServlet2中获取域数据key1的值为:" + servletContext.getAttribute("key1"));
System.out.println("HelloServlet2中获取域数据key1的值为:" + servletContext.getAttribute("key1"));
}
}
// HelloServlet3
public class HelloServlet3 extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("我是HelloServlet3的doGet()");
ServletContext servletContext = getServletContext();
System.out.println("HelloServlet3中获取域数据key1的值为:" + servletContext.getAttribute("key1"));
}
}
访问结果:
我们可以发现,在HelloServlet3中,并没有调用setAttribute(),存入数据,第一次调用的时候,值为null,然后再HelloServlet2中,才调用setAttribute()设置key1对应的值为value1,然后再次访问HelloServlet3,发现,可以通过getAttribute()传入key1,获取对应的value1,这是需要注意的一个点。