request和response是什么? request是请求,在浏览器输入地址,回车,就是一个请求 response是响应,服务器根据请求,返回数据到浏览器显示,就是一个响应 第一,response 1 HttpServletResponse是一个子接口,ServletResponse是父接口,是服务器响应对象 2 http分为三个部分 1.响应行 设置状态码 setStatus(int sc) response.setStatus(302); 2.响应头 是key-value结构,一个key对应一个value,可以一个key对应多个value (常用)设置响应头setHeader(String name , String value);一个key对应一个value 响应名称 响应参数 setHeader("aa","11"); setHeader("aa","22"); 结果是 aa : 22 setIntHeader(String name ,int value) setDateHeader(String name ,long date)毫秒值 针对是addHeader(String name ,int value)一个key对应多个value addHeader("bb","55"); addHeader("bb","66"); 结果是bb : 55,66 addIntHeader(String name ,int value) addDateHeader(String name ,long date)毫秒值 3.响应体 向页面显示内容 getWriter() 字符流输出 getOutputStream() 字节流输出 第二,重定向 使用重定向实现登录操作 1.需求 在登入页面中,输入用户名和密码,判断输入的用户和密码是否正确 如果用户名和密码都正确,登录成功,向页面输出内容 如果用户名或者密码有一个是错误的,重定向(2次请求,2次响应)到登录页面 2.步骤 第一步:创建登录页面,写表单,在表单里面写两个输入项,一个输入用户名,一个输入密码, 提交到一个servlet里面 第二步:创建servlet,在这个servlet里面首先获取到输入的用户名和密码, 根据用户名和密码进行判断(用户名如果是admin,密码如果是123456表示正确的) 如果用户名和密码都正确,登录成功,向页面输出内容; response.getWriter().write("login success"); 否则重定向到登录页面 重定向的代码简写的方式 response.sendRedirect("要重定向到的页面的路径"); String login = request.getParameter("login"); String password = request.getParameter("password"); if ("admin".equals(login) && "123456".equals(password)) { response.getWriter().write("login success"); } else {//重定向 /*response.setStatus(302); response.setHeader("Location", "http://localhost:8080/day08_my/html/demo02_other.html"); */ response.sendRedirect("http://localhost:8080/day08_my/html/demo02_other.html"); } 第三,定时跳转 当注册一个网站,注册完成之后,5秒之后跳转到登录页面 3.2 实现方式 (1)使用头信息Refresh实现 (2)写法: response.setHeader("Refresh","在几秒值后跳转;url=要跳转到页面的路径"); 3.3 创建servlet,在servlet实现,在五秒之后跳转到一个页面 response.setHeader("Refresh", "3;url=http://localhost:8080/day08_my/html/demo02.html"); 如:后台解决 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setHeader("Refresh", "3;url=http://localhost:8080/day08_my/html/demo02.html"); response.setContentType("text/html; charset=UTF-8"); response.getWriter().write("Demo03Servlet---3秒之后跳转"); } 前台解决 <html> <head> <meta http-equiv="Refresh" content="3;url=http://localhost:8080/day08_my/html/demo02.html"> </head> <body> <h1>Demo03.html---3秒之后跳转</h1> </body> </html> 倒计时 <!DOCTYPE html> <html> <head> <title>demo03.html</title> <meta http-equiv="Refresh" content="3;url=http://localhost:8080/day08_my/html/demo02.html"> </head> <!--3秒之后跳转--> <body> <h1>Demo03.html---<span id="spanid">3</span>秒之后跳转</h1> </body> <script type="text/javascript"> //显示3,2,1,...倒数 var time=2; function loadTime(){ var span = document.getElementById("spanid"); span.innerHTML=time--; } setInterval("loadTime()", "1000"); </script> </html> 第四,设置响应体 1 使用字节流向页面输出 * 1、设置浏览器的编码 * 2、设置字节数组的编码 * 让浏览器的编码和字节数组的编码一致 // <meta http-equiv="content-type" content="text/html; charset=UTF-8"> response.setHeader("content-type", "text/html; charset=UTF-8"); response.getOutputStream().write("4.1 使用字节流向页面输出内容".getBytes("UTF-8")); 2 使用字符流向页面输出 * 解决方法: * 1、设置response缓冲区的编码 * 2、设置浏览器的编码 * response缓冲区的编码和浏览器的编码一致 response.setCharacterEncoding("UTF-8"); // <meta http-equiv="content-type" content="text/html; charset=UTF-8"> response.setHeader("content-type", "text/html; charset=UTF-8"); response.getWriter().write("4.2 使用字符流向页面输出内容"); 第五,流的注意事项 5.1 字符流向页面输出中文乱码问题解决,简写方式 // <meta http-equiv="content-type" content="text/html; charset=UTF-8"> reesponse.setContentType("text/html; charset=UTF-8"); response.getWriter().write("4.2 ,简写 ,使用字符流向页面输出内容"); 5.2 字节流和字符流是互斥的 5.3 使用字符流不能直接向页面输出数字 //根据数字到码表中查询数字对应的字符,把字符输出 response.setCharacterEncoding("utf-8"); response.getWriter().write(111); 第六,验证码的案例 第一步:生成图片 第二步:生成随机的数字和字母 第三步:把数字和字母画到图片上 第四步:把图片显示到页面上 /* * 代码实现验证码 */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //生成图片 int width = 150; int height = 60; BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR); //得到画笔 Graphics2D g2d = (Graphics2D) bufferedImage.getGraphics(); //生成四个随机的数字和字母 String words = "asdfghjklqwertyuiopzxcvbASDFGHJKLQWERTYUIOPZXCVB1234567890"; //创建Random对象 Random r = new Random(); int x = 25; int y = 25; //设置颜色 g2d.setColor(Color.YELLOW); //设置字体的样式 g2d.setFont(new Font("宋体",Font.BOLD,25)); //rotate(double theta, double x, double y) //弧度=角度*3.14/180 for(int i=1;i<=4;i++) { int idx = r.nextInt(words.length()); //根据位置得到具体的字符 char ch = words.charAt(idx); //旋转+- 30度 int jiaodu = r.nextInt(60)-30; double hudu = jiaodu*Math.PI/180; //旋转的效果 g2d.rotate(hudu, x, y); //把字符画到图片上 g2d.drawString(ch+"", x, y); x += 25; //转回去 g2d.rotate(-hudu, x, y); } //生成三条干扰线 g2d.setColor(Color.green); int x1,y1,x2,y2; for(int m=1;m<=3;m++) { x1 = r.nextInt(width); y1 = r.nextInt(height); x2 = r.nextInt(width); y2 = r.nextInt(height); g2d.drawLine(x1, y1, x2, y2); } //把图片显示到页面上 ImageIO.write(bufferedImage, "jpg", response.getOutputStream()); } <!--页面显示验证码--> <body> <form name="f1" id="f1" action="" method="post"> <table border="0"> <tr> <td>Login:</td> <td><input type="text" name="login" id="login"></td> </tr> <tr> <td>Password:</td> <td><input type="password" name="password" id="password"></td> </tr> <tr> <tr> <td>code:</td> <td><img src="http://localhost:8080/day08_my/demo06" id="img1" οnclick="loadCode();"/></td> </tr> <tr> <td colspan="2" align="center"><input type="submit"></td> </tr> </table> </form> </body> <script type="text/javascript"> function loadCode(){ var img1 = document.getElementById("img1"); //这里"/day08_my/demo06"浏览器有缓存,所有需要加一个变量,时间对象是浏览器对象 img1.src="/day08_my/demo06?time="+new Date().getTime(); } </script> 第七,文件的下载 /* 7.1 文件下载的基本实现的步骤 (0)设置头信息 Content-Disposition,无论是什么格式的文件都以下载方式打开 (1)在服务器上面有一个可以下载的文件 (2)从服务器上拿到这个文件(使用文件输入流得到文件) (3)使用输出流把文件写到浏览器 */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //输入关联下载的资源 String path = "/download/a.zip"; InputStream is = getServletContext().getResourceAsStream(path); int lastIndexOf = path.lastIndexOf("/"); String filename = path.substring(lastIndexOf+1); response.setHeader("Content-Disposition", "attachment;filename="+filename); OutputStream os = response.getOutputStream(); int len = 0; byte[] b = new byte[8192]; while ((len=is.read(b))!=-1) { os.write(b, 0, len); } is.close(); os.close(); } 第八,request对象 /* * (1)getMethod() :得到http请求方式 (2)getRequestURI() :得到请求地址(不包含ip+端口号) (3)getProtocol() :得到http的版本 */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //浏览器中 http://localhost:8080/day08_my/rdemo01 // GET System.out.println(request.getMethod()); // day08_my/rdemo01 System.out.println(request.getRequestURI()); // HTTP/1.1 System.out.println(request.getProtocol()); } /* * 8.3 获取请求头的信息 (1)getHeader(java.lang.String name) :根据名称得到请求头的值 = 头信息 User-Agent:获取当前请求的浏览器的类型 = String agent = request.getHeader("User-Agent"); */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //Mozilla/5.0 (Windows NT 6.1; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0 System.out.println(request.getHeader("User-Agent")); } /* * 8.4 获取客户机的信息 (1)getContextPath() :请求项目的名称 (2)getRequestURL() :客户端发送的请求的路径 (3)getRemoteAddr() :获取当前客户端的ip地址 */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 浏览器中 http://localhost:8080/day08_my/rdemo02 // day08_my System.out.println(request.getContextPath()); // http://localhost:8080/day08_my/rdemo02 System.out.println(request.getRequestURL()); // 0:0:0:0:0:0:0:1 System.out.println(request.getRemoteAddr()); } <form name="f1" id="f1" action="http://localhost:8080/day08_my/rdemo04" method="post"> <table border="0"> <tr> <td>Login:</td> <td><input type="text" name="login" id="login"></td> </tr> <tr> <td>Password:</td> <td><input type="password" name="password" id="password"></td> </tr> <tr> <td>love:</td> <td> <input type="checkbox" id="" name="love" value="lanqiu"/>篮球 <input type="checkbox" id="" name="love" value="pingpang"/>乒乓球 <input type="checkbox" id="" name="love" value="yumao"/>羽毛球</td> </tr> <tr> <td colspan="2" align="center"><input type="submit"></td> </tr> </table> </form> //(1)String getParameter(java.lang.String name) :参数是表单输入项name属性的值,根据名称得到输入的值 private void test1(HttpServletRequest request) { String login = request.getParameter("login"); String password = request.getParameter("password"); System.out.println(login); System.out.println(password); } //(2)String[] getParameterValues(java.lang.String name) :参数是表单输入项name的值,针对复选框的情况 private void test2(HttpServletRequest request) { String[] loves = request.getParameterValues("love"); System.out.println(Arrays.toString(loves)); } //(3)Map<java.lang.String,java.lang.String[]> getParameterMap() : public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取所有的name和value Map<String, String[]> map = request.getParameterMap(); Set<Entry<String, String[]>> ens = map.entrySet(); for (Entry<String, String[]> en : ens) { String key = en.getKey(); String[] val = en.getValue(); System.out.println(key+"..."+Arrays.toString(val)); } } request中表单提交的中文数据乱码问题的解决 (1)post提交方式解决方法,会有一个缓冲区 /* * (1)post提交方式解决方法 */ //方法一 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String decode = URLDecoder.decode(request.getParameter("name"), "UTF-8"); System.out.println(decode); } //方法二 private void test1(HttpServletRequest request) throws UnsupportedEncodingException { request.setCharacterEncoding("UTF-8");//会有一个缓冲区 System.out.println(request.getParameter("login")); System.out.println(request.getParameter("password")); } (2)get提交中文乱码解决 改tomcat服务器 <Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="utf-8"/> /* * (2)get提交中文乱码解决 */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String login = request.getParameter("login"); login = new String(login.getBytes("iso8859-1"),"utf-8"); System.out.println(login); } request是域对象:在一定的范围内,可以存值和取值 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setAttribute("name", "张三"); //转发 // request.getRequestDispatcher("/rdemo08").forward(request, response); //重定向 response.sendRedirect("/day08_my/rdemo08"); } /* * 获取request域里面设置的那个值 */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = (String) request.getAttribute("name"); System.out.println(name); } 重定向和转发的区别 第一,重定向代码是 response.sendRedirect(""); 说明是服务器端的方法 2次请求,2次响应,路径是有项目名称的 域对象用session来保存数据 第二,转发代码是 request.getRequestDispatcher("").forward(request, response); 说明是服务器端的方法 1次请求,1次响应,路径是不包含项目名称 域对象用request来保存数据 重定向:从一个网站到另一个网站 转发:请求的过程中需要携带数据 第九,使用request域对象+转发实现登录功能 (1)创建登录页面,在登录页面中写表单,提交到servlet里面 (2)创建servlet,在servlet里面获取表单提交的数据,判断用户名和密码是否正确 (3)如果用户名和密码都正确,表示登录成功,向页面输出内容 (4)如果用户名或者密码错误,表示登录失败,转发到登录页面(同时向页面显示错误信息) = 转发的代码:request.getRequestDispatcher("登录的页面 不带项目名称").forward(request, response); = 传递数据的页面:首先把显示内容放到request域里面,使用转发到登录页面,在登录页面中使用el表达式获取 request域里面的值 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'MyJsp.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <form name="f1" id="f1" action="/day08_my/reqDemo09" method="post"> <table border="0"> <tr> <td>Login:</td> <td><input type="text" name="login" id="login"></td> </tr> <tr> <td>Password:</td> <td><input type="password" name="password" id="password"></td> </tr> <tr> <td colspan="2" align="center"><input type="submit"></td> </tr> </table> </form> <!-- 传递数据的页面: 首先把显示内容放到request域里面,使用转发到登录页面, 在登录页面中使用el表达式获取request域里面的值 --> ${msg}<br/> </body> </html> public class ReqDemo09 extends HttpServlet { /* * 9、转发的案例 9.1 使用request域对象+转发实现登录功能 (1)创建登录页面,在登录页面中写表单,提交到servlet里面 (2)创建servlet,在servlet里面获取表单提交的数据,判断用户名和密码是否正确 (3)如果用户名和密码都正确,表示登录成功,向页面输出内容 (4)如果用户名或者密码错误,表示登录失败,转发到登录页面(同时向页面显示错误信息) */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取表单提交的数据 String login = request.getParameter("login"); String password = request.getParameter("password"); //判断用户名和密码 if ("admin".equals(login) && "123456".equals(password)) { //如果用户名和密码都正确,表示登录成功,向页面输出内容 response.setContentType("text/html; charset=UTF-8"); response.getWriter().write("登录成功"); }else{ //用户名或者密码错误,表示登录失败,转发到登录页面(同时向页面显示错误信息) request.setAttribute("msg", "用户名或密码错误"); request.getRequestDispatcher("/html/rdemo09.jsp").forward(request, response); } } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }