网络编程 | 站长之家 | 网页制作 | 图形图象 | 操作系统 | 冲浪宝典 | 软件教学 | 网络办公 | 邮件系统 | 网络安全 | 认证考试 | 系统进程
Firefox | IE | Maxthon | 迅雷 | 电驴 | BitComet | FlashGet | QQ | QQ空间 | Vista | 输入法 | Ghost | Word | Excel | wps | Powerpoint
asp | .net | php | jsp | Sql | c# | Ajax | xml | Dreamweaver | FrontPages | Javascript | css | photoshop | fireworks | Flash | Cad | Discuz!
当前位置 > 网站建设学院 > 网络编程 > Java
Tag:注入,存储过程,分页,安全,优化,xmlhttp,fso,jmail,application,session,防盗链,stream,无组件,组件,md5,乱码,缓存,加密,验证码,算法,cookies,ubb,正则表达式,水印,索引,日志,压缩,base64,url重写,上传,控件,Web.config,JDBC,函数,内存,PDF,迁移,结构,破解,编译,配置,进程,分词,IIS,Apache,Tomcat,phpmyadmin,Gzip,触发器,socket
网络编程:ASP教程,ASP.NET教程,PHP教程,JSP教程,C#教程,数据库,XML教程,Ajax,Java,Perl,Shell,VB教程,Delphi,C/C++教程,软件工程,J2EE/J2ME,移动开发
本月文章推荐
.java变量的赋值与传递.
.osworkflow源码分析(一).
.java设计模式之Builder(解耦过程.
.EJB的编程限制.
.Struts源代码阅读(Commons-Vali.
.Java CORBA入门.
..net 的 MSMQ 异步调用全过程分析.
.bean里面如何打印到html页面.
.Java多线程编程基础之线程对象.
.TOMCAT+JIVE的安装配置(支持中文).
.The Alloy Look And Feel 1.4.4破.
.从XML到Java代码的数据绑定之对象.
.Java入门(8) 创建新类.
.Java学习之了解Java的运行环境.
.JBuilderX初体验.
.将 Java Web 应用从 Windows 移植.
.如何在JAVA SE中使用Hibernate.
.无需调优的内存优化.
.如何使用Java自带的正则表达式.
.something about Listeners.

基于 J2EE 体系实现多层结构 Blog 平台(2)

发表日期:2008-1-5



  六、配置iBatis
  接下来,使用iBatis实现O/R Mapping。首先从http://www.ibatis.com下载iBatis 2.0,将所需的jar文件复制到web/WEB-INF/lib/目录下。iBatis使用XML配置数据库表到Java对象的映射,先编写一个sql-map-config.xml:
  
  <?xml version="1.0" encoding="utf-8" ?>
  <!DOCTYPE sqlMapConfig
   PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
   "http://www.ibatis.com/dtd/sql-map-config-2.dtd">
  <sqlMapConfig>
   <settings cacheModelsEnabled="false" enhancementEnabled="true"
    lazyLoadingEnabled="true" maxRequests="32"
    maxSessions="10" maxTransactions="5"
    useStatementNamespaces="false"
   />
   <transactionManager type="JDBC">
    <dataSource type="JNDI">
     <property name="DataSource" value="jdbc/blog" />
    </dataSource>
   </transactionManager>
   <!-- 假如有其他xml配置文件,可以包含进来 -->
   <sqlMap resource="Account.xml" />
  </sqlMapConfig>
  
  将sql-map-config.xml放到web/WEB-INF/classes/目录下,iBatis就能搜索到这个配置文件,然后编写一个初始化类:
  
  public class SqlConfig {
    private SqlConfig() {}
    private static final SqlMapClient sqlMap;
    static {
      try {
        java.io.Reader reader = Resources.getResourceAsReader ("sql-map-config.xml");
        sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);
      } catch (Exception e) {
        e.printStackTrace();
        throw new RuntimeException("Error initializing SqlConfig. Cause: " + e);
      }
    }
    public static SqlMapClient getSqlMapInstance () {
      return sqlMap;
    }
  }
  
  SqlMapClient封装了访问数据库的大部分操作,可以直接使用SqlConfig.getSqlMapInstance()获得这个唯一实例。
  
  七、使用DAO模1式
  为了分离逻辑层和数据库持久层,定义一系列DAO接口:AccountDao,CategoryDao,ArticleDao……其实现类对应为SqlMapAccountDao,SqlMapCategoryDao,SqlMapArticleDao……这样就使得逻辑层完全脱离了数据库访问代码。假如将来需要使用其它的O/R Mapping方案,直接实现新的DAO接口替代现有的SqlMapXxxDao即可。以SqlMapAccountDao为例,实现一个login()方法是非常简单的:
  
  public int login(String username, String passWord) throws AuthorizationException {
    try {
      Map map = new HashMap();
      map.put("username", username);
      map.put("password", password);
      Integer I = (Integer)sqlMap.queryForObject("login", map);
      if(I==null)
        throw new RuntimeException("Failed: Invalid username or password.");
      return I.intValue();
    }
    catch(SQLException sqle) {
      throw new RuntimeException("Sql Exception: " + sqle);
    }
  }
  
  在Account.xml配置文件中定义login查询:
  
  <select id="login" parameterClass="java.util.Map" resultClass="int">
   select [accountId] from [Account] where
   [username] = #username# and password = #password#
  </select>
  
  八、逻辑层设计
  由于DAO模式已经实现了所有的数据库操作,业务逻辑主要是检查输入,调用DAO接口,因此业务逻辑就是一个简单的Facade接口:
  
  public class FacadeImpl implements Facade {
    private AccountDao accountDao;
    private ArticleDao articleDao;
    private CategoryDao categoryDao;
    private FeedbackDao feedbackDao;
    private ImageDao  imageDao;
    private LinkDao   linkDao;
    private SequenceDao sequenceDao;
  }
  
  对于普通的getArticle()等方法,Facade仅仅简单地调用对应的DAO接口:
  
  public Article getArticle(int articleId) throws QueryException {
    return articleDao.getArticle(articleId);
  }
  
  对于需要身份验证的操作,如deleteArticle()方法,Facade需要首先验证用户身份:
  
  public void deleteArticle(Identity id, int articleId) throws DeleteException {
    Article article = getArticleInfo(articleId);
    if(article.getAccountId()!=id.getAccountId())
      throw new AuthorizationException("Permission denied.");
    articleDao.deleteArticle(articleId);
  }
  
  要分离用户验证逻辑,可以使用Proxy模式,或者使用Spring的AOP,利用MethodInterceptor实现,不过,由于逻辑很简单,完全可以直接写在一块,不必使用过于复杂的设计。 至此,我们的Blog已经实现了所有的后台业务逻辑,并且提供统一的Facade接口。前台Web层仅仅依靠这个Facade接口,这样,Web层和后台耦合非常松散,即使替换整个Web层也非常轻易。
  
  九、Web层设计:使用MVC模式
  对于复杂的Web层,使用MVC模式是必不可少的。虽然Spring能轻易集成Struts,WebWorks等Web框架,但Spring本身就提供了一个非常好的Web框架,能完全实现MVC模式。
  
  Spring使用一个DispatcherServlet,所有的特定请求都被转发到DispatcherServlet,然后由相应的Controller处理,Controller返回一个ModelAndView对象(因为Java语言的方法调用只能返回一个结果,而且不支持ref参数,所以将Model和View对象合在一起返回),Model是一个Java对象,通常是Map,View是视图的逻辑名字,通常是jsp文件名,但也可以使用Velocity等作为视图。返回的View通过viewResolver得到真正的文件名。首先配置Spring的MVC,在web.xml中声明DispatcherServlet,处理所有以.c结尾的请求:
  
  <web-app>
    <servlet>
      <servlet-name>dispatcher</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
      <servlet-name>dispatcher</servlet-name>
      <url-pattern>*.c</url-pattern>
    </servlet-mapping>
  </web-app>
  
  Spring会在WEB-INF下查找一个名为dispatcher-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>
  </beans>
  
  用到的所有的Java Bean组件都要在这个文件中声明和配置,以下是配置URL映射的Bean:
  
  <bean id="urlMapping"
   class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
      <props>
        <prop key="/article.c">articleController</prop>
      </props>
    </property>
  </bean>
  
  凡是匹配/article.c的Request都会被名为articleController的Bean处理,同样需要声明这个articleController:
  
  <bean id="articleController" class="example.ViewArticleController">
  </bean>
  
  ViewArticleController处理请求,然后生成Model,并选择一个View:
  
  public class ViewArticleController implements Controller {
    private Facade facade;
    public void setFacade(Facade facade) { this.facade = facade; }
  public ModelAndView handleRequest(HttpServletRequest request,
    HttpServletResponse response) throws Exception {
      // 获得参数:
      int articleId = Integer.parseInt(request.getParameter("articleId"));
      // 使用facade处理请求:
      Article article = facade.getArticle(articleId);
      // 生成Model:
      Map map = new HashMap();
      map.put("article", article);
      // 返回Model和视图名“SKIN/blueskysimple/article”:
      return new ModelAndView("skin/blueskysimple/article", map);
    }
  }
  
  最后,skin/bluesky/article视图会将结果显示给用户。
  
  我们注重到,ViewArticleController并不自己查找或者创建Facade,而是由容器通过setFacade(Facade)方法设置的,这就是所谓的IoC(Inversion of Control)或者Dependency Injection。容器通过
上一篇:值得思考的 J2EE 架构的6个最佳实践 人气:500
下一篇:基于 J2EE 体系实现多层结构 Blog 平台(3) 人气:840
浏览全部Java的内容 Dreamweaver插件下载 网页广告代码 祝你圣诞节快乐 2009年新年快乐