看视频自学Servlet

(一)如何创建一个Servlet

1.继承 GenericServlet

代码:

public class ServletDemo1 extends GenericServlet{

	@Override
	public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
		
		res.getOutputStream().write("Hello servlet!".getBytes());
	}
}

web.xml中配置

  <servlet>
    <servlet-name>ServletDemo1</servlet-name>
    <servlet-class>com.boom.servlet.ServletDemo1</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>ServletDemo1</servlet-name>
    <url-pattern>/ServletDemo1</url-pattern>
  </servlet-mapping>

2.继承 HttpServlet

代码:

public class ServletDemo2 extends HttpServlet {
 
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.getOutputStream().write("Hello HttpServlet!".getBytes());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

web.xml

  <servlet>
    <description></description>
    <display-name>ServletDemo2</display-name>
    <servlet-name>ServletDemo2</servlet-name>
    <servlet-class>com.boom.servlet.ServletDemo2</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>ServletDemo2</servlet-name>
    <url-pattern>/ServletDemo2</url-pattern>
  </servlet-mapping>

(二)用new 键 新建Servlet 包含(init方法,destory方法),web.xml文件就不需要配置了

代码:

public class ServletDemo3 extends HttpServlet {
	//servlet  方法只 调用一次
	@Override
	public void init() throws ServletException { 
		// TODO Auto-generated method stub
		super.init();
		System.out.println("init");
	}

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.getOutputStream().write("Hello HttpServlet!".getBytes());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}
	
	@Override
	public void destroy() {
	System.out.println("destroy");
	}
}

web.xml不用配置了

(三)线程安全问题
1.静态变量的使用导致线程安全问题,静态变量尽量少使用

代码:

/**
 * 线程安全出现在多个线程操作同一资源上,就是静态的使用要慎重
 * @author Boom
 *
 */
public class Person {
	//如果不是静态变量的时候,当多个线程使用时用到的age是不同的,不会有线程安全
	public int age;
	
	//如果是静态变量,因为静态变量在类加载的时候都会创建,每个线程都是用到同一个对象,当同一个对象被多个线程使用时,就会产生线程并发事件
	// public static int age;
	
	//在开发中,用静态要小心,可能会造成内存奔溃
	public List list = new ArrayList();
	//public static List list = new ArrayList();
}
/**
 * 线程安全
 * @author Boom
 *
 */
public class Demo {
	//假设100个线程跑这个方法,看age的状态
	public static void main(String[] args) {
		Person person = new Person();	
		person.age++;
		//person.list.add("aaa");
		System.out.println(person.age);
	}	
}

2.实现SingleThreadModel接口解决线程安全问题

代码:

/**
 * 在web开发中,我们不用同步代码块去解决并发事件,而是通过实现一个接口SingleThreadModel(不太建议),就是打个标记
 * 这种接口叫做标记接口,同理的有序列化接口,就是标记这个类有特权
 * @author Boom
 *	Servlet就像一个网页,当出错了,我们就要抓起来
 */
