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中会自动生成
AServlet
/AServlet
/BServlet
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("等待3秒后跳转!;" +
"");
}
}
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 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 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+"/";
%>
My JSP 'index.jsp' starting page
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+"/";
%>
My JSP 'index.jsp' starting page
下面是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("这是第一部分!
");
//包含
request.getRequestDispatcher("/GServlet").include(request, response);
//这个是转发的
//request.getRequestDispatcher("/EServlet").forward(request, response);
response.getWriter().write("这是第二部分!
");
}
}
下面是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("这是相同的部分!
");
}
}
输入结果是:
这是第一部分!
这是相同的部分!
这是第二部分!