Servlet 快速概览

目录


生命周期

web.xml

获取表单数据(设置请求的编码格式)

返回响应内容(设置响应的编码格式)

结合前两点,总结基本模板

获取请求协议头部信息

设置响应头部信息

使用过滤器

在web.xml中为过滤器配置参数 

使用Cookie

使用Session

对字符串数据进行编码和解码

监听器

 

 


 

 

 

 

生命周期

  我们自己创建的servlet,继承自HttpServlet,就相当于有了init()、doGet()、doService()、doPost()、destroy()这几个方法,而这几个方法就可以描述Servlet的声明周期。

方法名 被调用的时刻 以及  功能
init() 只有第一次访问该servlet的时候被调用,一般用来进行数据初始化
doGet() 通过get方式访问servlet的时候被调用,响应get请求
doPost() 通过post方式访问servlet的时候被调用,响应post请求
service() 接收所有方式的请求,service会在doGet和doPost之前调用
destroy() 服务器停止的时候被调用,一般用来进行一些清理操作

 

   因为我们将代码部署到服务器Tomcat上面,也就是说,Tomcat是一个容器。同时,上面的那些方法都是都Tomcat服务器来调用(由容器来调用)。

 

 

web.xml

  web.xml是项目的配置文件,该文件用来配置请求路径与servlet的对应关系。

  全路径为project-root/WebContent/WEB-INF/web.xml。

  需要注意的是,servlet有多个版本,在高版本中,可以通过注解@WebServlet("url-pattern")来设置。之前的版本需要使用web.xml来配置。

  示例:

<web-app>
  	<display-name>tomcat</display-name>
	<servlet>
		<servlet-name>test</servlet-name>
		<servlet-class>lixin.gan.test.TestServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>test</servlet-name>
		<url-pattern>/testServlet</url-pattern>
	</servlet-mapping>
</web-app>

  Tomcat使用web.xml的步骤:  

  1. Tomcat服务器在启动的时候,会加载web.xml文件,并解析文件。
  2. 服务器收到客户端的请求时,首先会根据请求的url路径去web.xml中相同寻找匹配的url-pattern。
  3. 如果没有找到匹配的url-pattern,就表示出错了(返回404);如果存在url-pattern,那么就利用与之对应的servlet-name,去servlet标签中查找对应的servlet-class。
  4. 根据找到的servlet-class来确定调用哪一个servlet来处理请求。

 

 

获取表单数据(设置请求的编码格式)

  表单提交的方式get和post 与 servlet中的doGet和doPost方法相对应,但是可以使用service来获取get或者post请求。默认情况下,如果没有重写doPost、doGet、service,则先执行service方法,然后service方法中根据请求方式,再调用doGet或者doPost。

  获取表单数据常用的是下面三个方法:

// 获取请求参数中key对应的value
String HttpServletRequest.getParameter(String key)

// 用于获取checkbox这种有多个同名的key参数
String[] HttpServletRequest.getParameterValues(String key)

// 获取所有参数,并以map形式保存
Map<String, String[]> HttpServletRequest.getParameterMap()

  上面的所有方法接收到的数据,传输过程中都是经过编码,如果请求中的数据全是英文,那么不会出现问题;但是如果有其他字符(比如中文字符),此时打印获取的数据,会出现乱码,可以通过getBytes("utf-8")来解码,也可以直接设置请求的编码格式:

request.setCharacterEncoding("utf-8");

  如果通过req.setCharacterEncoding("utf-8"),只能对post提交的数据进行字符集编码,而不能对get方式进行编码。因为get方式传递的参数是在URL中,进行的是URL编码。

  但是可以在tomcat的配置文件中,增加一个配置项即可:useBodyEncodingForUri="true"

<Connector 
	connectionTimeout="200000" 
	port="80" 
	protocol="HTTP/1.1" 
	redirectPort="8443" 
	useBodyEncodingForUri="true"
/>

  

 

返回响应内容(设置响应的编码格式)

  要想发回响应给请求方,可以通过下面的格式来进行:

PrintWriter writer = response.getWriter();
writer.append("hello 你好\n");
writer.flush();

  上面的代码是简单的返回一些文本内容给客户端,但是有两个需要注意的地方:

  1、此时并没有告诉客户端这个内容是什么格式(XML? JSON?MP4?),所以客户端接收到数据之后,会原封不动的显示出来。

  2、响应回来的内容是使用了什么编码格式,注意编码格式和内容格式不一样,编码格式决定着客户端能否正确无误地解析文件内容。

  鉴于以上面个注意点,可以通过两个方法来解决:

