ServletContext
Context:上下文
ServletContext: 代表的是整个应用。一个应用只有一个ServletContext对象。是单例对象。
作用:
域对象:在一定范围内(当前应用),使多个Servlet共享数据。
常用方法:
- void setAttribute(String name,object value);//向ServletContext对象的map中添加数据
- Object getAttribute(String name);//从ServletContext对象的map中取数据
- void rmoveAttribute(String name);//根据name去移除数据
package com.zx.web.lesson01; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/Lesson01Servlet1") public class Lesson01Servlet1 extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub //1.获取一个应用的上下文 ServletContext context=this.getServletContext(); System.out.println(context); //2.往上下文存数据 context.setAttribute("name", "zx it caiji"); } }
package com.zx.web.lesson02; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/Lesson02Servlet1") public class Lesson02Servlet1 extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub /** * 注意:在web.xml中context-param配置的信息不是通过getAttribute方法获取的 */ //String str=(String) this.getServletContext().getAttribute("encoding"); String str=(String) this.getServletContext().getInitParameter("encoding"); System.out.println("web.xml中获取的encoding 值:"+str); } } 结果: web.xml中获取的encoding 值:utf-8
String getRealPath(String path);
ü 根据资源名称得到资源的绝对路径.
ü 可以得到当前应用任何位置的任何资源。
package com.zx.web.lesson03; import java.io.FileInputStream; import java.io.IOException; import java.util.Properties; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/Lesson03Servlet1") public class Lesson03Servlet1 extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub /** * 通过浏览器地址栏访问的路径都是get请求 */ /** * String path="src\\com\\zx\\web\\lesson03\\info.properties"; * 如果是web项目,查找文件时,要从类路径找 */ //String path="src\\com\\zx\\web\\lesson03\\info.properties"; String path=this.getServletContext().getRealPath("WEB-INF\\classes\\com\\zx\\web\\lesson03\\info.properties"); System.out.println(path); //在Servlet中获取info.properties数据 //1.创建属性对象 Properties pro=new Properties(); //2.关联属性文件的路径 pro.load(new FileInputStream(path)); System.out.println(pro.getProperty("username")); //响应客户端 resp.getWriter().write(path); } }
Servlet的转发
package com.zx.web.lesson04; import java.io.IOException; import javax.servlet.RequestDispatcher; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/Lesson04Servlet1") public class Lesson04Servlet1 extends HttpServlet{ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub /** * request:请求 * response:响应,给客户端响应数据 */ //response.getWriter().write("data from servlet1"); //1.获取请求转发的对象 RequestDispatcher rd= request.getRequestDispatcher("/Lesson04Servlet2"); //2.执行转发 rd.forward(request, response); } }
package com.zx.web.lesson04; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/Lesson04Servlet2") public class Lesson04Servlet2 extends HttpServlet{ @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub /** * request:请求 * response:响应 */ response.getWriter().write("data from servlet2"); } }
HTTP:
HTTP消息头
- HTTP消息头是指在超文本传输协议( Hypertext Transfer Protocol ,HTTP)的请求和响应消息中,协议头部分的那些组件。
- HTTP消息头用来准确描述正在获取的资源、服务器或者客户端的行为
- HTTP消息头定义了HTTP事务中的具体操作参数。
- 消息头包括请求时的消息头(请求头)和响应时的消息头(响应头)
HttpServletResponse
Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象。
响应正文(主体)
getWrite(); 字符输出流
getOutputStream(); 字节输出流,可以用来下载文件
响应编码
案例:向客户端输出中文
package com.zx.web.lesson06; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/Lesson06Servlet2") public class Lesson06Servlet2 extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub //响应编码问题 //1.设置响应头 //resp.setContentType("text/html");//设置响应的类型 //resp.setCharacterEncoding("UTF-8"); //设置响应的编码类型 //另外一种解决乱码的写法 resp.setHeader("Content-Type", "text/html;charset=UTF-8"); resp.getWriter().write("张无改-张又改"); } }
响应状态码
常见的状态码参照:http://tool.oschina.net/commons?type=5
404请求失败,请求所希望得到的资源未被在服务器上发现
200请求已成功,请求所希望的响应头或数据体将随此响应返回。
302 重定向
500 服务抛出异常
package com.zx.web.lesson07; import java.io.IOException; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/Lesson07Servlet1") public class Lesson07Servlet1 extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub //响应状态码 /** * 默认情况下,服务器响应给客户端的状态码为200 * 200:ok,没有问题 */ resp.setStatus(404); resp.getOutputStream().write("hello".getBytes()); } }
文件下载
package com.zx.web.lesson08; import java.io.FileInputStream; import java.io.IOException; import java.net.URLEncoder; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/Lesson08Servlet1") public class Lesson08Servlet1 extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub //处理文件下载[把文件的数据(二进制)响应给客户端] //1.文件名 String fileName="啥子.jpg"; String path="E:\\"+fileName; /** * 注意:如果是文件下载,需要设置响应头Content-disposition * 如果文件名中有中文,下载时为了解决乱码问题,需要对文本进行URLEncode,把中文变成百分号形式% * 哈哈.txt=%E5%93%88%E5%93%88.txt * 一个中文会对应三个百分号数据 */ //设置响应类型 fileName=URLEncoder.encode(fileName, "UTF-8"); System.out.println(fileName); resp.setHeader("Content-disposition", "attachment;filename=" + fileName); //2.获取文件输入流 FileInputStream fis=new FileInputStream(path); //3.获取输出流 ServletOutputStream sos= resp.getOutputStream(); //4.从文件中读取数据,响应给客户端 byte[] buf=new byte[1024]; int len=0; while ((len=fis.read(buf))!=-1) { sos.write(buf, 0, len); } //关闭资源(输出流会自动关闭) fis.close(); } }
手写验证码
package com.zx.web.lesson09; import java.awt.Color; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.FileInputStream; import java.io.IOException; import java.net.URLEncoder; import java.util.Random; import javax.imageio.ImageIO; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/VerificationCode") public class VerificationCode extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub //1.创建一个图片对象 int width=120; int height=30; BufferedImage bi=new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); //2.拿到画笔 Graphics graphics= bi.getGraphics(); //3.涂个背景颜色 graphics.setColor(Color.yellow);//设置画笔颜色 graphics.fillRect(0, 0, width, height); //4.画干扰线 //重新设置画笔颜色 graphics.setColor(Color.BLACK); Random random=new Random(); for (int i=0;i<4;i++) { //第一个点 int x1=random.nextInt(width); int y1=random.nextInt(height); //第二个点 int x2=random.nextInt(width); int y2=random.nextInt(height); graphics.drawLine(x1, y1, x2, y2); } //5.画验证码(4个随机数) graphics.setColor(Color.RED); int left=10; for (int i=0;i<4;i++) { int r=random.nextInt(10); graphics.drawString(r+"", (left+i*30), 20); } //设置响应类型 resp.setContentType("image/jpeg"); //把图片输出给客户端 ImageIO.write(bi, "JPEG", resp.getOutputStream()); } }
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> <script type="text/javascript"> function refreshCode(){ //1.获取img标签 var imgTag=document.getElementById("code"); //2.获取img标签src的属性值 console.log(imgTag.src); //3.重新赋值 imgTag.src="/day09Web/VerificationCode?"+new Date().getTime();//改的值与原本的src一致,js就不会去访问后台 } </script> </head> <body> <form action=""> 用户名:<input type="text"><br/> 密码:<input type="password"><br/> <!-- src下面要添加项目名称 --> 验证码:<input type="text"> <img id="code" alt="" src="/day09Web/VerificationCode"> <!-- 怎么在a标签中,调用js --> <a href="javascript:refreshCode()">看不清,换一张</a> </form> </body> </html>
使用工具类实现验证码
package com.zx.web.lesson10; import java.awt.Color; import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.FileInputStream; import java.io.IOException; import java.net.URLEncoder; import java.util.Random; import javax.imageio.ImageIO; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import cn.dsna.util.images.ValidateCode; @WebServlet("/VerificationCode2") public class VerificationCodeServlet extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // TODO Auto-generated method stub //使用工具来生成验证码,一个jar包 /** * JavaWeb中,导入第三方的包,跟以前有点不一样 * 导包都是放在WEB_INF/lib */ //创建验证码对象 ValidateCode validateCode=new ValidateCode(100, 30, 4, 6); //把验证码返回给客户端 validateCode.write(resp.getOutputStream()); } }
自动刷新响应头
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.setContentType("text/html;charset=UTF-8"); //response.setHeader("Refresh", "1");//每隔一秒刷新一次 response.setHeader("Refresh", "5;URL=index.html");//3秒后转到另一页面 response.getWriter().write("注册成功!3秒后会自动跳转,苦没有中转点击<a href='index.html'>这里</a>"); }
response需要注意的细节:
- getOutputStream和getWriter这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。 会抛异常
- 这两个流不需要我们关闭,如果自己写close方法也没有问题,但是这样做等于重复做事
HttpServletRequest
request常用方法
获得客户端信息
- getRequestURL方法返回客户端发出请求时的完整URL。
- getRequestURI方法返回请求行中的资源名部分。
- getQueryString 方法返回请求行中的参数部分。
- getRemoteAddr方法返回发出请求的客户机的IP地址
- getRemoteHost方法返回发出请求的客户机的完整主机名
- getRemotePort方法返回客户机所使用的网络端口号
- getLocalAddr方法返回WEB服务器的IP地址。
- getLocalName方法返回WEB服务器的主机名
- getMethod得到客户机请求方式
获得客户端请求头
- getHead(name)方法
- getHeaders(String name)方法
- getHeaderNames方法