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

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, 停服务器才销毁对象。

l WEB 容器在启动时,它会为每个 WEB应用程序都创建一个对应的ServletContext 对象,它代表当前 web 应用
l ServletContext 对象被包含在 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" οnclick="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 引擎将检查 getWritergetOutputStream方法返回的输出流对象是否已经调用过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域

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





 









 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值