public class ServletDemo5 extends HttpServlet implements SingleThreadModel {
	/**
	 * 线程安全问题
	 */
	//在这里初始化数据会出现并发事件
	int i=0; 
	//子类在覆盖父类的方法,不能抛出比父类更多的异常 (子类要比父类强,形象的说就是父亲做东西抛出了异常,子类又要比父类强我们就不能在子类抛更多的异常)
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		i++;
		try {
			Thread.sleep(1000*4);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//String.getBytes(); 把字符串输入到字节流中
		response.getOutputStream().write((i+"").getBytes());
		
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

3.用同步代码块synchronized(this){}解决线程安全问题

代码:

public class ServletDemo4 extends HttpServlet {
	/**
	 * 线程安全问题
	 */
	int i=0; 
	//在这里初始化数据会出现并发事件
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//假设100个人同时操作这个dOGet()方法 ,会不会出现并发问题
		//在方法内部定义初始化不会出现线程并发事件
		//int i=0;
		//同步代码块,单线程执行
		//用线程锁解决线程并发问题,但是这种方法不行,如果一个线程正在访问一个资源,而另一个也要等第一个线程访问完才执行获取资源
		synchronized(this){	
		i++;
		try {
			Thread.sleep(1000*4);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//String.getBytes(); 把字符串输入到字节流中
		response.getOutputStream().write((i+"").getBytes());
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

(四)ServletConfig

/**
 * ServletConfig
 * 在配置文件中定义数据,在java中获取(使用情况:在实际开发中,有些数据不适合在servlet中写死,这类数据就可以通过配置方式配置给servlet,
 * 例如:servlet采用哪个码表,servlet连接哪个库,servlet就配置哪个配置文件)
 * @author Boom
 *  其实,struts就是一个特殊的servlet
 */
public class ServletDemo6 extends HttpServlet {

	//方法一
/*    private ServletConfig servletConfig;
    
    @Override
    public void init(ServletConfig config) throws ServletException {
    	this.servletConfig=config;
    	String value = servletConfig.getInitParameter("data");
    	System.out.println(value);
    }*/
    
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		//String value = servletConfig.getInitParameter("data");  方法一
		//方法二
		String value = this.getServletConfig().getInitParameter("data");//得到指定的
		Enumeration em = this.getServletConfig().getInitParameterNames();
		while (em.hasMoreElements()) {
			String name = (String) em.nextElement();
			String value1 =	this.getServletConfig().getInitParameter(name);
			System.out.println(name+"="+value);
		}
		
    	System.out.println(value);
		response.getOutputStream().write("Hello HttpServlet!".getBytes());
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}
	
	
}

(五)ServletContext

/**
 * ServletContext 以及ServletDemo8 多个servlet之间传值(相当于聊天室)示例
 * @author Boom
 * ServletContext说的就是整个应用程序的范围  在多个servlet中共享数据
 */
public class ServletDemo7 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		//得到ServletContext的方式一:
		ServletContext	context = this.getServletConfig().getServletContext();
		//得到ServletContext的方式二:	
		//ServletContext	context1 = this.getServletContext();	
		String data="aaa";
		context.setAttribute("data",data);
	}


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

}

(六)使用ServletContext 多个servlet之间传值

/**
 * 多个servlet之间传值(相当于聊天室)
 * @author Boom
 * 
 */
public class ServletDemo8 extends HttpServlet {


	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	//应用场景  之前给每个servlet都配置数据连接,我们可以直接通过context域配置数据库连接
	String value1 =this.getServletContext().getInitParameter("data1");
	
	String value = (String) this.getServletContext().getAttribute("data");
	System.out.println(value);
	}

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

(七)Servlet中不适合对数据进行输出,我们要应用Servlet的转发

	/**
	 * Servlet中不适合对数据进行输出,我们要应用Servlet的转发
	 * @author Boom
	 * ServletDemo9和ServletDemo10
	 */

public class ServletDemo9 extends HttpServlet {
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String value =this.getServletContext().getInitParameter("data1");
		//Servlet数据输出比较麻烦,我们通过转发来实现  让jsp实现
		// servlet的重定向是让他自己去做
		// Servlet的转发是让我来帮他找人做
		response.getOutputStream().write(("<font color='red'>"+value+"</font>").getBytes());
	}

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

}

(八)同过servletcontext实现请求转发,每个web应用都有一个servletcontext

/**
 * 同过servletcontext实现请求转发,每个web应用都有一个servletcontext
 * Servlet的转发 ServletDemo9和ServletDemo10
 * @author Boom
 * 转发对象     RequestDispatcher
 */
public class ServletDemo10 extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	
		String data="aaaaa";
		this.getServletContext().setAttribute("dt", data);  //不能放在context域中,为什么呢?(涉及多线程问题,就是用的是同一对象,会覆盖数据)
		//把数据放到context域对象中,并转发给jsp去实现界面
		RequestDispatcher rd= this.getServletContext().getRequestDispatcher("/1.jsp");
		rd.forward(request, response);
	}


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

}

(九)读取资源文件 

1.通过ServletContext访问资源文件 db.propertis

/**
 * 读取资源文件 通过ServletContext访问资源文件 db.propertis
 * 
 * @author Boom
 *
 */

public class ServletDemo11 extends HttpServlet {

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

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

