Java Web项目实战第1篇之环境搭建

写在前面的话

从今天开始一个Java Web实战项目,参考自 http://blog.csdn.net/eson_15/article/details/51277324 这个博客(非常感谢博主的分享精神)。本博客系列文章也会参考前面博客中项目的进度来写,因此标题可能高度相似,章节结构也可能相似,只是内容排版和行文上会有些区别。

 

现在开始记录我开发的过程,争取每一个项目中的每一个知识点都有一个比较详细的记录,对每个知识点尽可能记录总结好1. 基本原理,2.框架/工具使用配置, 2.框架/工具/解决方案的基本用法。技术能力需要在实践中得到提高,概念也需要从实践中才能深刻理解,但是光做项目不够,还需要做总结,消化做过的项目,才能真正变成自己的知识。

需要说明的是本博客是边开发变记录, 因此很多东西可能不会很准确,也不会很全面, 后续会逐步订正和完善的。

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

下面开始本项目第一篇,环境的搭建,本项目主要使用主流框架SSH来完成。 搭建环境的整体步骤是是,

  1. 搭建好Java Web基础环境, 创建基本的web.xml配置文件
  2. 导入Spring框架Jar包,创建webContext.xml等配置文件,同时在web.xml中配置监听器(listener)来监听Spring容器对象的创建,这样就将Spring框架集成进了Java Web项目。
  3. 导入Hibernate框架Jar包,Hibernate大部分配置都将直接写入Spring的配置文件中,这样就将Hibernate也集成进了Java Web项目
  4. 导入Struts2框架Jar包,需要创建struts.xml用来配置Action, 同时在web.xml中配置过滤器(filter), 拦截器 (interceptor) 用来接管HTTP请求,这样就将struts2集成进了Java Web项目。

 

一、搭建Java Web基础环境

这个步骤需要注意的是做好java web的基本设置,例如编码之类。以及tomcat的一些基本配置。

1.tomcat的基本配置

下载tomcat,也可以下载xampp集成包,因为里面带有mysql使用方便。解压tomcat目录结构如下,

如果单独配置tomcat,我们需要使用如下一些配置文件

1 bin:二进制执行文件。里面最常用的文件是startup.bat,如果是 Linux 或 Mac 系统启动文件为 startup.sh。 启动tomcat后
2 conf:配置目录。里面最核心的文件是server.xml。可以在里面改端口号等。默认端口号是8080,也就是说,此端口号不能被其他应用程序占用。
3 lib:库文件。tomcat运行时需要的jar包所在的目录
4 logs:日志
5 temp:临时产生的文件,即缓存
6 webapps:web的应用程序。web应用放置到此目录下浏览器可以直接访问
7 work:编译以后的class文件。
View Code

 

如果启动上面的startup.bat, 在浏览器输入 http://localhost:8080/, 则可以看到tomcat的控制台页面(经典的汤姆猫页面),本篇暂不对tomcat的管理页面做介绍,因为本项目将使用Eclipse集成tomcat搭建web服务器。
如果要在Eclipse中集成tomcat,则不需要改动以上配置,直接在Eclipse中新建一个server,将路径指向tomcat的根目录即可,并且无需进入tomcat的bin目录去启动tomcat,而是直接在Eclipse中启动。

在Eclipse搭建基本的Java Web运行环境步骤如下,

  1. 在windows->show view->server中,添加tomcat的根目录。 Eclipse将自动配置和部署tomcat,不需要手工拷贝class文件。
  2. 新建一个java dynamic web 应用程序, 其target runtime选择刚才配置好的tomcat, 并勾选自动生成web.xml
  3. 完成前面2步,我们看到在新建的web工程的build path中,已经添加了apache tomcat library了, 此时就可以在WebContent中新建一个index.jsp, 启动tomcat,然后测试这个jsp文件(Run As->Run on Server).

      

这样就算是配置了好了一个能运行的java web应用了, 注意上面的web.xml如果没有自动生成, 可以直接拷贝 tomcat根目录的webapps\examples\WEB-INF\web.xml来用;

如果上面的tomcat library没有导入进web工程, 也可以手动在build path->libraries->Add libraries->Server Runtime中添加tomcat。

 

2. Eclipse配置全局的编码类型

如果不尽早统一编码, 由于后续需要往工程中添加jsp, java, xml 等多种不同类型的文件, 同时还需要连接数据库, 不同编码的数据在不同载体中传输存储,势必会引起乱码问题, 因此需要尽早统一编码。

在Eclipse中,默认编码是ISO-8859-1,不支持中文,可以设置全局的缺省字符编码(即默认编码),设置步骤如下。

a. windows->preference->general->workspace, 设置textfile encoding  为UTF-8

b.windows->preference->general->content types, 将右边所有文件都设置为UTF-8

c. 如果以上方法不起作用,还可以尝试直接找到相应类型的文件设置编码,如下

 

