文章目录
深入了解servlet
1、Servlet 创建
第一种方式: 实现接口Servlet
public class HelloServlet implements Servlet {
// 初始化
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
// 业务处理
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}
// 获取servlet配置
// ServletConfig 对象,
// 该对象用来返回初始化参数和 ServletContext。
// ServletContext 接口提供有关 servlet 的环境信息。
@Override
public ServletConfig getServletConfig() {
return null;
}
// servlet 的信息,如作者、版本、版权
@Override
public String getServletInfo() {
return null;
}
// 销毁
@Override
public void destroy() {
}
}
第二种方式: 继承GenericServlet
public class HelloServlet2 extends GenericServlet {
// 必须实现
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}
}
第三种方式:继承HttpServlet
public class HelloServlet3 extends HttpServlet {
}
2、Servlet对象和方法解析
servlet的继承结构图:
由上图可以看到,Servlet和ServletConfig都是顶层接口类,而GenericServlet实现了这两个顶层类,然后HttpServlet实现了GenericServlet类.所以要实现一个Servlet直接就可以继承HttpServlet。
2.1、Servlet接口代码
public interface Servlet {
//容器在启动的被调用,仅调用一次
void init(ServletConfig var1) throws ServletException;
//获取Servlet配置
ServletConfig getServletConfig();
//处理具体请求
void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
//获取Servlet的相关信息
String getServletInfo();
//Servlet销毁后释放资源
void destroy();
}
init方法
接收一个ServletConfig参数,由容器传入.ServletConfig就是Servlet的配置,在web.xml中定义Servlet时通过 <init-param>标签配置的参数由ServletConfig保存。
2.2、ServletConfig接口定义
public interface ServletConfig {
//用于获取Servlet名,web.xml中定义的servlet-name
String getServletName();
//获取应用本身(非常重要)
ServletContext getServletContext();
//获取init-param中的配置参数
String getInitParameter(String var1);
//获取配置的所有init-param名字集合
Enumeration<String> getInitParameterNames();
}
ServletConfig是Servlet级别
,而ServletContext是Context(也就是Application)级别.ServletContext通常利用setAttribute()
方法保存Application的属性。
2.3、Servlet第一个实现类GenericServlet
GenericServlet是Servlet的默认实现,是与具体协议无关的,主要做了三件事.
1、实现了ServletConfig接口,可以调用ServletConfig里面的方法。
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable
2、提供了无参的init方法
public void init() throws ServletException {}
3、提供了2个log方法,一个记录日志,一个记录异常。
public void log(String msg) {
this.getServletContext().log(this.getServletName() + ": " + msg);
}
public void log(String message, Throwable t) {
this.getServletContext().log(this.getServletName() + ": " + message, t);
}
2.4、基于协议的HttpServlet
HttpServlet是基于Http协议
实现的Servlet基类
,我们在写Servlet的时候直接继承它就行了。SpringMVC中的DispatchServlet
就是继承了HttpServlet.HttpServlet重新了service方法,而service方法首先将ServletRequest和ServletResponse转成HttpServletRequest和HttpServletResponse,然后根据Http不同类型的请求,再路由到不同的处理方法进行处理.
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
HttpServletRequest request;
HttpServletResponse response;
try {//直接对请求类型进行强转
request = (HttpServletRequest)req;
response = (HttpServletResponse)res;
} catch (ClassCastException var6) {
throw new ServletException("non-HTTP request or response");
}
//调用Http的请求方法处理
this.service(request, response);
}
之后查看下HttpServlet的service方法源码。
3、配置解析
一般的web工程中都会用到web.xml,web.xml主要包括一些配置标签,例如Filter、Listener、Servlet等,可以用来预设容器的配置,可以方便的开发web工程。但是web.xml并不是必须的,一个web工程可以没有web.xml文件。
3.1、web-app
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
</web-app>
这是整个配置文件的根标签,web.xml的模式文件是由Sun公司定义的,它必须标明web.xml使用的是哪个模式文件。
3.2、display-name
<display-name>serTest</display-name>
它标注了该web项目的名字,提供GUI工具可能会用来标记这个特定的Web应用的一个名称,代表项目名字。
<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>
<welcome-file-list>定义了首页文件,也就是用户直接输入域名时跳转的页面。
3.4、servlet
用来声明一个servlet的数据,主要有以下子元素:
指定servlet的名称
指定servlet的类名称
指定web站台中的某个JSP网页的完整路径
用来定义初始化参数,可有多个init-param。在servlet类中通过ServletConfig对象传入init函数,通过- getInitParamenter(String name)方法访问初始化参数。例如使用<init-param>来初始化数据库连接参数。
指定当Web应用启动时,装载Servlet的次序。当值为正数或零时:Servlet容器先加载数值小的servlet,再依次加载其他数值大的servlet。当值为负或未定义:Servlet容器将在Web客户首次访问这个servlet时加载它。
public void init(ServletConfig config) throws SevletException{
super(config);// 不影响servlet正常初始化。
String driver = config.getInitParameter("driver");
String url = config.getInitParameter("url");
String username = config.getInitParameter("username");
String passwd = config.getInitParameter("passwd");
try{
Class.forName(driver).newInstance();
this.conn = DriverManager.getConnection(url, username, passwd);
System.out.println("Connection successful...");
} catch(SQLExceprion se){
System.out.println("se");
} catch(Exception e){
e.printStackTrace():
}
}
此时servlet配置为
<servlet>
<servlet-name>myServlet</servlet-name>
<servlet-class>*.myservlet</servlet-class>
<init-param>
<param-name>driver</param-name>
<param-value>com.mysql.jdbc.Driver</param-value>
</init-param>
<init-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/myDatabase</param-value>
</init-param>
<init-param>
<param-name>username</param-name>
<param-value>tang</param-value>
</init-param>
<init-param>
<param-name>passwd</param-name>
<param-value>whu</param-value>
</init-param>
</servlet>
用来定义servlet所对应的URL,包含两个子元素。
指定servlet的名称。
指定servlet所对应的URL。
<!-- 基本配置 -->
<servlet>
<servlet-name>myServlet</servlet-name>
<servlet-class>*.myservlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myServlet</servlet-name>
<url-pattern>/myServlet</url-pattern>
</servlet-mapping>
<!-- 高级配置 -->
<servlet>
<servlet-name>myServlet</servlet-name>
<servlet-class>*.myservlet</servlet-class>
<init-param>
<param-name>foo</param-name>
<param-value>bar</param-value>
</init-param>
<run-as>
<description>Security role for anonymous access</description>
<role-name>tomcat</role-name>
</run-as>
</servlet>
<servlet-mapping>
<servlet-name>myServlet</servlet-name>
<url-pattern>/myServlet</url-pattern>
</servlet-mapping>
需要特别注意的是元素,这个元素规定了一个 servlet-name 和 url-pattern,如果请求的url能够匹配该url-pattern,则使用servlet-name指定的servlet处理该请求。
url-pattern匹配规则
按照优先级从高到低排列:
- 精确匹配:类似于/myServlet的精确路径。
- 通配符匹配:/*。当前url下任何子路径都可以访问 比如:abc/* abc/任何路径 窄化处理
- 扩展名匹配:.html,.jpg ,.do ,.action之类的。
- 默认匹配(/)——当之前匹配都不成功时。
当servlet收到来自客户端的url请求时,先把请求url减去当前项目上下文路径,然后再与url-pattern进行匹配,匹配按照上面列出的优先级顺序进行,只要有一个匹配成功就停止,不再继续匹配其他的。
(注:/*.action这种匹配式是错误的,容器无法识别同时拥有两种匹配规则的pattern)
<!-- 配置-->
<servlet>
<servlet-name>myServlet</servlet-name>
<servlet-class>*.myservlet</servlet-class>
</servlet>
<servlet-name>myServlet</servlet-name>
<url-pattern>/myServlet</url-pattern>
</servlet-mapping>
收到来自客户端的请求http://localhost:8080/serTest/myServlet/index.html,首先将该请求url减去项目上下文得到/myServlet/index.html,之后与url-pattern进行匹配,发现/myServlet匹配成功,之后便把该请求交由servlet-name指定的myServlet处理。
3.5、session-config
配置会话超时,单位是分钟
<session-config>
<session-timeout>120</session-timeout>
</session-config>
3.6、error-page
在返回特定HTTP状态代码时,或者特定类型的异常被抛出时,能够制定将要显示的页面。
<error-page>
<error-code>500</error-code>
<location>/error.html</location>
</error-page>
4、内置对象的常用方法
4.1、request
request.getParameter("键")
name为键 value为值 由键取值
request.getParameterValues("键")
复选框中name相同,value不同 由同一name取得value数组
request.getRequestURL()
获得页面url地址,不带参数
request.getParameterNames()
获得页面url地址并带参数的枚举集合
request.getRequestDispatcher()
转发url不变,并携带数据
request.setCharaterEncoding("编码方式")
设置页面请求编码方式
request.getRemoteAddr()
获得页面请求ip地址
4.2、response
response.setCharaterEncoding("编码方式")
设置页面响应编码方式
response.sendRedirect("页面地址")
重定向,url地址变化,不带数据
response.setContextType("text/html;charset=UTF-8")
响应给页面头文件添加此页面为html类型,编码方式为UTF-8的信息
4.3、session
session.getId()
获得会话唯一id
session.clear()
清除所有会话数据
session.removeAttribut("键")
根据键清除数据
session application request 都有 setAttribute(String,Object);
给属于自己的作用域存放键值信息。
session application request 都有 getAttribute(String);
给属于自己的作用域获取信息。
session application request 都有 removeAttribut(String);
给属于自己的作用域获取信息。
application 存放公用的内容 如一些工具信息(时间、日期)还有公共内容。
session 存放与当前用户有关的内容。
request 数据二次访问的时候。