ServletResponse
概述
设置响应报文
response.setStatus(404);
response.setHeader("Content-Type","text/html;charset=utf-8");
response.getWriter().println("<h1 style='color:red'>File Not Found</h1>");
输出字符数据
输出数据到响应报文的响应体
response.getWriter().println()
中文乱码
设置服务器传输的编码方式:只能设置服务器传输的编码,不能告诉客户端
response.setCharacterEncoding("utf-8");
通过响应头将编码格式告诉给客户端,默认会设置服务器的编码
response.setHeader("Content-Type", "text/html;charset=utf-8");
resp.setContentType("text/html;charset=utf-8");
通过响应体
使用这种方式,一定要先设置客户端的编码格式
<meta charset=“UTF-8”>这个标签是告诉客户端的解码
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置响应报文
response.setCharacterEncoding("utf-8");
//设置客户端解码
response.getWriter().println("<!DOCTYPE html>\n" +
"<html lang=\"en\">\n" +
"<head>\n" +
" <meta charset=\"UTF-8\">\n" +
" <title>Title</title>\n" +
"</head>\n" +
"<body>");
response.getWriter().println("你好!!!!");
response.getWriter().println("</body>\n" +
"</html>");
}
输出字节数据
使用ServletOutputStream,输出到response的缓冲区内,相当于输出进一个数组,然后由tomcat帮我们转出去
String realPath = getServletContext().getRealPath("WEB-INF/1.jpeg");
FileInputStream fileInputStream = new FileInputStream(new File(realPath));
ServletOutputStream outputStream = response.getOutputStream();
int length = 0;
byte[] bytes = new byte[1024];
while ((length = fileInputStream.read(bytes)) != -1){
outputStream.write(bytes, 0, length);
}
这里要注意,输出字符数据和字节数据不能同时应用,否则会乱码,并且在输出字节数据的时候,如果掺杂着输出字符数据,那么肯定会出现乱码,原因是中文字符编码混入了二进制文件中,那么就会导致出错
页面跳转
定时跳转refresh
值可以设置一个数字,表示每隔多少秒刷新一下当前的页面,或者传入一个数字+url,表示隔多少秒后跳转到该url
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// System.out.println("1");每隔1秒刷新页面
response.getWriter().println(new Date());
response.setHeader("refresh", "1");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// System.out.println("1");
// response.getWriter().println(new Date());
//隔两秒后跳转到新的页面
response.setHeader("refresh", "2;url=" + request.getContextPath() + "/1.html");
}
重定向
发送一个301、302、307的状态码,同时响应头搭配一个Location,浏览器会再次往新的地址发起请求
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//重定向
// response.setStatus(302);
// response.setHeader("Location", request.getContextPath() + "/info.html");
//其实ee规范中给我们提供了一个简化的写法
response.sendRedirect(request.getContextPath() + "/info.html");
}
页面跳转之间的区别
1.转发是request介导的;另外两个是response介导的
2.转发是一次请求;另外两个是多次请求
3.转发是服务器行为;另外两个是浏览器行为
4.重定向状态码是302;另外是200
5.转发局限性:只能在应用内跳转;另外两个不受限制
页面登陆跳转案例
登陆页面实现登陆的功能—>转发到欢迎页面---->点击注销---->跳转到注销的重定向—>回到注册页面
分次实现
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/servlet/login" method="post">
<input type="text" name="username"><br>
<input type="password" name="password"><br>
<input type="submit">
</form>
</body>
</html>
package com.fh.login;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//这里面需要获取到登陆传入的用户名和密码来判断是否登陆成功
//将用户名的信息通过request域转发给欢迎页面
String username = request.getParameter("username");
String password = request.getParameter("password");
if (username.equals("username")&&password.equals("password")){
//进行一个简单的判断
//登陆成功
request.setAttribute("username",username);//设置共享的username
//转发给欢迎页面
request.getRequestDispatcher("/info").forward(request,response);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
package com.fh.login;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/info")
public class InfoServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//需要响应欢迎,并且提供一个标签跳转到注销页面
response.setContentType("text/html;charset=utf-8");//设置中文编码
//获取转发过来的username并生成欢迎标语
Object username = request.getAttribute("username");
response.getWriter().println("欢迎你!"+username+"<a href='"+request.getContextPath()+"/logout'>点我注销</a>");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
package com.fh.login;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/logout")
public class logoutServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//因为是跳转过来,所以肯定是get请求,那么这里需要处理的是重定向到登陆的页面
response.sendRedirect(request.getContextPath()+"/login.html");
}
}
集中实现,使用一个servlet
使用这种方法的核心要点就在于,/user/*可以处理任何的以/user/开头的servlet,那么利用这一点,我们只需在同一个servlet中写出各种方法,只要方法调用的名字符合这个格式,那么就能用同一个servlet来解决,在dopost和doget中写出对应就方法即可
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/servlet/user/login" method="post">
<input type="text" name="username"><br>
<input type="password" name="password"><br>
<input type="submit">
</form>
</body>
</html>
package com.fh.login2;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/user/*") //设置为/user/*意味着可以处理任何/user/xxx的servlet
public class UserServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//首先要根据拿到的uri来判断是什么方法,然后找到对应的方法执行即可
String requestURI = request.getRequestURI();
//如果跳转到这里处理,那么说明拿到的uri的格式一定是/应用名/user/xxx
//那就将前面的部分替换成空白,这样就能拿到后面的xxx的部分
String replace = requestURI.replace(request.getContextPath() + "/user/", "");
if (replace.equals("login")){
//login是post请求,那么会跳到这里,进行处理
login(request,response);//实现一个login方法
}else if (replace.equals("info")){
//info也是post请求,那么也应该放在这里处理
info(request,response);
}
}
private void info(HttpServletRequest request, HttpServletResponse response) throws IOException {
//需要响应欢迎,并且提供一个标签跳转到注销页面
response.setContentType("text/html;charset=utf-8");//设置中文编码
//获取转发过来的username并生成欢迎标语
Object username = request.getAttribute("username");
response.getWriter().println("欢迎你!"+username+"<a href='"+request.getContextPath()+"/user/logout'>点我注销</a>");
}
private void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
if (username.equals("username")&&password.equals("password")){
//进行一个简单的判断
//登陆成功
request.setAttribute("username",username);//设置共享的username
//转发给欢迎页面
request.getRequestDispatcher("/user/info").forward(request,response);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String requestURI = request.getRequestURI();
String replace = requestURI.replace(request.getContextPath() + "/user/", "");
if (replace.equals("logout")){
//logout是get请求,放在get里面来处理
logout(request,response);
}
}
private void logout(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.sendRedirect(request.getContextPath()+"/login2.html");
}
}
获取请求参数的方式来实现
/u?op=login
/u?op=info
/u?op=logout
每次在访问的过程中,都在后面手动拼接一个请求参数即可
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/servlet/u?op=login" method="post">
<input type="text" name="username"><br>
<input type="password" name="password"><br>
<input type="submit">
</form>
</body>
</html>
package com.fh.login2;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/u") //设置为/u,后面根据请求来判断
public class UserServlet2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求参数
String op = request.getParameter("op");
if (op.equals("login")){
//login是post请求,那么会跳到这里,进行处理
login(request,response);//实现一个login方法
}else if (op.equals("info")){
//info也是post请求,那么也应该放在这里处理
info(request,response);
}
}
private void info(HttpServletRequest request, HttpServletResponse response) throws IOException {
//需要响应欢迎,并且提供一个标签跳转到注销页面
response.setContentType("text/html;charset=utf-8");//设置中文编码
//获取转发过来的username并生成欢迎标语
Object username = request.getAttribute("username");
response.getWriter().println("欢迎你!"+username+"<a href='"+request.getContextPath()+"/u?op=logout'>点我注销</a>");
}
private void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
if (username.equals("username")&&password.equals("password")){
//进行一个简单的判断
//登陆成功
request.setAttribute("username",username);//设置共享的username
//转发给欢迎页面
request.getRequestDispatcher("/u?op=info").forward(request,response);
}
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String op = request.getParameter("op");
if (op.equals("logout")){
//logout是get请求,放在get里面来处理
logout(request,response);
}
}
private void logout(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.sendRedirect(request.getContextPath()+"/login3.html");
}
}
下载
浏览器的行为:
Accept : * / * .
浏览器对于那部分可以打开的文件执行打开操作,对于无法打开的文件,执行下载操作
设置一个响应头,那么会将资源下载到本地,而不是打开
response.setHeader("Content-Disposition", "attachment;filename=1.jpeg");
常见的使用场景:导出到Excel表格