二、搭建Spring环境

1.基本的Spring 容器环境搭建

Spring中的jar包多达六七十个,但我们并不需要使用全部jar包。

按照Spring4.2.4 reference大致可以分为,core, aop, message, data access, web, test这6个模块, 我们也可以在Eclipse中分别创建不同的user library, 参考上面博客的分法,我也创建了如下library.

当我们导入core和aop两个library之后,就已经可以进行Spring最基本的IOC特性的测试了,下面是一个简单的测试用例。

2. Spring  test模块简介

Spring的test模块中,org.springframework.test.context.junit4包提供在Junit下进行Spring集成测试的功能, 其中SpringJUnit4ClassRunner类提供了Spring容器,注解功能。
要在Junit中做基本的Spring容器测试,只需要在测试类头部添加注解 @RunWith(SpringJUnit4ClassRunner.class)

Junit默认会从类加载目录加载applicationContext.xml配置文件,当然也可以通过类头部的 @ContextConfiguration(locations="classpath*:testSpringContext.xml") 自定义配置文件,

如果在测试类中定义一个自动装配的容器对象

@Autowired

private ApplicationContext ctx

则此容器对象就能自动根据Junit测试类默认的spring配置文件或者自定义的配置文件进行初始化,

此时就能直接在测试类中使用Spring容器对象去加载Spring中的bean了! 一个基本的Junit集成Spring测试类如下,

 1 @RunWith(SpringJUnit4ClassRunner.class) 
 2 @ContextConfiguration(locations="classpath*:testSpringContext.xml") 
 3 public class TestSpring {
 4     @Autowired
 5     private ApplicationContext ctx;
 6     
 7     @Test
 8     public void testSpringIoc() {
 9         TestBean tb = (TestBean)ctx.getBean("testBean");
10         tb.test();
11     }
12 }

 

现在就在当前的J2eeShop工程中通过Junit测试Spring容器的基本功能,

先创建一个测试Bean,

 1 package test;
 2 
 3 public class TestBean implements java.io.Serializable {
 4     private String name;
 5     private int age;
 6     public String getName() {
 7         return name;
 8     }
 9     public void setName(String name) {
10         this.name = name;
11     }
12     public int getAge() {
13         return age;
14     }
15     public void setAge(int age) {
16         this.age = age;
17     }
18     public void test() {
19         System.out.println("this is TestBean.test()");
20         System.out.println("name="+this.getName()+",age="+this.getAge());
21     }
22 }
View Code

从spring的文档中拷贝一个配置文件模板内容,在6.2.1 Configuration metadata章节就有一个,然后配置一个最基本的测试bean

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:context="http://www.springframework.org/schema/context"
 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans
 6         http://www.springframework.org/schema/beans/spring-beans.xsd
 7         http://www.springframework.org/schema/context 
 8    http://www.springframework.org/schema/context/spring-context-3.0.xsd">
 9 
10     <context:component-scan base-package="test" />
11 
12     <bean id="testBean" class="test.TestBean">
13         <property name="name" value="zhangsan" />
14         <property name="age" value="25" />
15     </bean>
16 </beans>
View Code

 

创建一个Junit测试类,

 1 package test;
 2 
 3 import static org.junit.Assert.*;
 4 
 5 import org.junit.Test;
 6 import org.junit.runner.RunWith;
 7 import org.springframework.beans.factory.annotation.Autowired;
 8 import org.springframework.context.ApplicationContext;
 9 import org.springframework.test.context.ContextConfiguration;
10 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
11 
12 @RunWith(SpringJUnit4ClassRunner.class) 
13 @ContextConfiguration(locations="classpath*:testSpringContext.xml") 
14 public class TestSpring {
15     @Autowired
16     private ApplicationContext ctx;
17     
18     @Test
19     public void testSpringIoc() {
20         TestBean tb = (TestBean)ctx.getBean("testBean");
21         tb.test();
22     }
23 }
View Code

执行结果,

this is TestBean.test()
name=张三,age=25

3. 在Web工程中集成Spring

我们上面的步骤仅仅是单独地配置了Web环境和Spring环境,并没有将两者集成起来。 我们在web.xml中配置<context-param>, 用来指定Spring容器的配置文,添加一个<listener>,用来监听Spring容器对象。

1     <context-param>
2         <param-name>contextConfigLocation</param-name>
3         <param-value>/WEB-INF/applicationContext.xml, /WEB-INF/daoContext.xml</param-value>
4     </context-param>
5     
6     <listener>
7         <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
8     </listener>

这样,当Java web应用启动时, 会负责根据Spring配置文件来初始化一个Sping的容器对象。

4. Java Web加载Spring原理及简单测试

像上面那样将Spring集成到Java web中后,Spring容器就会随着java web应用的启动而启动,但是整个过程的基本原理是怎样的呢。

要弄清楚这个问题,需要先搞清楚java web应用,即servlet在tomcat中的启动过程。