// 只设置响应内容的编码格式,而没有设置响应内容的数据格式
response.setCharacterEncoding("utf-8");

// 设置响应内容的数据格式,同时也设置了响应内容的编码格式
response.setContentType("text/html; charset=utf-8");

  

 

结合前两点,总结基本模板

  以doGet为例子:

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	
	// 首先设置请求数据的字符编码
	req.setCharacterEncoding("utf-8");
	
	// 设置响应内容的数据格式以及编码格式
	resp.setContentType("text/html; charset=utf-8");
	
	// 然后是自己的业务代码
	
}

  上面这个模板其实并不好,因为,这样做之后,每一个方法都需要加这两行代码,一旦字符编码或者响应格式改变,就要修改很多地方。

  后期可以使用拦截器来完成设置 字符编码 以及 响应数据格式 的功能。

 

 

获取请求协议头部信息

  获取请求协议中的头部信息,有三个方法,但通常使用最多的是下面这个方法

String req.getHeader(String key)

  使用方式很简单,需要注意的是,请求中key和value都是要经过编码的(不能直接传输中文字符)。

 

 

设置响应头部信息

  设置响应头信息,也很简单,最常用的是下面这个方法:

void resp.setHeader(String key, String value)

  注意,如果value包含中文字符,需要先经过编码才能作为参数。

  如果要设置响应状态码,可以使用setStatus()方法来设置:

void resp.setStatus(int statusCode);

  如果还要设置状态码的信息,可以使用sendError()

void resp.sendError(int statusCode, String msg);

  

 

使用过滤器

  过滤器是一种特殊的工具,功能如下:

  1、在请求到达服务器的时候先于servlet处理请求。

  2、在返回给客户端响应之前,对Servlet的响应再进行一次加工,之后在返回给客户端。

 

  使用过滤器,可以在web.xml中进行配置,也可以使用注解@WebFilter("url-pattern")来设置,下面是在web.xml中的配置:

<filter>
	<filter-name>testFilter</filter-name>
	<filter-class>lixin.gan.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
	<filter-name>testFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

 

  filter中的三个主要的方法:

public void init(FilterConfig fConfig)

  filter中的init(),功能和servlet中的init()一样,用于数据的初始化,第一次调用是在服务器启动的时候

 

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

  调用doFilter()进行过滤操作。三个参数的意义以及作用:

  1、第1个参数request是客户端的请求(还没有被servlet处理),此时可以修改请求中的数据。

  2、第2个参数response是由servlet处理之后的返回的response,此时可以修改响应中的数据。

  3、filter对request进行一些处理之后,调用第3个参数chain的doFilter(request, response)方法,来将请求转发给对应的servlet处理,表示通过了过滤。

 

public void destroy()

  服务器关闭的时候被调用。

 

  结合前面servlet中的service()、doPost()、doGet()中对于所有请求,都要设置请求的编码格式以及相应内容的数据格式和编码格式,有了过滤器,可以将这些操作都单独地写在过滤器中,可以消除冗余,同时维护起来也方便。

  比如:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws Exception {

	// 统一设置字符集编码以及响应内容格式
	request.setCharacterEncoding("utf-8");
	response.setContentType("text/html; charset=utf-8");
	
	// 放行,执行真正的servlet
	chain.doFilter(request, response);
}

  

 

在web.xml中为过滤器配置参数

  前面已经介绍了过滤器怎么使用,这里增加一点内容:从web.xml中读取过滤器的配置参数。过滤器的init()方法使用来对过滤器进行一些初始化工作,再进行初始化的时候,可能会有这种情况:有一些(配置)参数的值在程序代码中写死,这样的话,一旦要修改配置参数的话,就需要修改代码。

  其实,完全可以在web.xml中配置,然后在init方法中,利用FilterConfig类来获取web.xml中的配置项。在web.xml中添加配置项的方法如下:

<filter>
	<filter-name>testFilter</filter-name>
	<filter-class>lixin.gan.filter.MyFilter</filter-class>
	<init-param>
		<param-name>token</param-name>
		<param-value>123456abc</param-value>
	</init-param>
	<init-param>
		<param-name>code</param-name>
		<param-value>9999</param-value>
	</init-param>
</filter>
<filter-mapping>
	<filter-name>testFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

  在Filter的init方法中这样使用:

public void init(FilterConfig fConfig) throws ServletException {
	System.out.println(fConfig.getInitParameter("code"));
	System.out.println(fConfig.getInitParameter("token"));
}

  

  

使用Cookie

  设置响应cookie(通过response对象返回客户端)

Cookie cookie = new Cookie("key", "value");

