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表格