一、servlet
服务器端小程序。
是运行在web服务器之上,在服务器端调用、执行、并按servlet规范编写的java类。
对客户端的请求进行处理,对客户端返回响应。
servlet容器:web服务器中专门负责装载、运行servlet的一个模块。
继承servlet就可以请求和响应。
1.方法
- init():在servlet实例化后,调用service之前调用init()方法
- service():调用此方法允许servlet响应请求,在servlet成功初始化之前无法调用。
- destory():当一个servlet被从服务中去除时,servlet容器会调用此方法。在这个对象service()方法所有的线程未全部退出或者没有被容器认为发生超时操作时,此方法不会被调用。
- getServletConfig:返回一个* ServletConfig对象,作为一个servlet的开发者,应该通过init()方法存储ServletConfig对象以便这个方法能返回这个对象。
getServletInfo():允许servlet向主机的servlet运行者提供有关信息。
2.servlet生命周期
加载和实例化
- 查看部署描述符(web.xml)对于sevlet的定义
- ServletConfig包含web程序部署描述符中定义的参数。Servlet实例化的同时实例化对应的ServletConfig对象,并传入到init(ServletConfig config)
- 每个web应用启动后,Servlet容器都会创建唯一的一个ServletContext对象,该对象包含整个web程序的信息。getServletContext()读取< context-param>内的数据
第一次访问servlet时,在服务器启动加载网站时,具体什么时候加载需要通过web.xml配置文件中,对应servlet设置项的< load-on-startup>节点进行设置。
< load-on-startup>元素标记容器是否应该在web应用程序启动时加载这个servlet,调用init()方法。
如果该值为负数或者没有设置,则容器会当Servlet被请求时再加载。
如果值为正整数或者0时,表示容器在应用启动时就加载并初始化这个servlet,值越小,servlet的优先级越高,就越先被加载
Servlet对init方法调用
init(ServletConfig config)方法:
- 在一个servlet的生命周期只执行一次
- 通过config.getInitParameter(param)可取得web.xml中的参数
处理客户端请求
servlet调用destory()方法
- 在一个servlet生命周期中只执行一次
二、request和response
1.请求与响应
javax.servlet.ServletRequest:service()
javax.servlet.http.HttpServletRequest:
doGet(),doPost(),service()
2.转发请求和重定向
request.setAttribute(String,Object);
request.getAttribute(String);
请求转发:request.getRequestDispatcher(“targetURL”).forward(request,reponse);
重定向:request.sendRedirect(“targetURL”);
3.数据共享方式
- 在请求request和request之间,通过request的set/getAttribute方法:只能应用于请求转发。
- 在客户端和服务端程序(servlet)之间,通过请求request.getParameter()方法共享数据。
- 同一个servlet对象,通过servletConfig对象共享数据。
- 在整个web应用范围内,通过ServletContext的set/getAttribute方法共享数据。
servlet非线程安全。
HttpServletRequest和HttpServletReponse
Http协议前后端的连接
HttpServletRequest
客户端浏览器发出的请求被封装成为一个HttpServletRequest对象。包括请求地址,请求头,实体数据
举例如下:
POST /examples/default.jsp HTTP/1.1
Accept: text/plain; text/html
Accept-Language: en-gb
Connection: Keep-Alive
Host: localhost
User-Agent: Mozilla/4.0 (compatible; MSIE 4.01; Windows 98)
Content-Length: 33
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip, deflate
lastName=Franks&firstName=Michael
常用方法
- 获得客户机信息
- getRequestURL:返回客户端发出请求时完整的URL
- getRequestURI:返回请求行中的资源名部分
- getQueryString:返回请求行中的参数部分
- getRemoteAddr:返回发出请求的客户机的ip地址
- getRemoteHost:返回发出请求的客户机的完整主机名
- getRemotePort:返回客户机所使用的网络端口号
- getLocalAddr:返回为 服务器的IP地址
- getLocalName:返回WEB服务器的主机名
- getMethod:得到客户机请求方式
- getServerPath:获取请求的文件的路径
- 获得客户机请求参数
- getHeader(String name)
- getHeaders(String name)
- GetHeaderName()
- 获得客户机请求参数(客户端提交的数据)
- getparameter(name):获取请求中的参数,该参数由name指定
- getParameterValues(String name):适用于一个参数名对应多个值的情况,如页面表单中的复选框,多选列表提交的值。
- getParameterNames():返回一个包含请求信息中的所有参数名的Enumeration对象,就可以获取消息列中所有的参数名。
- getCharacterEncoding():返回请求的字符编码方式
- getAttributeNames():返回当前请求的所有属性的名字集合
- getAttribute(String name):返回name指定的属性值
- getSession():返回客户端相关的session,如果没有客户端分配session,则返回null
- getParameterMap():返回一个保存了请求消息中的所有参数名和值的Map对象,Map对象的key是字符串类型的参数名,value是这个参数所对应的object类型的值数组。
- getRequestDispatcher(targetURL).forward(request,response):方法的请求结束后,浏览器地址保持初始的URL地址不变。方法在服务器端内部将请求转发给另外一个资源,浏览器只知道发出了请求并得到了响应结果,并不知道服务器程序内部发生了转发行为。
- setCharacterEncoding(“utf-8”):设置编码
- getReader():获取请求体的数据流
- getInputStream():获取请求的输入流中的数
乱码原因及解决方案
java程序中默认的是中文字符 ----- Unicode
系统会把在java程序中的unicode字符按照某种字符集编码的方式转换成字节数组,再通过浏览器在输出的时候要进行解码。只有两种方式一样的情况下,才不会出现乱码。
response.setContentType(“text/html;charset=utf-8”)
request.setCharacterEncoding(“utf-8”)
系统默认的编码方式为ISO08859-1,如果没有指定字符编码,不支持中文,则输出的都是乱码。
解决方案:
- post提交:客户端和服务器设置统一的编码,服务器端request.setCharacterEncoding(charset)进行设置。
- get获取:以get方式传输数据,以get方式传输数据,request即使设置了以指定的编码接收数据也是无效的,默认以ISO8859-1这个字节编码来接收数据,需要如下操作
String name = request.getParameter(“name”);//接收数据
name =new String(name.getBytes(“ISO8859-1”), “UTF-8”) ;//获取request对象以ISO8859-1字符编码接收到的原始数据的字节数组,然后通过字节数组以指定的编码构建字符串,解决乱码问题
HttpServletResponse
HttpServletResponse继承了ServletResponse接口,并提供了与http协议有关的方法,这些方法的主要功能是设置HTTP状态码和管理Cookie。HttpServletResponse对象代表服务器的响应。这个对象中封装了向客户端发送数据、发送响应头、发送响应状态码的方法。
1.常用方法
addHeader(String name,String value):将指定的名字和值加入到响应的头信息中。
encodeURL(“批量模板.xls”,“UTF-8”):编码指定URL
sendError(int src):使用指定状态码发送一个错误到客户端
setDateHeader(String name,long date):将给出的名字和日期设置响应的头部
setHeader(String name,String value)
setStatus(int sc):给当前响应设置的状态码
HttpServletResponse.sendRedirect():对浏览器的请求直接作出响应,响应的结果发出对另外一个URL访问请求
setContentType
setHeader(String name,String name)
getWriter()
getOutputStream()
- 向客户写入中文:
response.setCharacterEncoding("UTF_8");//设置Response的编码方式为UTF-8
response.setHeader("Content-type","text/html;charset=UTF-8");
//response.setContentType("text/html;charset=UTF-8");同上句代码作用一样
PrintWriter writer = response.getWriter();
writer.write("中国");
2.下载文件
HttpServletResponse对象就可以实现文件的下载
- 文件下载功能实现的思路:
- 获取要下载的文件的绝对路径
- 获取要下载的文件名
- 设置content-disposition响应头控制浏览器以下载的形式打开文件
- 获取要下载文件输入流
- 创建数据缓存区
- 通过resonse对象获取outputstream流
- 将FileInputStream流写入到buffer缓存区
- 使用outputStrem将缓存区的数据输出到客户端浏览器
例子:
private void downloadFileByOutputStream(HttpServletRequest request,HttpServletResponse response){
//1.获取要下载的文件的绝对路径
String realPath = this.getServletContext().getRealPath("/download/1.JPG");
//另一种方式:request.getSession().getServletContext().getRealPath("/download/1.JPG");
//2.获取要下载的文件名
String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);
//3.设置content-disposition响应头控制浏览器以下载的形式打开文件
response.setHeader("content-disposition", "attachment;filename="+fileName);
//4.根据文件路径获取要下载的文件输入流
IntputStream 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();
}
三 四种常见的POST提交数据方式
详见链接:https://imququ.com/post/four-ways-to-post-data-in-http.html