java web开发(五)请求和响应
一 HttpServletRequest
它继承自ServletRequest,用来封装HTTP请求消息。它提供了获取请求行,请求头和请求消息体的相关方法。
1.获取请求行方法
public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html;charset=utf-8"); PrintWriter out = resp.getWriter(); out.println(req.getMethod()+"<br>");//获取请求行中请求方式 out.println(req.getRequestURI()+"<br>");//获取请求行中资源名称 out.println(req.getQueryString()+"<br>");//获取请求行中参数部分,?后面的参数 out.println(req.getProtocol()+"<br>");//获取请求行中协议名和版本,HTTP1.1 out.println(req.getContextPath()+"<br>");//获取相对与Web站点根目录的web应用程序的路径 out.println(req.getServletPath()+"<br>");//获取Servlet的名称或Servlet所映射的路径 } }
2.获取请求头方法
public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html;charset=utf-8"); PrintWriter out = resp.getWriter(); //获取请求中的所有头字段 Enumeration names = req.getHeaderNames();//返回集合对象,由头字段组成,可能会重复 while(names.hasMoreElements()){ String header = (String) names.nextElement(); out.println(header+":"+req.getHeader(header)); } } }
3.获取消息体方法
- getInputStream():如果实体内容为非文本,只能通过该方法获取消息体。
- getReader():该对象会将实体内容中的字节数据按照请求消息中指定的字符集编码转换为文本字符串。如果在请求消息中不指定实体内容的字符编码,那么,返回的字节数据将采用ISO8859-1进行解码。
public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html;charset=utf-8"); InputStream in = req.getInputStream(); byte[] buffer = new byte[1024]; StringBuilder sb = new StringBuilder(); int len; while((len=in.read(buffer)) != -1){ sb.append(new String(buffer, 0, len)); } System.out.println(sb); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
4.请求中文乱码问题
原因:字符与字节之间的转换是通过查码表完成的,将字符转换成字节的过程称为编码,将字节转换成字符的过程称为解码,当编码和解码使用的码表不一致时,就导致乱码问题,因此请求中文乱码是由于客户端编码方式和Servlet解码方式不一致导致的。
解决:以utf-8编码为例
在jsp文件中指定contentType:
<%@ page contentType="text/html;charset=utf-8" language="java" %>
在Servlet中添加代码:
req.setCharacterEncoding("utf-8");
5.防盗链
原理:浏览器向服务器发出的请求,可能是直接在浏览器中输入URL地址而发出,也可能是单击一个超链接而发出的,对于第一种情况,浏览器不会发出Referer请求头,而对于第二种情况,浏览器会使用Referer头字段标识发出请求的超链接所在网页的URL,我们就可以通过判断该URL,允许或阻止该请求。
//Servlet
public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { try { resp.setContentType("text/html;charset=utf-8"); PrintWriter out = resp.getWriter(); req.setCharacterEncoding("utf-8"); String referer = req.getHeader("referer"); String site = "http://" + req.getServerName();//获取域名localhost if(referer!=null && referer.startsWith(site)){ out.println("合法请求"); } else { out.println("非法请求"); } } catch (Exception e) { e.printStackTrace(); } }
//download.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>下载页面</title> </head> <body> <a href="/HelloServlet">download</a> </body> </html>
6.传递数据
- setAttribute:设置属性
- getAttribute:获取属性
- removeAttribute:删除指定名称的属性
- getAttributeNames:返回所有属性名的Enumeration对象
二 HttpServletResponse
1.响应状态行
setStatus(int status):设置HTTP响应消息的状态码,并生成响应状态行。状态描述信息直接与状态码相关,二http版本由服务器确定。
sendError(int sc):发送错误信息的状态码。
2.响应消息头
addHeader(String name, String value) | 设置头字段,可以增加同名字段 |
setHeader(String name, String value) | 设置头字段,会覆盖同名字段 |
setContentLength(int len) | 设置实体内容的大小,单位为字节。 |
setContentType(String type) | 设置输出内容的MIME类型;如果响应的内容是文本,也可以通过该字段设置字符编码 |
setCharacterEncoding(String charset) | 设置输出内容使用的字符编码,它的优先级比setContentType和setLocale方法高,它设置结果会覆盖这两个设置的参数 |
3.响应消息体
1.getOutputStream()
获取字节输出流ServletOutputStream对象,它可以直接输出二进制数据。
2.getWriter()
获取字符输出流PrintWriter对象,用于输出字符文本内容。
4.响应中文乱码问题
原因:字符与字节之间的转换是通过查码表完成的,将字符转换成字节的过程称为编码,将字节转换成字符的过程称为解码,当编码和解码使用的码表不一致时,就导致乱码问题,因此响应中文乱码是由于客户端解码方式和Servlet编码方式不一致导致的。
解决:
由于浏览器默认一般是GBK解码格式,因此我们向浏览器输出内容时,需要用下面的代码设置下输出内容:
response.setContentType("text/html;charset=gbk");
三 RequestDispatcher
如果服务器通知另一个资源去处理客户端的请求,除了使用sendRedirect()方法实现请求重定向,还可以通过RequestDispatcher实现。
getRequestDispatcher(String path) | 返回封装所指资源的diapatcher对象,path以“/”开头。 |
forward(req, resp) | 将请求从一个Servlet传递给另外的资源,它必须在最终响应提交给客户端之前被调用,否则报异常。 |
include(req, resp) | 将其他资源作为当前响应内容包含进来 |
1.forward方法
当前Servlet不想处理客户端请求,可以通过该方法将当前请求传递给其他Web资源处理,这种方式称为请求转发。当然,Servlet也可以封装数据到req或resp中,将数据传递给后面的资源,从而实现数据共享。
2.include方法
当前Servlet将请求交给其他资源处理,当返回给客户端时,响应结果会将其他资源的处理结果包含进来一同返回,有并行处理的意思;其他资源的req和resp和当前Servlet是不同的。
转载于:https://my.oschina.net/kun123/blog/912062