	//在项目的相对路径src下新建db.properties文件
	public void test1() throws IOException {
		InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
		// 固定套路 (把流输出到properties中)
		Properties properties = new Properties();
		properties.load(in);

		String url = properties.getProperty("url");
		String username = properties.getProperty("username");
		String password = properties.getProperty("password");
		System.out.println(url);
		System.out.println(username);
		System.out.println(password);
	}
	//在com.boom.thread包下新建db.properties文件
	public void test2() throws IOException {
		InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/boom/thread/db.properties");
		// 固定套路 (把流输出到properties中)
		Properties properties = new Properties();
		properties.load(in);

		String url = properties.getProperty("url");
		String username = properties.getProperty("username");
		String password = properties.getProperty("password");
		System.out.println(url);
		System.out.println(username);
		System.out.println(password);
	}
	
	//在WEB-INF下新建db.properties文件
	public void test3() throws IOException {
		InputStream in = this.getServletContext().getResourceAsStream("/db.properties");
		// 固定套路 (把流输出到properties中)
		Properties properties = new Properties();
		properties.load(in);

		String url = properties.getProperty("url");
		String username = properties.getProperty("username");
		String password = properties.getProperty("password");
		System.out.println(url);
		System.out.println(username);
		System.out.println(password);
	}
	
	//读取资源文件需要注意的问题(但是我们得在tomcat的bin文件考入文件db.properties,才能实现)  最好采用servletcontext来读取资源文件
	public void test4() throws IOException {
		FileInputStream in = new FileInputStream("classes/db.properties");
		// 固定套路 (把流输出到properties中)
		Properties properties = new Properties();  //map
		properties.load(in);
		String url = properties.getProperty("url");
		String username = properties.getProperty("username");
		String password = properties.getProperty("password");
		System.out.println(url);
		System.out.println(username);
		System.out.println(password);
	}
	
	public void test5() throws IOException{
		String path = this.getServletContext().getRealPath("/WEB-INF/classes/db.properties");
		String filename=path.substring(path.lastIndexOf("\\")+1);
		System.out.println(filename);
		FileInputStream in=new FileInputStream(path);
		// 固定套路 (把流输出到properties中)
				Properties properties = new Properties();  //map
				properties.load(in);
				String url = properties.getProperty("url");
				String username = properties.getProperty("username");
				String password = properties.getProperty("password");
				System.out.println(url);
				System.out.println(username);
				System.out.println(password);	
	}
	
}


2.如果读取资源文件的程序不是servlet的话,就只能通过类加载器去读了

代码:

新建一个UserDao

/**
 * 类装载器
 * 如果读取资源文件的程序不是servlet的话,就只能通过类装载器去读了
 * @author Boom
 *
 */
public class UserDao {
	//把东西放到预编译中,在类加载时就生成了,而且只有一次
	private static Properties dbconfig = new Properties();
	static{
		try {
		//针对如果修改了配置文件中的数据,查看运行后的输出  方案一:无论文件中怎么改还是原来的
		//以下代码虽然可以读取资源文件的数据,但是无法获取更新后的数据
		InputStream in = UserDao.class.getClassLoader().getResourceAsStream("db.properties");
		//方案二:修改后,数据也跟着修改了
		//String path = UserDao.class.getClassLoader().getResource("db.properties").getPath();
		//FileInputStream inputStream  = new FileInputStream(path); 
		//获取文件中的东西
		dbconfig.load(in);
		} catch (IOException e) {
		//抛一个初始化错误
			throw new ExceptionInInitializerError(e);
		}	
	}
	
	//不能传入一个servletcontext对象,避免耦合
	public void update() throws IOException {
		System.out.println(dbconfig.getProperty("url"));
		System.out.println(dbconfig.getProperty("username"));
		System.out.println(dbconfig.getProperty("password"));
	}
	
	public void find(){
		
	}
	
	public void delete(){
		
	}
	
	/**
	 * 总结:读取资源文件
	 * 1.在servlet中,我们可以通过servletcontext去读取资源文件的数据
	 * 2.在其他类中,我们需要通过类加载器去读取资源文件的数据
	 * 
	 */
}

新建测试类

/**
 * 如果读取资源文件的程序不是servlet的话,就只能通过类加载器去读了
 * @author Boom
 *
 */
public class ServletDemo12 extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		UserDao userdao =new UserDao();
		userdao.update();
	}

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

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值