(1)配置基础装备。每个符合Java EE规范的web应用程序都需要符合相应的目录结构,如图所示。
工作之初,我们需要构建web应用的基础结构。不过,现在的IDE通常都有良好的Web开发支
持,MyEclipse9.1下载与安装请参见:http://guoyiqi.iteye.com/blog/1182653
剩下的只是按照Wizard的说明构建一个web应用的工程就行了。
a)配置web.xml。我们需要将org.springframework.Web.servlet.DispatcherServlet和
org.springframework.Web.context.ContextLoaderListener通过<servlet>和<listener>元素添
加至web.xml部署描述符文件中。另外,出于其他目的考虑,我们还可以
添加相应的Filter以及ServletContextListener以处理字符编码和Log4j初始化等配置内容,这些
完全根据当前应用程序的需求情况来决定。现在,我们的web.xml看起来如代码清单所示。
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <!-- Filter 定义 --> <!-- Character Encoding filter --> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <!-- Filter 映射 --> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!--Spring的ApplicationContext 载入 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- Spring 刷新Introspector防止内存泄露 --> <listener> <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> </listener> <!--配置Sring MVC的核心控制器DispatcherServlet --> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <!--为DispatcherServlet建立映射 --> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> <!-- session超时定义,单位为分钟 --> <session-config> <session-timeout>20</session-timeout> </session-config> <!-- 出错页面定义 --> <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/common/500.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/common/500.jsp</location> </error-page> <error-page> <error-code>404</error-code> <location>/common/404.jsp</location> </error-page> <error-page> <error-code>403</error-code> <location>/common/403.jsp</location> </error-page> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
b)WebApplicationContext文件的添加。我们需要在web-inf目录下添加org.springframework.Web.servlet.Dispatcherservlet和org.springframework.Web.context.ContextLoaderListener对应的WebApplicationContext配置文件(/WEB-INF/applicationContext.xml和
/WEB-INF/dispatcherServlet-servlet.xml)。这完全可以从Spring下载文件包中的sample目录下任何一个Web
应用程序中复制过来。只不过,需要根据命名规则修改相应的文件名称。当然,复制过来的文件内容
最好是清空,只保留可以在当前应用中能够通用的配置内容。
以上基础设施构建完成之后,我们开始“盖楼”。
(2)开发独立的业务逻辑。对于一个设计良好的web应用程序来说,虽然Web层依赖于业务层对象,
但业务层却不应该对Web层有任何的依赖。web层只应该看作是公开业务逻辑的一种视角或者交互方
式。这样做或者说这样看待系统的好处在于,业务层可以独立设计并实现,而不需要关心最终通过什
么手段将服务公开给用户。鉴于这样的理念,我们完全可以从业务层开始着手设计和实现。
entity - 领域模型层
使用Sql First的开发模式,先设计数据库,参考DBA的性能意见而不要太片面追求OO化的表结构。
package entity;
public class Author {
private String auId;
private String auLname;
private String phone;
public String getAuId() {
return auId;
}
public void setAuId(String auId) {
this.auId = auId;
}
public String getAuLname() {
return auLname;
}
public void setAuLname(String auLname) {
this.auLname = auLname;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
access - 资源访问层
资源访问层包括对数据库、JMS、外部的WebService等的访问。
每个领域对象对应一个DAO类。
package dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.RowMapperResultSetExtractor;
import entity.Author;
public class AuthorDao {
class UserRowMapper implements RowMapper{
public Object mapRow(ResultSet rs,int index) throws SQLException {
Author author = new Author();
author.setAuId(rs.getString(1));
author.setAuLname(rs.getString(2));
author.setPhone(rs.getString(3));
return author;
}
}
private JdbcTemplate jdbcTemplate;
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public List select(String where) {
List list;
String sql = "select * from authors";
list = jdbcTemplate.query(sql,new RowMapperResultSetExtractor(new UserRowMapper()));
return list;
}
}
service - 业务逻辑层
Service层有两类对象,
一类是领域对象管理类(Entity Manager), 按领域对象划分,每个Manager类负责管理多个紧密关联的Entity的增删改查及其业务逻辑。
一类是业务服务类(Service),按业务脚本划分,可能会访问到多种领域对象与Manager类。
package service;
import java.util.List;
import dao.AuthorDao;
import entity.Author;
public class AuthorService {
private AuthorDao authorDao;
public AuthorDao getAuthorDao() {
return authorDao;
}
public void setAuthorDao(AuthorDao authorDao) {
this.authorDao = authorDao;
}
public List<Author> getAuthorsList(){
return authorDao.select("");
}
}
web - Web MVC层
MVC框架使用SpringMVC框架 ,每个Action实现一组页面操作。
package web;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import service.AuthorService;
import entity.Author;
public class AuthorAction implements Controller {
private AuthorService authorService;
private String viewName; // 用于获取配置文件中的viewPage属性
public ModelAndView handleRequest(HttpServletRequest req,
HttpServletResponse res) throws Exception {
Map<String,List<Author>> model=new HashMap<String,List<Author>>();
List<Author> authors=authorService.getAuthorsList();
model.put("model", authors);
return new ModelAndView(this.getViewName(), model); // 调用getViewPage获取要返回的页面
}
public String getViewName() {
return viewName;
}
public void setViewName(String viewName) {
this.viewName = viewName;
}
public AuthorService getAuthorService() {
return authorService;
}
public void setAuthorService(AuthorService authorService) {
this.authorService = authorService;
}
}
View模板用JSP2.0 , 尽量使用纯html+JSP2.0 EL展示页面。
<%@ page language="java" import="java.util.*,entity.*" pageEncoding="UTF-8"%>
<%@ include file="/common/taglibs.jsp" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'authorsList.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
This is my JSP page2. <br>
<c:forEach items="${model}" var="author">
${author.auId},${author.auLname }${author.phone }<br/>
</c:forEach>
</body>
</html>
Javascript与Ajax使用JQuery或Dojo Base。
尽量采用CSS框架规范CSS的布局。
(3)配置
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> <!-- 定义受环境影响易变的变量 --> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE" /> <property name="ignoreResourceNotFound" value="true" /> <property name="locations"> <list> <!-- 标准配置 --> <value>/WEB-INF/application.properties</value> </list> </property> </bean> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <!-- Connection Info --> <property name="driverClassName" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}"></property> <!-- Connection Pooling Info --> <property name="maxIdle" value="${dbcp.maxIdle}" /> <property name="maxActive" value="${dbcp.maxActive}" /> <property name="defaultAutoCommit" value="false" /> <property name="timeBetweenEvictionRunsMillis" value="3600000" /> <property name="minEvictableIdleTimeMillis" value="3600000" /> </bean> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <property name="dataSource"> <ref bean="dataSource" /> </property> </bean> <bean id="authorDao" class="dao.AuthorDao"> <property name="jdbcTemplate"> <ref bean="jdbcTemplate" /> </property> </bean> <bean id="authorService" class="service.AuthorService"> <property name="authorDao"> <ref bean="authorDao" /> </property> </bean> </beans>
dispatcherServlet-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="localeResolver" class="org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver"> </bean> <!--配置控制器的映射--> <bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <prop key="authorAction.do">authorAction</prop> </props> </property> </bean> <!--配置视图--> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/content/" /> <property name="suffix" value=".jsp" /> </bean> <!--指定控制器的实现类,并且配置其参数的值--> <bean id="authorAction" class="web.AuthorAction"> <property name="viewName"> <value>authorsList</value> </property> <property name="authorService"> <ref bean="authorService" /> </property> </bean> </beans>
(4)发布运行