深入了解servlet

深入了解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匹配规则

按照优先级从高到低排列:

  1. 精确匹配:类似于/myServlet的精确路径。
  2. 通配符匹配:/*。当前url下任何子路径都可以访问 比如:abc/* abc/任何路径 窄化处理
  3. 扩展名匹配:.html,.jpg ,.do ,.action之类的。
  4. 默认匹配(/)——当之前匹配都不成功时。

当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 数据二次访问的时候。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值