Servlet的创建方式
1)实现Servlet接口
2)继承GenericServlet
3)继承HttpServlet
servlet何时被创建
1)默认情况下,用户第一次访问servlet实例的时候,web容器将创建这个servlet实例
2)web.xml如果指定了load-on-startup,servlet容器在创建servlet时会按照优先级加载servlet
- 当num值为0或者大于0时,表示容器在应用启动时就加载这个servlet。
- 当num值小于0或者没有指定时,则指示容器在该servlet被选择时才加载。
- 正数的值越小,启动该servlet的优先级越高。
配置初始化参数
在Servlet的配置文件web.xml中,可以使用一个或多个
其实相当于某个servlet的局部变量。将配置信息放在在web.xml中可以方便修改。
配置:
basic
com.briup.prep.day01.BasicServlet
username
licy
1
获取:
String password = getServletConfig().getInitParameter("username");
ServletContext对象
ServletContext application
值的范围是:一个应用
WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。
ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过config.getServletContext()方法获得ServletContext对象。
它相当于整个服务器的全局变量,也就是说只有关闭服务器的时候才找不到改数据
-
多个Servlet通过ServletContext对象实现数据共享
ServletContext context = this.getServletConfig().getServletContext();
//获得ServletContext对象
context.setAttribute("data", data); //将data存储到ServletContext对象中 -
获取WEB应用的初始化参数
url jdbc:mysql://localhost:3306/test -
用servletContext实现请求转发
context.getRequestDispatcher("/login.jsp").forward(request, response);
-
使用servletContext读取资源文件db.properties中保存的是类似与driver=com.mysql.driver.Driver的配置信息
InputStream is = context.getResourceAsStream("/WEB-INF/init/db.properties"); Properties prop = new Properties(); prop.load(is); String name = (String) prop.getProperty("name"); String gender = prop.getProperty("gender");
HttpServletResponse
-
向客户端(浏览器)发送数据的相关方法
getOutputStream() getWriter()
-
向客户端(浏览器)发送响应头的相关方法
addDateHeader() addHeader() addIntHeader() containsHeader() setDateHeader() setHeader() setIntHeader() 例如: response.setHeader("content-type", "text/html;charset=UTF-8");
下载实例:
private void downloadFileByOutputStream(HttpServletResponse response)
throws FileNotFoundException, IOException {
//1.获取要下载的文件的绝对路径
String realPath = this.getServletContext().getRealPath("/download/1.JPG");
//2.获取要下载的文件名
String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);
//3.设置content-disposition响应头控制浏览器以下载的形式打开文件
response.setHeader("content-disposition", "attachment;filename="+fileName);
//4.获取要下载的文件输入流
InputStream in = new FileInputStream(realPath);
int len = 0;
//5.创建数据缓冲区
byte[] buffer = new byte[1024];
//6.通过response对象获取OutputStream流
OutputStream out = response.getOutputStream();
//7.将FileInputStream流写入到buffer缓冲区
while ((len = in.read(buffer)) > 0) {
//8.使用OutputStream将缓冲区的数据输出到客户端浏览器
out.write(buffer,0,len);
}
in.close();
}
HttpServletRequest
HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,
HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,
可以获得客户端请求的所有信息。
-
- 作为容器
setAttribute(String name,Object o) 将数据作为request对象的一个属性存放到request对象中
getAttribute(String name) 获取request对象的name属性的属性值
removeAttribute(String name)移除request对象的name属性
getAttributeNames() 获取request对象的所有属性名
- 作为容器
-
- 获得客户机信息
getRequestURL() 返回客户端发出请求时的完整URL。
getRequestURI() 返回请求行中的资源名部分。
getRemoteAddr() 返回发出请求的客户机的IP地址。
getRemoteHost() 返回发出请求的客户机的完整主机名。
getRemotePort() 返回客户机所使用的网络端口号。
getLocalAddr() 返回WEB服务器的IP地址。
getLocalName() 返回WEB服务器的主机名。
getQueryString()返回请求行中的参数部分。
getPathInfo() 返回请求URL中的额外路径信息。
额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以“/”开头。
-
- 获得客户机请求头
getHeader(string name)
getHeaders(String name)
getHeaderNames()
-
- 获得客户机请求参数(客户端提交的数据)
getParameter(String) 方法(常用)
getParameterValues(String name)方法(常用)
getParameterNames() 方法(不常用)
getParameterMap() 方法(编写框架时常用)
- 获得客户机请求参数(客户端提交的数据)
-
- request接收表单提交中文参数乱码问题解决
get方式提交表单:
对于以get方式传输的数据,request即使设置了以指定的编码接收数据也是无效的,
默认的还是使用ISO8859-1这个字符编码来接收数据,客户端以UTF-8的编码传输数据到服务器端,而服务器端的request对象使用的是ISO8859-1这个字符编码来接收数据,服务器和客户端沟通的编码不一致因此才会产生中文乱码的。
(1)get方式的解决方案:
在接收到数据后,先获取request对象以ISO8859-1字符编码接收到的原始数据的字节数组,然后通过字节数组以指定的编码构建字符串,解决乱码问题。
- request接收表单提交中文参数乱码问题解决
String name = request.getParameter("name");//接收数据
//获取request对象以ISO8859-1字符编码接收到的原始数据的字节数组,
name =new String(name.getBytes("ISO8859-1"), "UTF-8") ;
然后通过字节数组以指定的编码构建字符串,解决乱码问题
(2) server.xml中配置
URIEncoding=utf-8
3)post方式提交表单:
之所以会产生乱码,就是因为服务器和客户端沟通的编码不一致造成的,因此解决的办法是:在客户端和服务器之间设置一个统一的编码,之后就按照此编码进行数据的传输和接收。
request.setCharacterEncoding("UTF-8");
response.setHeader("content-type", "text/html;charset=utf-8");
-
- Request对象实现请求转发
request.getRequestDispatcher("/test.jsp").forward(request, response);
request.getRequestDispatcher("/test.jsp").include(request, response);
调用forward()方法后,原先存放在HttpResponse对象中的内容将会自动被清除
调用include()方法后,原先存放在HttpResponse对象中的内容将不会被清除,内容追加
1)内部跳转
请求次数: 一次
浏览器地址栏地址: 不改变
实现方式: request.getRequestDispatch()
application.getRequestDispatch()
2)外部跳转
请求次数: 两次
浏览器地址栏地址:改变
实现方式:response.sendRedirect();
Cookie & Session
1) Cookie
Cookie在服务器端产生的,以文件的形式保存在客户端的,
客户端每次发送请求,都会将相应的Cookie发送给服务器端
创建Cookie Cookie c = new Cookie()
保存Cookie response.addCookie(c) 传递到浏览器端,浏览器就会保存一个cookie,下次请求相同的路径时就要携带cookie
得到所有的Cookie request.getCookies();
cookie的存活期:默认为-1,会话cookie
会话Cookie:把Cookie保存到浏览器上,当存活期为负数
持久Cookie:把Cookie保存到文件中,当存活期为正数
设置存活期:c.setMaxAge();
2) session
值的范围是:一次会话。
创建于服务器端,保存于服务器,维护于服务器端,每创建一个新的Session,服务器端都会分配一个唯一的ID,并且把这个ID保存到客户端的Cookie中,保存形式是以JSESSIONID来保存的。
- 创建session
1,HttpSession session=request.getSession();
2,request.getSession(true);第二种创建方式,默认为true,有session就调用那个session,没有就自动创建一个
保存数据 setAttribute(string,object)
取数据 getAttribute(key);
设置最大存活期
session.setMaxInactiveInterval(秒数);
当浏览器被禁用,session不能使用的时候,就采用重写URL,就是在URL地址后加上JSESSIONID
String url = response.encodeURL(path);
response.sendRedirect(url);
3)request
值的范围是:一次请求。
路径问题
1)在servlet当中 /-->相当于webcontent,项目的根目录
2)在jsp 当中 /-->相当于webapps,服务器的根目录
过滤器
Filter 并不是一个标准的Servlet ,它不能处理用户请求,也不能对客户端生成响应。主要用于对HttpServletRequest 进行预处理,也可以对HttpServletResponse 进行后处理,是个典型的处理链。
过滤器类:
public class EncodingFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
}
public void init(FilterConfig config) throws ServletException { }
}
配置文件
encodingFilter
<com.briup.filter.EncodingFilter
encodingFilter
/*
Filter的配置与在web.xml配置文件中的无关,Filter的配置可以放在servlet的之上也可以之后。
但是多个Filter的filter-mapping配置的顺序会影响到doFilter()方法的执行顺序。
将请求传递给下一个过滤器:
chain.doFilter(request, response);
监听器
Listener是Servlet的监听器,它可以监听客户端的请求、服务端的操作等。
通过监听器,可以自动激发一些操作,比如监听在线的用户的数量。
当增加一个HttpSession时,就激发sessionCreated(HttpSessionEvent se)方法,
这样就可以给在线人数加1。常用的监听接口有以下几个:
ServletContextListener
ServletContextAttributeListener
SessionListener
SessionAttributeListener
SessionBindingListener
ServletRequestListener
ServletRequestAttributeListener
HttpSessionListener:监听session的创建和销毁
想知道listener什么时候创建的,我们可以写构造函数来实现。
listener的配置
com.huihui.day03.MySessionListener