JavaWeb -- 服务器传递给Servlet的对象 -- ServletConfig, ServletContext,Request, Response

时间:2021-12-30 09:36:14

1.  ServletConfig 

一些东西不合适在程序中写死,应该写在web.xml中,比如 文字怎么显示, 访问数据库名 和 密码, servlet要读取的配置文件 等等。。

l在Servlet的配置文件中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数。
l当servlet配置了初始化参数后,web容器在创建servlet实例对象时,会自动将这些初始化参数封装到ServletConfig对象中,并在调用servlet的init方法时,将ServletConfig对象传递给servlet。进而,程序员通过ServletConfig对象就可以得到当前servlet的初始化参数信息。
web.xml 设置参数
  <servlet>
<servlet-name>Test</servlet-name>
<servlet-class>com.kevin.Test</servlet-class>
<init-param>
<param-name>data1</param-name>
<param-value>data11.log</param-value>
</init-param>
<init-param>
<param-name>data2</param-name>
<param-value>data2.log</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Test</servlet-name>
<url-pattern>/Test2</url-pattern>
</servlet-mapping>
Servlet获取参数
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
String servletConfig1 = this.getServletConfig().getInitParameter("data1");//获取指定名的参数
response.getOutputStream().write(("WebTest2.Test " + servletConfig1).getBytes()); Enumeration<String> e = this.getServletConfig().getInitParameterNames(); //获取所有参数名
while(e.hasMoreElements()) //获取所有参数
{
String name = (String) e.nextElement();
String data = this.getServletConfig().getInitParameter(name);
response.getOutputStream().write((" "+data).getBytes());
}
}

2. ServletContext: 服务已启动就会对应每个Web应用产生一个ServletContext, 停服务器才销毁对象。

lWEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用
lServletContext对象被包含在ServletConfig对象中,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得对ServletContext对象的引用。
l由于一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象

应用:聊天室等

应用一: l多个Servlet通过ServletContext对象实现数据共享。

Demo1
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
String data = "aaaa";
this.getServletContext().setAttribute("data1", data); //写入
}
Demo2
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
String data = (String) this.getServletContext().getAttribute("data1"); //读取
response.getOutputStream().write(data.getBytes());
}
应用二: l获取WEB应用的初始化参数
如1ServletConfig配置参数只能一个Servlet使用,用ServletContext设置参数能使整个Web应用所有Servlet访问。
web.xml参数
<context-param>
<param-name>data2</param-name>
<param-value>context-param in web.xml</param-value>
</context-param>
获取参数
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
String data = (String) this.getServletContext().getInitParameter("data2");//获取ServletContext参数
response.getOutputStream().write(data.getBytes());
}
应用三:l实现Servlet的转发
注意Servlet转发和Http协议重定向的区别, Http重定向 消息头为Location,重定向的意思是 “我没有,你自己去找别人”,转发的意思是“我没有,我帮你去找别人”。
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
String data = "dataaaaaaaaa";
this.getServletContext().setAttribute("data3", data); //线程不安全。实际开发不能用
RequestDispatcher rd = this.getServletContext().getRequestDispatcher("/1.jsp"); //带数据请求转发jsp
rd.forward(request, response);
}
应用四:l利用ServletContext对象读取资源文件
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub //注意路径是对Tomcat服务器里面的资源,而不是Eclipse项目的资源显示
InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties"); //获取字节流
String path = this.getServletContext().getRealPath("/WEB-INF/classes/db.properties");//获取绝对路径,能获取到文件名
Properties props = new Properties();
props.load(in);
String url = props.getProperty("URL");
String username = props.getProperty("username");
String password = props.getProperty("password");
response.getOutputStream().write((url + " " + username + " " + password).getBytes());
}

如果读取资源文件的程序不是Servlet的话,就只能用类装载器去读。

String path = UserDao.class.getClassLoader().getResource("db.properties").getpath();

通过类装载器的getResource()获得一个URL,再获得其绝对路径, 再通过普通的InputStream 读取文件。

3. Response
控制编码输出
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//程序以什么码表输出,就要控制浏览器用什么码表显示
response.setHeader("Content-type", "text/html;charset=UTF-8");
String data = "中国人";
OutputStream out = response.getOutputStream();
out.write(data.getBytes("UTF-8"));
}
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setCharacterEncoding("UTF-8"); //控制response 以UTF-8编码
response.setHeader("content-type","text/html;charset=UTF-8"); //http头, 控制浏览器以UTF-8显示
String data = "中国";
PrintWriter out = response.getWriter();
out.write(data); }

