Servlet是服务器中的一个类,而Response和Request是使用Servlet编写和控制的针对于浏览器端的程序。Response是服务器向浏览器发送回应,Request是浏览器向服务器发送请求。
一、:Servlet统计访问量的例子
其中getAttribute()是根据键来获得指定名字的对象,然后判断一下,最终通过response将其写到页面上。一个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>
二、:Response倒计时3秒跳转
通过在write()中嵌套JavaScript代码来实现页面倒计时的效果
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>");
}
}
三、: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 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");
}
}
四、: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 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"));
}
}
五、:Response中图片的传输显示
先获得流然后再将两个流对接,实现传输显示,最后关闭流。
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();
}
}
六、:Response中图片的传输显示
设置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();
}
}
六、:Request中的一些方法
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());
}
}
七、:Request通过浏览器提交获得键值对
通过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>
八、:Request解决乱码问题
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>
九、:Request实现转发
通过访问DServlet来访问EServlet的内容下面是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!");
}
}
十、:Request包含
通过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>");
}
}
输入结果是:
这是第一部分!
这是相同的部分!
这是第二部分!