现在的位置: 首页 > 综合 > 正文

Servlet学习

2017年03月28日 ⁄ 综合 ⁄ 共 5059字 ⁄ 字号 评论关闭

一、Servlet
    1.sun提供的一种动态web资源开发技术.本质上就是一段java小程序.可以将Servlet加入到Servlet容器中运行.
    *Servlet容器 -- 能够运行Servlet的环境就叫做Servlet容器. --- tomcat

    *web容器 -- 能够运行web应用的环境就叫做web容器 --- tomcat

 2.
        写一个类实现sun公司定义的Servlet接口
        将写好的类配置到tomcat中的web应用的web.xml中,(配置对外访问路径)

  3.Servlet的调用过程/生命周期

 4.Servlet的继承结构
        Servlet接口 -- 定义了Servlet应该具有的基本方法
            |
            |--GenericServlet --通用基本Servlet实现,对于不常用的方法在这个实现类中进行了基本的实现,对于Service设计为了抽象方法,需要子类去实现
                    |
                    |--HttpServlet --在通用Servlet的基础上基于HTTP协议进行了进一步的强化:实现了GenericServlet中的Service方法,判断当前的请求方式,调用对应到doXXX方法,这样一来我们开发Servlet的过程中只需继承HttpServlet ,覆盖具体要处理的doXXX方法就可以根据不同的请求方式实现不同的处理.一般不要覆盖父类中的Service方法只要覆盖doGet/doPost就可以了

线程安全问题
            由于默认情况下Servlet在内存中只有一个对象,当多个浏览器并发访问Servlet时就有可能产生线程安全问题
            解决方案:
                加锁--效率降低
                SingleThreadModel接口 -- 不能真的防止线程安全问题
                最终解决方案:在Servlet中尽量少用类变量,如果一定要用类变量则用锁来防止线程安全问题,但是要注意锁住内容应该是造成线程安全问题的核心代码,尽量的少锁主内容,减少等待时间提高servlet的响应速度

ServletConfig -- 代表当前Servlet在web.xml中的配置信息
         String getServletName()  -- 获取当前Servlet在web.xml中配置的名字
         String getInitParameter(String name) -- 获取当前Servlet指定名称的初始化参数的值
         Enumeration getInitParameterNames()  -- 获取当前Servlet所有初始化参数的名字组成的枚举
         ServletContext getServletContext()  -- 获取代表当前web应用的ServletContext对象

一般运用的时候用的比较的少,可以运用在配置数据库信息、配置字符编码

ServletContext -- 代表当前web应用
    1.做为域对象可以在整个web应用范围内共享数据
        域对象:在一个可以被看见的范围内共享数据用到对象
        
        作用范围:整个web应用范围内共享数据
        生命周期:当服务器启动web应用加载后创建出ServletContext对象后,域产生。当web应用被移除出容器或服务器关闭,随着web应用的销毁域销毁。
      
       void setAttribute(String,Object);
       Object getAttribute(String);
       void removeAttribute(String);
     
     2.用来获取web应用的初始化参数

             请求参数 parameter --- 浏览器发送过来的请求中的参数信息
     初始化参数 initparameter --- 在web.xml中为Servlet或ServletContext配置的初始化时带有的基本参数
     域属性 attribute --- 四大作用于中存取的键值对
     

	ServletContext context = this.getServletContext();
		Enumeration enumeration = context.getInitParameterNames();
		while(enumeration.hasMoreElements()){
			String name = (String) enumeration.nextElement();
			String value = context.getInitParameter(name);
			System.out.println(name+":"+value);
		}

     

     3.实现Servlet的转发
        
        重定向 : 302+Location
        请求转发 : 服务器内不进行资源流转
        
        *请求转发是一次请求一次响应实现资源流转.请求重定向两次请求两次响应.

public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		RequestDispatcher dispatcher = this.getServletContext().getRequestDispatcher("/servlet/Demo6Servlet");
		dispatcher.forward(request, response);
	}

        
      4.加载资源文件
            在Servlet中读取资源文件时:
                如果写相对路径和绝对路径,由于路径将会相对于程序启动的目录--在web环境下,就是tomcat启动的目录即tomcat/bin--所有找不到资源
                如果写硬盘路径,可以找到资源,但是只要一换发布环境,这个硬盘路径很可能是错误的,同样不行.
                为了解决这样的问题ServletContext提供了getRealPath方法,在这个方法中传入一个路径,这个方法的底层会在传入的路径前拼接当前web应用的硬盘路径从而得到当前资源的硬盘路径,这种方式即使换了发布环境,方法的底层也能得到正确的web应用的路径从而永远都是正确的资源的路径
                 this.getServletContext().getRealPath("config.properties")
                

package com.itheima;

import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Properties;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * ServletContext读取资源文件
 */
public class Demo7Servlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
//		File file = new File("config.properties");
//		System.out.println(file.getAbsolutePath());
		//--如果写相对路径,则会到程序启动目录 即tomcat/bin目录下去找资源,找不到
		//--如果写绝对路径,则会到程序启动目录的根目录 即tomcat/bin 目录的磁盘目录,我的机器tomcat在e:/workspace/tomcatt6 所以找到了e:/下去找资源,找不到
		//--如果用硬盘路径,则能找到资源,但是一旦换一个运行环境,很可能硬盘路径就是不正确的了,也不行
		//----所以,在web环境下如果项读取资源文件,必须使用ServletContext提供的方法进行读取,
		//		原理是在传入的路径前拼接当前web应用的硬盘路径从而得到当前资源的硬盘路径,
		//		由于web应用的硬盘路径是动态获取的,即使换了发布环境也是正确的,所以路径就保证了永远是正确的
		Properties prop = new Properties();
		prop.load(new FileReader(this.getServletContext().getRealPath("config.properties")));
		
		System.out.println(prop.getProperty("username"));
		System.out.println(prop.getProperty("password"));
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

   如果在非Servlet环境下要读取资源文件时可以采用类加载器加载文件的方式读取资源
    Service.class.getClassLoader().getResource("../../../config.properties").getPath()

public class Service {
	public void methdo1() throws FileNotFoundException, IOException{
		//--在没有ServletContext的环境下,如果想要读取资源,可以使用类加载器以加载类的方式加载资源,
		//		这里要注意,类加载器从哪个目录加载类,就从哪个目录加载资源,
		//		所以此处的路径一定要给一个相对于类加载目录的路径
		Properties prop = new Properties();
		prop.load(new FileReader(Service.class.getClassLoader().getResource("../../../config.properties").getPath()));
		System.out.println(prop.getProperty("username"));
		System.out.println(prop.getProperty("password"));
	}
}

然后再Servlet中调用该方法,实现类加载文件读取资源。

package com.itheima;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.itheima.service.Service;
/**
 * 类加载器方式读取资源文件
 */
public class Demo8Servlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		Service service = new Service();
		service.methdo1();
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

 

抱歉!评论已关闭.