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,response,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. [原创]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学习总结(六)——Servlet开发(二)

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

  9. Javaweb 第7天 Servlet课程

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

随机推荐

  1. thread.join() 方法存在的必要性是什么?

    好久远的问题,为什么关注这个问题的人这么少? 或许是用到这个功能的情形比较少吧. 1.等待处理结果 为什么要用join()方法在很多情况下,主线程生成并起动了子线程,如果子线程里要进行大量的耗时的运算 ...

  2. lua学习笔记(八)

      元表与元方法  基本概念         1.lua中每个值都有一个元表         2.table和userdata可以有各自独立的元表         3.其它类型的值共享其类型所属的单一 ...

  3. The best way to predict the future is to invent it,预测未来最好的方法是创造它!

    The best way to predict the future is to invent it,预测未来最好的方法是创造它! ——Smalltalk发明人Alan Kay “预测未来的最好方法, ...

  4. listView的异步加载数据

    1 public class MainActivity extends Activity { 2 3 private ListView listView; 4 private ArrayList< ...

  5. PHP性能之语言性能优化:vld——查看代码opcode的神器

    vld介绍 vld是PECL(PHP 扩展和应用仓库)的一个PHP扩展,现在最新版本是 0.14.0(2016-12-18),它的作用是:显示转储PHP脚本(opcode)的内部表示(来自PECL的v ...

  6. 模拟多级复选框效果--jquery

    今天又次体会到jquery的强大了,做了个多级复选框的效果,代码总共就20+行就over了. 我又想用js来做一个看看,才写了几个方法就写不动了,兼容性要考虑很多,而且代码量直线上升. 主要分享下jq ...

  7. junit spring 测试

    http://my.oschina.net/dlpinghailinfeng/blog/336694 http://blog.csdn.net/zhangzikui/article/details/1 ...

  8. vue实践---vue结合 promise 封装原生ajax

    有时候不想使用axios这样的外部依赖,想自己封装ajax,这里有两种方法 方法一,在单个页面内使用 封装的代码如下: beforeCreate () { this.$http = (() => ...

  9. 移动Web开发技巧汇总(转)

    META相关 1. 添加到主屏后的标题(IOS) <meta name="apple-mobile-web-app-title" content="标题" ...

  10. IOS启动页动画(uiview 淡入淡出效果 )2

    Appdelegate里面右个这个函数,只要它没结束,你的等待界面就不会消失.以在启动的时候做些动画 - (BOOL)application:(UIApplication *)application ...