4.1 Java Web应用程序的启动过程

以下文章详细描述了servlet在tomcat中的工作原理,

Servlet 工作原理解析 - https://www.ibm.com/developerworks/cn/java/j-lo-servlet/
Tomcat 系统架构与设计模式,第 2 部分: 设计模式分析 - https://www.ibm.com/developerworks/cn/java/j-lo-tomcat2/

tomcat从启动到为一个java web应用提供服务的过程非常复杂,我将上面的内容高度抽象成下五步,

  1. tomcat启动过程中, 创建web容器(Container)。
  2. 向Container添加web应用,创建servlet容器(servletContext),一个web应用就对应一个servlet容器,即一个servletContext对象。
  3. 初始化servletContext:包括解析tomcat配置(server.xml等)以及web应用程序配置(主要是web.xml),加载servlet class文件等。
  4. 根据web.xml文件,初始化其中的filter, servlet, listener等
  5. 启动http服务,响应客户端请求

4.2 servlet事件监听及spring容器加载

前面说了java web应用程序的启动过程,那么集成在java web中的spring容器又是如何加载的呢?

我们知道tomcat会使用观察者/广播订阅的设计模式来通知事件的发生,当一个servlet容器(即创建了servletContext对象)启动,即发生了一个servlet容器创建事件,

tomcat中的web容器会将这个事件通知给相应监听对象。

在4.1节的第4步中,servletContext对象将会根据web.xml配置创建listener对象,我们在第3节中在web.xml配置了一个ContextLoaderListener监听器,

这是spring提供的一个监听器,servlet容器在初始化的时候会根据web.xml配置创建这样的监听器对象,这个监听器有什么作用呢?

查看这个监听器的源码如下,

 1 public class ContextLoaderListener extends ContextLoader
 2     implements ServletContextListener
 3 {
 4 ...
 5     public void contextInitialized(ServletContextEvent event)
 6     {
 7         initWebApplicationContext(event.getServletContext());
 8     }
 9 ...
10 }

可见这个监听器实现了servlet包中的ServletContextListener接口,并重写其中的contextInitialized方法,

根据servlet技术描述,servlet中的ServletContextListener实现类的实例可以监听servlet容器的启动(即创建servletContext对象)事件,并回调contextInitialized方法。

也就是说当上面的java web应用启动之后,将会通知spring的这个监听类对象,并回调被spring监听类重写的contextInitialized方法,

而在这个由spring监听器重写的回调方法中,进行了spring容器的初始化!即创建spring容器对象WebApplicationContext,并将此对象保存在servlet容器(即servletContext对象)中。

 

至此,java web容器完成了所有初始化工作,同时加载了spring容器,可以在web应用中直接使用注册在spring中的bean了,

上面过程比较复杂,下面再简要总结一下java web应用加载spring容器的过程,

  1. servlet容器创建spring listener对象
  2. web容器发出servlet容器启动成功的通知,spring的listener对象监听到事件
  3. spring的listener对象进行spring容器的初始化,并将spring容器保存进servlet容器中
  4. servlet容器加载了spring容器,此时可以直接在servlet实例中使用spring容器中的bean了

4.3 直接在jsp中测试spring和java web的集成

当我们完成了java web应用于spring的集成配置之后,就可以进行简单的测试了,我们可以直接在jsp中通过WebApplicationContextUtils获取spring容器对象,

index.jsp

 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <%@page import="org.springframework.web.context.WebApplicationContext" %>
 4 <%@page import="org.springframework.web.context.support.WebApplicationContextUtils" %>
 5 <%@page import="test.TestBean" %>
 6 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 7 <html>
 8 <head>
 9 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
10 <title>Insert title here</title>
11 </head>
12 <body>
13 <h1>Hello World</h1>
14 <%
15 WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
16 TestBean tb = (TestBean) ctx.getBean("testBean");
17 out.println("<h1>"+tb.getName()+"</h1>");
18 tb.setName("lisi");
19 %>
20 </body>
21 </html>
View Code

关键代码,

1 <%
2 WebApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
3 TestBean tb = (TestBean) ctx.getBean("testBean");
4 out.println("<h1>"+tb.getName()+"</h1>");
5 tb.setName("lisi");
6 %>

执行结果,可以看我们并没有显式地初始化spring容器,而是用工具WebApplicationContextUtils(本质上是获取由servlet容器初始化的spring容器)到了spring容器对象,将spring容器中的testBean的属性打印出来了,

 

到这里,spring框架就整合到了java web项目中,下一步是要整合Hibernate框架。

三、搭建Hibernate环境

首先也是导入Hibernat的必要jar包,以及Hibernate提供的一些第三方工具包(例如数据池C3P0和二级缓存ehcache),

 

posted @ 2017-04-24 17:24  fysola  阅读(1278)  评论(1编辑  收藏  举报