控制文件下载

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
String path = this.getServletContext().getRealPath("/download/apple.png");
String filename = path.substring(path.lastIndexOf("/")+1); //截取文件名
//System.out.println(filename);
response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));//用URL防止中文文件名乱码问题
InputStream in = null;
OutputStream out = null;
try
{
in = new FileInputStream(path);
out = response.getOutputStream();
int len = 0;
byte[] buf = new byte[1024];
while( (len=in.read(buf)) > 0 )
{
out.write(buf, 0, len);
}
}
finally
{
try
{
in.close();
out.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}

输出随机认证图片,防恶意注册 

    private static final int width = 120;
private static final int height = 40;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics(); setBackGround(g);
setBorder(g);
drawRandomLine(g);
drawRandomNum((Graphics2D)g);
response.setContentType("image/jpeg"); //设置头, 浏览器以图片方式打开
response.setDateHeader("expries", -1); //设置头, 不让浏览器缓存
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
ImageIO.write(image, "jpg", response.getOutputStream());
} private void drawRandomNum(Graphics2D g) { //添加随机汉字
// TODO Auto-generated method stub
//[\u4e00 ~ \u9fa5]
g.setColor(Color.BLUE);
g.setFont(new Font(null, Font.BOLD, 20));
String base = "\u7684\u4e00\u662f\u4e86\u6211\u4e0d\u4eba\u5728\u4ed6\u6709\u8fd9\u4e2a\u4e0a\u4eec\u6765";
int x = 5;
for(int i=0; i<4; i++)
{
String ch = base.charAt(new Random().nextInt(base.length())) + "";
//System.out.println(ch);
int degreen = new Random().nextInt()%30;
g.rotate(degreen*Math.PI/180, x, 25); //翻转汉字
g.drawString(ch, x, 25);
g.rotate(-degreen*Math.PI/180, x, 25);
x += 30;
} } private void drawRandomLine(Graphics g) { //加干扰线
// TODO Auto-generated method stub
g.setColor(Color.green);
for(int i=0; i<8; i++)
{
int x1 = new Random().nextInt(width);
int y1 = new Random().nextInt(height);
int x2 = new Random().nextInt(width);
int y2 = new Random().nextInt(height);
g.drawLine(x1, y1, x2, y2);
} } private void setBorder(Graphics g) { //设置边框
// TODO Auto-generated method stub
g.setColor(Color.blue);
g.drawRect(1, 1, width-2, height-2);
} private void setBackGround(Graphics g) { //设置背景颜色
// TODO Auto-generated method stub
g.setColor(Color.WHITE);
g.fillRect(0, 0, width, height);
}

Html调用上面的Servlet, 点击即可更换随机图片

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Insert title here</title> <script type="text/javascript">
function changeImage(img) {
img.src = img.src + "?" + new Date().getTime();
}
</script> </head>
<body>
<form action="">
<pre>
User :<input type="text" name="username"/> <br />
Passwd :<input type="password" name="passwd"/> <br />
CheckCode:<input type="text" name="checkcode"/> <br />
<img src="Demo4" alt="ChangeOne" onclick="changeImage(this)" style="cursor: hand"/>
</pre>
</form>
</body>
</html>

注册完成后实现 几秒跳转,转发

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub test2(request, response); //实用 } private void test2(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { //利用meta标签实现refresh, 跳转到jsp显示页面
String message = "<meta http-equiv='refresh' content='3;url=http://www.baidu.com'>"
+ "Register successfully!! Will goto .... <a href='http://www.baidu.com'>Clicked here!!</a></meta>";
this.getServletContext().setAttribute("message", message);
this.getServletContext().getRequestDispatcher("/1.jsp").forward(request, response); //转发
} private void test1(HttpServletResponse response) throws IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
response.setHeader("refresh", "3;url=/WebTest2/1.jsp");
response.getWriter().write("Register successfully!! Will goto .... "
+ "<a href='http://www.baidu.com'>Clicked here!!</a>");
}

1.jsp

<body>
<font color="red">
<% java.util.Date d = new java.util.Date(); %>
<h1>
Today's date is <%= d.toString() %> and this jsp page worked!
</h1> <%
String message = (String)application.getAttribute("message");
out.write(message);
%> </font>
</body>

上面的方法是转发, 注意和下面的重定向的区别

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
/* response.setStatus(302); //实用http响应头重定向
response.setHeader("location", "/WebTest2/1.html");*/ response.sendRedirect("/WebTest2/1.html"); //API方法重定向
}

控制缓存 // 缓存时间需要在当前时间的基础上添加。

response.addDateHeader("expires",System.currentTimeMillis() + 1000*3600);

Response要注意的一些细节

a: getOutputStream和getWriter方法分别用于得到输出二进制数据、输出文本数据的ServletOuputStream、Printwriter对象。
b: getOutputStream和getWriter这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。 
c: Servlet程序向ServletOutputStream或PrintWriter对象中写入的数据将被Servlet引擎从response里面获取,Servlet引擎将这些数据当作响应消息的正文,然后再与响应状态行和各响应头组合后输出到客户端。
d: Serlvet的service方法结束后,Servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,Servlet引擎将调用close方法关闭该输出流对象,不需要程序猿手动close掉返回流

