Servlet原理解析及作用2

来源:互联网 发布:查药物的软件 编辑:程序博客网 时间:2024/05/17 03:34

注:再看本文章前,请先看我前面写的《Servlet原理解析及作用1》。

一、Servlet中的线程安全问题

  *首先我们要明白web应用是并发应用

   当用户多次刷新页面,就会请求一次服务端,这个时候就会出现该同一个请求service被两个对象调用现象,存在数据不安全。

解决方案:
      (1)在Servlet中定义变量,除非特殊要求,尽量使用局部变量。
      (2)如果有需要实例变量时,应做同步处理,且同步代码块尽量包围少的代码。

                     

implements SingleThreadModel接口就可以保证安全这个时候servlet就可能实行两种方式进行加锁:

(1)每次进来一个的访问serlet对象就进行加锁,指导用完后,才给下一个访问加锁。

(2)给每一个访问一个servlet对象(相对繁琐了,而且违背了servlet单独一个对象在内存中的原则)但是安全还是无    法成立。

二、Servlet的配置对象:
ServletConfig:(读取下列数据咋内存中创建该对象(由容器来创建))
作用:代表了Servlet配置中的参数信息。
比如在web.xml中的参数配置如下:
   

<servlet>    <servlet-name>ServletDom2</servlet-name>    <servlet-class>com.dp.java.servlet.ServletDom2</servlet-class>    <init-param>    <param-name>AAA</param-name>    <param-value>BBB</param-value>    </init-param>    <init-param>    <param-name>XXX</param-name>    <param-value>YYY</param-value>    </init-param>  </servlet>

     问题来了!!怎么调用方法呢?用init(ServletConfig config)周期方法

public class ServletDom2 extends HttpServlet {private ServletConfig config;public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {test1();//去配置固定值test2();//取配置所有init的值test3();//取配置servlet-name}private void test3() {//得到servlet元素文本String s_name=config.getServletName();System.out.println("servlet-name: "+s_name);}private void test2() {//得到所有init元素标签,并打印所有映射的value值Enumeration enu=config.getInitParameterNames();while(enu.hasMoreElements()){String parmname=(String)enu.nextElement();System.out.println("init-param的name值: "+parmname+"  " +"  init-param的value值: "+config.getInitParameter(parmname));}}private void test1() {//得到init的AAA所映射的value值String AAA_value=config.getInitParameter("AAA");System.out.println(AAA_value);}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}@Override//组件创建对象public void init(ServletConfig config) throws ServletException {this.config=config;}}
结果:

                 


三、ServletContext详解

                 

        1、在应用被服务器加载时就创建ServletContext对象的实例。每一个JavaWeb应用都有唯一的一个                                 ServletContext对象它就代表着当前的应用。
2、如何得到ServletContext对象:ServletConfig.getServletContext();

      (1)第一种,写一个ServletContext对象来调用

private ServletConfig config;//一个web应用只有一个servletcontext对象public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {config.getServletContext();}public void init(ServletConfig config) throws ServletException {this.config=config;}
    (2)第二种直接调用,因为在HttpServlet的父类关系中写得有。

ServletContext sc=getServletContext();

3、有什么用呢?

最重要的一个作用实现Servlet对象之间可以通过ServletContext(就因为它可以得到类对象名)对象来实现通讯,           所以ServletContext对象也被称为Context域对象。

              3.1ServletContext对象是一个域对象(域对象就是说其内部维护了一个Map<String,Object>)
       Object getAttribute(String name):根据名称获取绑定的对象
Enumeration getAttributeNames() :获取ServletContext域中的所有名称
void removeAttribute(String name):根据名称移除对象
void setAttribute(String name,Object value):添加或修改对象。


3.2实现多个Servlet之间的数据共享

                这个举一个例子:

在ServletContext对象中放入数据  

//ServletContext的练习public class ServletDom3 extends HttpServlet {private ServletConfig config;//一个web应用只有一个servletcontext对象public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {ServletContext sc=config.getServletContext();sc.setAttribute("P", "放了一个p对象");response.getOutputStream().write("已经放了".getBytes());}public void init(ServletConfig config) throws ServletException {this.config=config;}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}
在ServletContext对象中放入数据   

public class ServletDom4 extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {    ServletContext sc=getServletContext();    String obj=(String)sc.getAttribute("p");    response.getOutputStream().write(obj.getBytes());}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}

3.3获取WEB应用的初始化参数(应用的全局参数)
在web.xml的根元素下配置一下信息:
<context-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</context-param>
这些参数就属于整个应用的全局参数,使用ServletContext来读取。 可以直接进行得到全局value。

3.4读取资源文件的三种方式:
利用ServletContext.getRealPath():
特点:读取应用中任何文件。只能在Web环境下用
利用ResourceBundle读取配置文件
特点:可以用在非web环境下。但是只能读取类路径中的properties文件
利用类加载器读取配置文件(专业)
特点:可以用在非web环境下。可以读取类路径下的任何文件。

举一个例子:

package com.dp.java.servlet;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.io.PrintWriter;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 ServletDom6_file extends HttpServlet {public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {  test2(response);}/** *最简单的文件下载 */private void test2(HttpServletResponse response)throws FileNotFoundException, IOException {//得到要下载的文件ServletContext sc=getServletContext();String path=sc.getRealPath("/1.jpg");//根目录下的真实照片文件路径,必须通过它System.out.println(path);//打印路径//截取文件名String filename=path.substring(path.lastIndexOf("\\")+1);System.out.println(filename);  //构建输入流InputStream in=new FileInputStream(path);  //通知客户端的形式打开response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(filename, "UTF-8"));response.setHeader("Content-Type", "application/octet-stream");  //得到输出流OutputStream out=response.getOutputStream();int len=-1;byte b[]=new byte[1024];while((len=in.read(b))!=-1){out.write(b, 0, len);}}private String URLEncoder(String filename, String string) {// TODO Auto-generated method stubreturn null;}/** *最简单的文件下载 */private void test1(HttpServletResponse response)throws FileNotFoundException, IOException {//得到要下载的文件ServletContext sc=getServletContext();String path=sc.getRealPath("/1.jpg");//根目录下的照片System.out.println(path);//打印路径  //构建输入流InputStream in=new FileInputStream(path);  //通知客户端的形式打开response.setHeader("Content-Disposition", "attachment;filename=1.jpg");response.setHeader("Content-Type", "application/octet-stream");  //得到输出流OutputStream out=response.getOutputStream();int len=-1;byte b[]=new byte[1024];while((len=in.read(b))!=-1){out.write(b, 0, len);}}public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}}


0 0