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 contextServletContextListenercontextInitialized(ServletContextEvent arg0)
contextDestroyed(ServletContextEvent arg0)
ServletContextAttributeListenerattributeAdded(ServletContextAttributeEvent arg0)
attributeRemoved(ServletContextAttributeEvent arg0)
attributeReplaced(ServletContextAttributeEvent arg0)
   
SessionHttpSessionListenersessionCreated(HttpSessionEvent arg0)
sessionDestroyed(HttpSessionEvent arg0)
HttpSessionAttributeListenerattributeAdded(HttpSessionBindingEvent arg0)
attributeRemoved(HttpSessionBindingEvent arg0)
attributeReplaced(HttpSessionBindingEvent arg0)
   
requestServletRequestListenerrequestInitialized(ServletRequestEvent arg0)
requestDestroyed(ServletRequestEvent arg0)
ServletRequestAttributeListenerattributeAdded(ServletRequestAttributeEvent arg0)
attributeRemoved(ServletRequestAttributeEvent arg0)
attributeReplaced(ServletRequestAttributeEvent arg0)

 

  

 

转载于:https://www.cnblogs.com/-beyond/p/10065860.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值