4. Request

Request 常用方法

l获得客户机信息

•getRequestURL方法返回客户端发出请求时的完整URL。
•getRequestURI方法返回请求行中的资源名部分。
•getQueryString方法返回请求行中的参数部分。
•getPathInfo方法返回请求URL中的额外路径信息。额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以“/”开头。
•getRemoteAddr方法返回发出请求的客户机的IP地址
•getRemoteHost方法返回发出请求的客户机的完整主机名
•getRemotePort方法返回客户机所使用的网络端口号
•getLocalAddr方法返回WEB服务器的IP地址。
•getLocalName方法返回WEB服务器的主机名
l获得客户机请求头
•getHeader方法
•getHeaders方法
•getHeaderNames方法
l获得客户机请求参数(客户端提交的数据)
•getParameter方法
•getParameterValues(String name)方法
•getParameterNames方法
•getParameterMap方法 
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub test3(request); } private void test3(HttpServletRequest request) throws IOException { //获得客户机请求参数(客户端提交的数据)
Enumeration<String> e = request.getParameterNames();
while(e.hasMoreElements())
{
String name = e.nextElement();
String value = request.getParameter(name);
System.out.println(name + "=" + value);
} String[] values = request.getParameterValues("name");
for(int i=0; values!=null && i<values.length; i++)
{
if(!values[i].trim().equals(""))
System.out.println("name=" + values[i]);
} Map<String, String[]> map = request.getParameterMap();
User user = new User();
try {
BeanUtils.populate(user, map);
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println(user.getPasswd());
} private void test2(HttpServletRequest request) { //获得客户机请求头
String headValue = request.getHeader("Accept-Language");
System.out.println(headValue);
Enumeration<String> e = request.getHeaders("Accept-Language");
while(e.hasMoreElements())
{
String value = e.nextElement();
System.out.println(value);
} e = request.getHeaderNames();
while(e.hasMoreElements())
{
String name = e.nextElement();
String value = request.getHeader(name);
System.out.println(name + "=" + value);
}
} private void test1(HttpServletRequest request) { // 获得客户机信息
System.out.println(request.getRequestURI());
System.out.println(request.getRequestURL());
System.out.println(request.getQueryString());
System.out.println(request.getRemoteAddr());
System.out.println(request.getRemoteHost());
System.out.println(request.getRemotePort());
System.out.println(request.getMethod());
} /**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
System.out.println("+++++++++++++++++++");
InputStream in = request.getInputStream();
int len = 0;
byte[] buf = new byte[1024];
while( (len=in.read(buf))>0 )
{
System.out.println(new String(buf, 0, len));
}
}

上面User类为 , 请求数据为 ....?name=kevin&name=xiang&passwd=123456

public class User {
private String[] name;
private String passwd;
public String[] getName() {
return name;
}
public void setName(String[] name) {
this.name = name;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
} }

Request 请求中会夹带中文, 解决乱码问题

如果是Post方式提交的请求带中文参数,可以设置编码

                  //post方式提交
request.setCharacterEncoding("UTF-8");
System.out.println("post username=" + request.getParameter("username"));

如果是Get方式 或 超链接方式 提交的请求带中文参数, 只能手动转码

                  String name = request.getParameter("username");  //Get方式提交
name = new String(name.getBytes("iso8859-1"), "UTF-8");
System.out.println("get name=" + name);

Request请求转发

和ServletContext一样Request 也可以做到请求转发,而且更实用,由于Request域不同于ServletContext域,每个请求都会有一个Request,所以用setAttribute()方法传递数据,不会有线程安全问题,具有实用性。

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
String data = "xxxxxx";
request.setAttribute("data", data);
request.getRequestDispatcher("/1.jsp").forward(request, response);//请求转发
}

5. Web工程中各种地址的写法

首先“/” 加斜杠, 看地址使用的对象是谁。如果是服务器使用,斜杠就代表当前Web应用。 如果是浏览器使用,斜杠就代表网站,网站下面才有Web应用。

例一: 转发, 转发是给服务器使用,所以斜杠是代表当前Web应用

request.getRequestDispatcher("/1.html");

例二: 重定向, 重定向是给浏览器使用的,所以斜杠是代表网站,后面还需要接Web应用名

response.sendRedirect("/WebTest2/1.html");

书写路径时, 如果是Web工程中的资源文件用“/”斜杠, 如果是要获取硬盘上的文件,用“C:\\” 反斜杠

6. 域, ServletContext域 和 request域

对于域 需要有两个理解, 首先是一个容器,然后有自己的作用范围
















 

JavaWeb -- 服务器传递给Servlet的对象 -- ServletConfig, ServletContext,Request, Response的更多相关文章

  1. JavaWeb(一)Servlet中的ServletConfig与ServletContext

    前言 前面我介绍了一下什么是servlet,它的生命周期,执行过程和它的原理.这里我们做一个简单的回顾! 什么是Servlet? servlet 是运行在 Web 服务器中的小型 Java 程序(即: ...

  2. js封装用户选项传递给Servlet之考试系统二

    <%@ page language="java" import="java.util.*" contentType="text/html; ch ...

  3. JSP内置对象1(request&comma;response&comma;session)

    request对象 response对象:请求重定向与请求转发的区别. session对象:表示客户端与服务器的一次会话,也就是用户浏览网站所花费的时间.在服务器的内存中保存着不同用户的session ...

  4. 1、Servlet 2、ServletConfig 3、ServletContext 4、HttpUrlConnection

    1.Servlet 2.ServletConfig 3.ServletContext 4.HttpUrlConnection 07. 五 / J2EE / 没有评论   一.第一个Servlet的编写 ...

  5. &lbrack;原创&rsqb;java WEB学习笔记05:Servlet中的ServletConfig对象

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  6. Servlet接口的实现类,路径配置映射,ServletConfig对象,ServletContext对象及web工程中文件的读取

    一,Servlet接口实现类:sun公司为Servlet接口定义了两个默认的实现类,分别为:GenericServlet和HttpServlet. HttpServlet:指能够处理HTTP请求的se ...

  7. JavaWeb基础—Servlet重要对象

    一.ServletConfig对象 当servlet配置了初始化参数后(<init-param> <param-name> <param-value>),web容器 ...

  8. javaweb学习总结&lpar;六&rpar;——Servlet开发&lpar;二&rpar;

    一.ServletConfig讲解 1.1.配置Servlet初始化参数 在Servlet的配置文件web.xml中,可以使用一个或多个<init-param>标签为servlet配置一些 ...

  9. Javaweb 第7天 Servlet课程

    Servlet课程 三日大纲 ● 网络概念,专业术语 ● Tomcat使用,发布网站,使用Myeclispe发布网站(搭建环境) ● 编写Servlet,Servlet生命周期 ● 用户注册,显示所有 ...

随机推荐

  1. HUD 4007 &lbrack;扫描线&rsqb;&lbrack;序&rsqb;

    /* 大连热身B题 不要低头,不要放弃,不要气馁,不要慌张 题意: 坐标平面内给很多个点,放置一个边长为r的与坐标轴平行的正方形,问最多有多少个点在正方形内部. 思路: 按照x先排序,然后确定x在合法 ...

  2. NPOI Excel类

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using NPOI.HSSF.Us ...

  3. 【动态规划】HDU 5791 Two

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5791 题目大意: A,B两个数列,问A的子集和B的子集相等的子集对数.子集内顺序按照数列顺序,相同的 ...

  4. XML的四种解析方式

    本文描述了构建良好的XML需要遵循的规则.作者详细介绍了构建XML需要考虑的元素,如何命名约定.正确的标记嵌套.属性规则.声明和实体,以及DTD和schema的验证,十分便于新手开始学习了解XML. ...

  5. ubuntu环境下jdk安装及jenkins安装

    本文内容参考http://jingyan.baidu.com/article/c33e3f48a3365dea15cbb5c9.html 1 jdk下载 安装 http://www.oracle.co ...

  6. Myeclipse安装jbpm6

    1.下载jbpm-6.3.0.Final-installer-full.zip解压此文件 2.在myeclipse2013安装路径(F:\tool\myeclipse2013)下新建文件夹jbpm6- ...

  7. bzoj3997组合数学(求最长反链的dp)

    组合数学 给出一个网格图,其中某些格子有财宝,每次从左上角出发,只能向下或右走.问至少走多少次才能将财宝捡完.此对此问题变形,假设每个格子中有好多财宝,而每一次经过一个格子至多只能捡走一块财宝,至少走 ...

  8. PHP多进程编之僵尸进程问题

    上一篇说到了使用pcntl_fork函数可以让PHP实现多进程并发或者异步处理的效果.那么问题是我们产生的进程需要去控制,而不能置之不理.最基本的方式就是fork进程和杀死进程. 通过利用pcntl_ ...

  9. &lbrack;leetcode&rsqb;432&period; All O&grave;one Data Structure全O&lpar;1&rpar;数据结构

    Implement a data structure supporting the following operations: Inc(Key) - Inserts a new key with va ...

  10. 小技巧css解决移动端ios不兼容position&colon;fixed属性,无需插件

    移动端开发仿app头部底部固定设置position:fixed,android2.2以上已经实现.但是在ios8以下系统,当小键盘激活时,都会出现位置浮动问题.如图: 如何解决: 查阅资料之后想到一下 ...