// 不设置过期时间(临时cookie),默认在浏览器窗口关闭之前有效。
cookie.setMaxAge(100);

// 若设置cookie的过期时间,单位为秒,0表示删除该cookie。
cookie.setMaxAge(0)

cookie.setValue("value2")
 
cookie.setDomain("www.baidu.com");
cookie.setPath("/demo/test");
 
// 将cookie放入response对象中,返回给客户端。
response.addCookie(cookie);

  

  获取请求中的cookie(通过request对象来获取)

// 获取所有cookie
Cookie[] cookies = request.getCookies();

for (Cookie cookie : cookies) {
	System.out.println("name --> " + cookie.getName());
	System.out.println("value --> " + cookie.getValue());
	System.out.println("maxAge --> " + cookie.getMaxAge());
	System.out.println("-----------------------------------");
	if (cookie.getName().equals("id")) {
		cookie.setMaxAge(0);  // 销毁cookie
	}
}

  

 

使用Session

  session基于cookie。

// 如果请求中携带有session,那么就会返回请求中的session
// 如果没有携带session,那么就创建一个session,并返回。
HttpSession session = request.getSession();
 
// 获取session_id,即JSESSION
String session_id = session.getId();
 
// 设置过期时间,不设置的话,默认是30分钟 
// session失效了之后,下一次访问,服务器会重新创建一个session,并返回。
// 失效是指 指定时间端内,如果用户都没有发起请求,那么时间一到就失效
session.setMaxInactiveInterval(60);
 
// 设置session项
session.setAttribute("name", "小强");
session.setAttribute("age", 99);

// 移除session中的某一项,即使key不存在也不报错
session.removeAttribute("key");
 
// 获取session值,如果不包含key对应的session项,则返回null
String name = (String)session.getAttribute("name");
int age = (int)session.getAttribute("age");

// 强制session失效
session.invalidate();

  

  

对字符串数据进行编码和解码

  前面有几个地方需要注意字符编码:

  1、设置header的时候,如果设置的值包含中文,客户端接收到之后是乱码。

  2、是指cookie和session的时候,value如果包含中文,则会出现错误。

  这两种情况需要进行手动编码,使用的是java.net.URLEncoder.encode()方法,

  使用方式如下:

// 将msg按照操作系统默认的字符编码格式进行编码,然后再进行url编码
String java.net.URLEncoder.encode(String msg)

// 将msg按照charset进行编码,然后再进行url编码
String java.net.URLEncoder.encode(String msg, String charset)

  

  对于请求中的header、cookie、session数据,与编码对应的是解码,使用的是java.net.URLDecoder.decode()方法:

// 将内容进行URL解码之后,再按照charset编码
java.net.URLDecoder.decode(String msg, String charset)

  

  注意上面的编码和解码方式都是:URL编码。

 

 

监听器

   监听器可以用于对request、session、servlet被创建、修改、销毁时,触发的事件处理程序。

  配置监听器有两种方式:

  1、使用注解@WebListener来标明为监听器。

  2、在web.xml中配置,格式如下:

<listener>
	<listener-class>lixin.gan.listener.MyListener</listener-class>
</listener>

  

  监听器的分类如下:

  

  

  监听器可以对servlet context、session、request进行监听,监听的时候,分为两类:

  1、对初始化和销毁的监听器(XxxListener)

  2、对属性进行修改时触发的监听器(XxxAttributeListener)

  

  监听器在javax.servlet包里面。

监听器分类 监听器 方法
servlet context ServletContextListener contextInitialized(ServletContextEvent arg0)
contextDestroyed(ServletContextEvent arg0)
ServletContextAttributeListener attributeAdded(ServletContextAttributeEvent arg0)
attributeRemoved(ServletContextAttributeEvent arg0)
attributeReplaced(ServletContextAttributeEvent arg0)
     
Session HttpSessionListener sessionCreated(HttpSessionEvent arg0)
sessionDestroyed(HttpSessionEvent arg0)
HttpSessionAttributeListener attributeAdded(HttpSessionBindingEvent arg0)
attributeRemoved(HttpSessionBindingEvent arg0)
attributeReplaced(HttpSessionBindingEvent arg0)
     
request ServletRequestListener requestInitialized(ServletRequestEvent arg0)
requestDestroyed(ServletRequestEvent arg0)
ServletRequestAttributeListener attributeAdded(ServletRequestAttributeEvent arg0)
attributeRemoved(ServletRequestAttributeEvent arg0)
attributeReplaced(ServletRequestAttributeEvent arg0)

 

  

 

posted @ 2018-12-04 18:19  寻觅beyond  阅读(241)  评论(0编辑  收藏  举报
返回顶部