Servlet是服务器中的一个类,而Response和Request是使用Servlet编写和控制的针对于浏览器端的程序。Response是服务器向浏览器发送回应,Request是浏览器向服务器发送请求。
一个servlet上下文是servlet引擎提供用来服务于Web应用的接口,一个servlet可以通过ServletConfig对象的getServletContext()方法得到servlet上下文的引用,如果servlet直接或间接调用子类GenericServlet,则可以使用getServletContext()方法。
Web应用中servlet可以使用servlet上下文得到:
1.在调用期间保存和检索属性的功能,并与其他servlet共享这些属性。
2.读取Web应用中文件内容和其他静态资源的功能。
3.互相发送请求的方式。
4.记录错误和信息化消息的功能。
ServletContext接口中的方法 :
1、Object getAttribute(String name) 返回servlet上下文中具有指定名字的对象,或使用已指定名捆绑一个对象。从Web应用的标准观点看,这样的对象是全局对象,因为它们可以被同一servlet在另一时刻访问。或上下文中任意其他servlet访问。
2、void setAttribute(String name,Object obj) 设置servlet上下文中具有指定名字的对象。 3、Enumeration getAttributeNames() 返回保存在servlet上下文中所有属性名字的枚举。
4、ServletContext getContext(String uripath) 返回映射到另一URL的servlet上下文。在同一服务器中URL必须是以“/”开头的绝对路径。
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class AServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1 获得Application域中的统计数字,根据"count"名字获得 Integer count = (Integer) getServletContext().getAttribute("count"); //2 判断是否获得到统计数字 if(count == null){ //如果没有获得到,将数字初始化为1 count = 1; }else{ //如果获得到了,数字在原有基础上加1 count += 1; } //3 将数字处理并放回到Application域中 response.getWriter().write("you are the "+ count+" vistors"); //其中“count”是键,count是值 getServletContext().setAttribute("count",count); } }当然在Web.xml中会自动生成
<servlet-mapping> <servlet-name>AServlet</servlet-name> <url-pattern>/AServlet</url-pattern> <url-pattern>/BServlet</url-pattern> </servlet-mapping>
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class BServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //解决乱码的问题 response.setContentType("text/html;charset=utf-8"); //添加响应头 refresh response.addHeader("Refresh", "3;url=http://localhost:8080"); // 页面的倒计时的效果 response.getWriter().write("等待<span id = 'one'>3</span>秒后跳转!;" + "<script type='text/javaScript' >" + "var span = document.getElementById('one');" + "var i =3;" + "function fun(){" + "i--;" + "if(i>=0){" + "span.innerHTML = i;" + "}" + "}" + "window.setInterval(fun,1000);" + "</script>"); } }
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class CServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { /*//1 添加302状态码 => 告诉浏览器需要重定向 response.setStatus(302); //2 添加Location响应头 => 高速浏览器重定向到哪里 response.setHeader("Location", "http://localhost:8080");*/ //该方法是对上面两行代码的封装 response.sendRedirect("http://localhost:8080"); } }
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //控制解码码表 //response.setHeader("Content-Type", "text/html;charset=GBK"); //控制编码码表 response.getOutputStream().write("哈哈你好".getBytes("GBK")); } }
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class FServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //判断是否有查看的权限 // 1 获得图片的输入流 InputStream is = getServletContext().getResourceAsStream("/WEB-INF/xxx1.jpg"); // 2 获得输出到浏览器的输出流 OutputStream os = response.getOutputStream(); // 3 两个流对接 byte[] buffer = new byte[1024]; int len = -1; while((len = is.read(buffer))!=-1){ os.write(buffer,0,len); os.flush(); } os.close(); is.close(); } }
设置content-type的原因是因为我们平时输出的是文本,这次输出的是别的格式的文件,所以要设置一下,与传输图片不同的是传输文档的时候要设置响应头。
import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class GServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //0 原则: 凡是响应正文中需要输出内容, 一定要设置content-type头 ServletContext sc = getServletContext(); String type = sc.getMimeType("abc.exe"); response.setContentType(type); //0 设置响应头=> 提示用户保存名称 => Http协议不支持中文码表=> %E5%C3 => URLEncoder.encode("apache-汤姆-6.0.35.exe","UTF-8"); response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode("apache-汤姆-6.0.35.exe","UTF-8")); // 1 获得文件的输入流 InputStream is = getServletContext().getResourceAsStream("/WEB-INF/apache-tomcat-6.0.35.exe"); // 2 获得输出到浏览器的输出流 OutputStream os = response.getOutputStream(); // 3 两个流对接 byte[] buffer = new byte[1024]; int len = -1; while((len = is.read(buffer))!=-1){ os.write(buffer,0,len); os.flush(); } os.close(); is.close(); } }
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class AServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("request.getContentLength(): " + request.getContentLength()); System.out.println("request.getContentType(): " + request.getContentType()); System.out.println("request.getContextPath(): " + request.getContextPath()); System.out.println("request.getMethod(): " + request.getMethod()); System.out.println("request.getLocale(): " + request.getLocale()); System.out.println("request.getQueryString(): " + request.getQueryString()); System.out.println("request.getRequestURI(): " + request.getRequestURI()); System.out.println("request.getRequestURL(): " + request.getRequestURL()); System.out.println("request.getServletPath(): " + request.getServletPath()); System.out.println("request.getRemoteAddr(): " + request.getRemoteAddr()); System.out.println("request.getRemoteHost(): " + request.getRemoteHost()); System.out.println("request.getRemotePort(): " + request.getRemotePort()); System.out.println("request.getScheme(): " + request.getScheme()); System.out.println("request.getServerName(): " + request.getServerName()); System.out.println("request.getServerPort(): " + request.getServerPort()); } }
通过doGet()和doPost()两种方式都可以获得键值对并打印,通过访问.jsp文件的方式来进行提交页面的访问
import java.io.IOException; import java.util.Enumeration; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class BServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1 获得 所有参数的键 Enumeration<String> en = request.getParameterNames(); // 2 遍历所有键 while(en.hasMoreElements()){ String key = en.nextElement(); //根据键 获得值 String value = request.getParameter(key); System.out.println(key+"==>"+value); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 1 获得 所有参数的键 Enumeration<String> en = req.getParameterNames(); // 2 遍历所有键 while(en.hasMoreElements()){ String key = en.nextElement(); //根据键 获得值 String value = req.getParameter(key); System.out.println(key+"==>"+value); } } }下面是jsp源代码
<%@ 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 'index.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 action="/day08-request/BServlet" method="get" > 用户名:<input type="text" name="name" /><br/> 密码:<input type="password" name="password" /><br/> <input type="submit" value="提交" /> </form> <hr> <form action="/day08-request/BServlet" method="post" > 用户名:<input type="text" name="name" /><br/> 密码:<input type="password" name="password" /><br/> <input type="submit" value="提交" /> </form> </body> </html>
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class CServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String name = request.getParameter("name"); System.out.println(name); //1 将乱码使用latin码表 编码回字节数组 byte[] bytes= name.getBytes("ISO-8859-1"); //2 将字节用UTF-8码表 解码回中文 String name2 = new String(bytes, "UTF-8"); System.out.println(name2); } @Override protected void doPost(HttpServletRequest request, HttpServletResponse resp) throws ServletException, IOException { //post解决乱码,只要在调用获得参数方法前.设置解码码表即可 request.setCharacterEncoding("UTF-8"); String name = request.getParameter("name"); System.out.println(name); } }对应的访问jsp代码
<%@ 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 'index.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 action="/day08-request/CServlet" method="get" > 用户名:<input type="text" name="name" /><br/> 密码:<input type="password" name="password" /><br/> <input type="submit" value="提交" /> </form> <hr> <form action="/day08-request/CServlet" method="post" > 用户名:<input type="text" name="name" /><br/> 密码:<input type="password" name="password" /><br/> <input type="submit" value="提交" /> </form> </body> </html>
下面是DServlet的代码:
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("我来处理业务逻辑"); String name = "肉丝";//假设该值是从数据库中取出来.要将该值交给EServlet显示 //将name变量放入request域 request.setAttribute("name", name); //转发(山寨,帮助我们理解转发原理) /*EServlet eservlet = new EServlet(); eservlet.service(request, response);*/ response.getWriter().write("DServlet hello!"); //转发 request.getRequestDispatcher("/EServlet").forward(request, response); } }
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class EServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("我来负责输出显示!"); String name = (String) request.getAttribute("name"); System.out.println("EServlet:"+name); response.getWriter().write("EServlet hello!"); } }
通过FServlet来包含GServlet,这样做的目的是,当不同的网页中有相同的内容时,我们可以通过这种技术来统一操作和修改,省去了逐个网页修改的烦恼。
下面是FServlet的代码:
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class FServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); response.getWriter().write("这是第一部分!<br>"); //包含 request.getRequestDispatcher("/GServlet").include(request, response); //这个是转发的 //request.getRequestDispatcher("/EServlet").forward(request, response); response.getWriter().write("这是第二部分!<br>"); } }下面是DServlet的代码:
import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class GServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().write("这是相同的部分!<br>"); } }输入结果是:
这是第一部分! 这是相同的部分! 这是第二部分!