ServletResponse
响应报文相关API,响应体输出中文乱码问题
响应报文,提供了一系列的API来帮助我们设置相应的属性。再由connector读取里面的属性值,做出响应
- 响应行:状态码
- 响应头:
- 响应体:
- 解决响应体出现的中文乱码
浏览器默认使用get请求方法。
@WebServlet("/response1")
public class ResponseServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setStatus(404); //状态码
resp.setContentType("text/html"); // 设置响应头中的Content-Type 设置之后才能让下面的<h1>正常显示,或者getWriter().println(写出完整的html代码)
// resp.setContentType("text/html;charset=utf-8"); //乱码解决方式1
// resp.setHeader("Content-type","text/html;charset=utf-8"); // 乱码解决方式2
resp.getWriter().println("<h1>File not Found</h1>"); //响应体
resp.getWriter().println("哈哈不可能哈");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
输出字节数据
响应报文可以写入存在二进制文件的数据,怎么传输字节数据?
1.浏览器直接访问1.jpg:
能访问的原因,是缺省servlet的作用(静态资源),缺省servlet找到了当前文件的信息,然后将它的二进制文件数据写出到响应报文中
2.访问web目录下的1.jpg:
@WebServlet("/stream")
public class StreamServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String realPath = getServletContext().getRealPath("WEB-INF/1.jpg"); //获取web的绝对路径,再通过绝对路径的相对路径获得,1.jpg的路径。WEB-INF可以屏蔽浏览器直接访问,但是阻止不了内鬼的背叛
FileInputStream fileInputStream = new FileInputStream(new File(realPath)); //从文件中写入。再通过response的getOutputStream方法读出
ServletOutputStream outputStream = resp.getOutputStream(); //重点,存在response存在getOutputStream方法。能够输出字节数据
byte[] bytes = new byte[1024];
int length = 0;
while((length = fileInputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, length);
}
fileInputStream.close();
}
//关闭流 输出流可以不关,tomcat会再最后做出响应之前帮我们关闭
ServletRequest中路径信息的补充
@WebServlet("/path")
public class ReqPathServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String contextPath = req.getContextPath(); // /app
StringBuffer requestURL = req.getRequestURL(); // http://localhost:8080/app/path
String requestURI = req.getRequestURI(); // /app/path
String servletPath = req.getServletPath(); // /path
System.out.println(contextPath);
System.out.println(requestURL);
System.out.println(requestURI);
System.out.println(servletPath);
}
}
下载
浏览器的原则是对于可以打开的文件默认执行打开,无法打开则执行下载工作(比如exe等),如果希望浏览器将可以打开的文件下载下来,则需要设置一个响应头。
Content-Disposition:attachment;filename=xxx
@WebServlet("/down")
public class DownServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setHeader("Content-Disposition","attachment;filename=1.jpg"); //filename是下载下来的名字
//同样是通过servlet打开资源
ServletOutputStream outputStream = resp.getOutputStream();
String realPath = getServletContext().getRealPath("1.jpg");
FileInputStream fileInputStream = new FileInputStream(realPath);
int length = 0;
byte[] bytes = new byte[1024];
while((length = fileInputStream.read(bytes)) != -1) {
outputStream.write(bytes, 0, length);
}
fileInputStream.close();
}
}
定时刷新
@WebServlet("/refresh")
public class refreshServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// resp.setHeader("refresh","5;url=http://www.cskaoyan.com"); //路径可以写全路径
// resp.setHeader("refresh","3,url=haha/2.html"); // 相对路径,是相对当前页面的路径,同form表单,应用名不会变 --> /app/haha/2.html
resp.setHeader("refresh","3,url=" + req.getContextPath() + "/1.html"); // /app/1.html 应用名不会出现两次
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
重定向
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// resp.setStatus(302);
// resp.setHeader("Location","http://www.cskaoyan.com");
resp.sendRedirect("http://www.cskaoyan.com"); //两步变一步
}
跳转方式的总结
转发包含(用到了两个以上的servlet)
定时刷新
重定向
联系:都可以用来跳转页面
区别:
- 转发只发送了一次请求;定时更新和重定向浏览器发送了两次请求。
- 转发是服务器介导的,定时刷新和重定向是response参与的。
- 转发可以使用request域,刷新和重定向不可以。