这两天忙公司的项目,没有把项目的demo写出来。趁如今空闲,偷偷的写一下。
先上demo结构目录图:

你们看到了吧,项目层次分得很清楚。
config 是 spring和itatis的配置文件。接下来就是经典的mvc分层架构啦,bean ---- dao ---- service ----- action --- view。理论的东西,我就很少说了。下面我按照这个demo开发流程一步一步写出来:
一。在eclipse新建项目,导入jar包,有木有??!!!
二。集成spring和struts,web.xml文件配置以下:javascript
- <span style="font-size:16px;"><?xml version="1.0" encoding="UTF-8"?>
- <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
- http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
- <display-name>ctcoms</display-name>
- <description>A Java Forum System Based on Struts2</description>
- <!-- 加载spring 配置文件 -->
- <context-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath*:config/spring*.xml</param-value>
- </context-param>
- <listener>
- <listener-class>
- org.springframework.web.context.ContextLoaderListener
- </listener-class>
- </listener>
-
- <!-- 定义Struts 2的FilterDispatcher的Filter -->
- <filter>
- <!-- 定义核心Filter的名字 -->
- <filter-name>struts2</filter-name>
- <!-- 定义核心Filter的实现类 -->
- <filter-class>
- org.apache.struts2.dispatcher.FilterDispatcher
- </filter-class>
- <!-- 设置编码 -->
- <init-param>
- <param-name>encoding</param-name>
- <param-value>utf-8</param-value>
- </init-param>
- </filter>
-
- <!-- FilterDispatcher用来初始化Struts 2而且处理全部的Web请求 -->
- <filter-mapping>
- <filter-name>struts2</filter-name>
- <url-pattern>/*</url-pattern>
- </filter-mapping>
-
- <!-- jsp等头文件的过滤器,解决乱码用 -->
- <filter>
- <filter-name>AddHeaderFilter</filter-name>
- <filter-class>
- org.mission.ctcoms.web.filter.AddHeaderFilter
- </filter-class>
- <init-param>
- <param-name>headers</param-name>
- <param-value>Content-Encoding=gzip</param-value>
- </init-param>
- </filter>
- <filter-mapping>
- <filter-name>AddHeaderFilter</filter-name>
- <url-pattern>*.gzjs</url-pattern>
- </filter-mapping>
- <welcome-file-list>
- <welcome-file>/login.jsp</welcome-file>
- <welcome-file>/index.jsp</welcome-file>
- </welcome-file-list>
-
-
- <error-page>
- <exception-type>java.lang.Exception</exception-type>
- <location>/error.jsp</location>
- </error-page>
- </web-app>
- </span>
三。项目里,spring是用来配置数据库,事物管理,配置ibatis, 管理struts的action,管理dao层的bean,管理service的bean。相关的配置文件以下图:css

四。在classpath路径下,新建struts.xml 和log4j.properties 文件,分别是 struts的映射文件 和 日志信息的配置。html
五。把配置文件建好之后,就开始写代码了。这个demo业务很简单,只有一个bean,一张表就足够了。表的话 你们就本身建把,一个主键,一个产品名就OK啦。java
bean的代码就不贴出来了,就是getter 和setting方法。jquery
六。创建ibatis的sql配置文件,StoreProduct.xml以下:web
- <span style="font-size:16px;"><?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE sqlMap
- PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
- "http://ibatis.apache.org/dtd/sql-map-2.dtd">
- <sqlMap namespace="StoreProduct">
- <select id="findStoreProdctListNameForJson" parameterClass="java.lang.String" resultClass="java.lang.String" >
- select S.name from zy_store_product S where lower(S.name) LIKE lower('%$productName$%')
- </select>
- </sqlMap>
- </span>
namespace 就是 sql的命名空间;findStoreProdctListNameForJson 为 调用sql 的惟一标识id; parameterClass 为参数类型,这里是传了一个产品名的字符串;resultClass为返回值类型。spring
select S.name from zy_store_product S where lower(S.name) LIKE lower('%$productName$%') 就是一句标准的sql语句了,$productName$ 表明参数。在这里能够执行任何复杂的sql语句,这就是sql
ibatis的灵活之处。ibatis的用法这里就不详细说了,之后有机会贴上一篇ibatis的增删查改的demo。数据库
七。封装一个操做ibatis的类,用于简化ibatis的crud(增删查改)操做,每一个dao都要继承这个类。BaseIbaitsDAO 以下:apache
- <span style="font-size:16px;">package org.mission.ctcoms.ibatis;
-
- import java.util.Date;
- import java.util.List;
- import java.util.Map;
-
- import org.apache.log4j.Logger;
- import org.apache.struts2.ServletActionContext;
- import org.mission.ctcoms.exception.ApplicationException;
- import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;
-
- /**
- *
- * @author 黄宇强
- * @date 2011-8-5 上午09:27:06
- * @description This base class is prepared for subclass to do CRUD easily.
- */
- public class BaseIbaitsDAO extends SqlMapClientDaoSupport {
- private Logger log4j = Logger.getLogger(BaseIbaitsDAO.class);
-
- /**
- * 根据条件查询对象集合
- *
- * @param sqlid
- * 对应IBATIS xml SQL_ID
- * @param paramObj
- * 参数对象
- * @return
- */
- @SuppressWarnings("unchecked")
- public <T> List<T> loadList(String sqlid, Object paramObj) {
- return (List<T>) getSqlMapClientTemplate()
- .queryForList(sqlid, paramObj);
- }
-
- /**
- * 根据条件查询对象全部数据
- *
- * @param <T>
- * @param sqlid
- * 对应IBATIS xml SQL_ID
- * @return
- */
- @SuppressWarnings("unchecked")
- public <T> List<T> loadList(String sqlid) {
- return (List<T>) getSqlMapClientTemplate().queryForList(sqlid);
- }
-
- /**
- * 根据ID查询ENTITY 对象
- *
- * @param <T>
- * @param sqlid对应IBATIS
- * xml SQL_ID
- * @return <T> 实体对象
- */
- @SuppressWarnings("unchecked")
- public <T> T loadObject(String sqlid) {
- return (T) getSqlMapClientTemplate().queryForObject(sqlid);
- }
-
- /**
- * 根据ID查询ENTITY 对象
- *
- * @param <T>
- * @param sqlid对应IBATIS
- * xml SQL_ID
- * @param id
- * 实体ID
- * @return <T> 实体对象
- */
- @SuppressWarnings("unchecked")
- public <T> T loadObject(String sqlid, String id) {
- return (T) getSqlMapClientTemplate().queryForObject(sqlid, id);
- }
-
- /**
- * 根据ID查询ENTITY 对象
- *
- * @param <T>
- * @param sqlid对应IBATIS
- * xml SQL_ID
- * @param id
- * 实体ID
- * @return <T> 实体对象
- */
- @SuppressWarnings("unchecked")
- public <T> T loadObject(String sqlId, Long id) {
- return (T) getSqlMapClientTemplate().queryForObject(sqlId, id);
- }
-
- /**
- * 根据条件查询对象
- *
- * @param <T>
- * @param sqlid对应IBATIS
- * xml SQL_ID
- * @param paramObj
- * 参数
- * @return <T> 实体对象
- */
- @SuppressWarnings("unchecked")
- public <T> T loadObject(String sqlId, Object paramObj) {
- return (T) getSqlMapClientTemplate().queryForObject(sqlId, paramObj);
- }
-
- /**
- * 保存对象
- *
- * @param sqlid
- * 对应IBATIS xml SQL_ID
- * @param entity
- * 保存的对象
- */
- public void save(String sqlid, Object entity) {
- getSqlMapClientTemplate().insert(sqlid, entity);
- }
-
- /**
- * 保存对象
- *
- * @param sqlid
- * 对应IBATIS xml SQL_ID
- * @param entity
- * 保存的对象
- */
- public void save(String sqlid, Map<String, Object> entity) {
- getSqlMapClientTemplate().insert(sqlid, entity);
- }
-
- /**
- * 更新对象
- *
- * @param sqlid
- * 对应IBATIS xml SQL_ID
- * @param entity
- * 修改对象
- */
- public void update(String sqlId, Map<String, Object> entity) {
- getSqlMapClientTemplate().update(sqlId, entity);
- }
-
- /**
- * 更新对象
- *
- * @param sqlid
- * 对应IBATIS xml SQL_ID
- * @param entity
- * 修改对象
- */
- public void update(String sqlId, Object entity) {
- getSqlMapClientTemplate().update(sqlId, entity);
- }
-
- /**
- * 删除指定的对象
- *
- * @param sqlId
- * @param object
- * 须要删除的对象
- */
- public void delete(String sqlId, Object object) {
- getSqlMapClientTemplate().delete(sqlId, object);
- }
-
- /**
- * 查询数据总条数
- *
- * @param sqlid
- * @param object
- * @return
- */
- public Long loadRecordCountObject(String sqlid, Object object) {
- log4j.info("sqlid====" + sqlid);
- return (Long) getSqlMapClientTemplate().queryForObject(sqlid, object);
- }
-
- /**
- * 查询数据总条数
- *
- * @param sqlid
- * @param object
- * @return 返回Int
- */
- public Integer loadRecordCount(String sqlid, Object object) {
- log4j.info("sqlid====" + sqlid);
- return (Integer) getSqlMapClientTemplate()
- .queryForObject(sqlid, object);
- }
-
- /**
- * @Title: findTNextId
- * @Description: 返回表中ID最大值加一
- * @param:
- * @param tabName
- * 表名
- * @return:
- * @returnType: Long
- * @throws
- */
- public Long findTNextId(String tabName) {
- Long id = 0l;
- String seqName = tabName.substring(3) + "_S";
- id = (Long) getSqlMapClientTemplate().queryForObject(
- "Common.findTNextId", seqName);
- if (id == null || id.equals(0l))
- throw new ApplicationException("ID查询错误");
- return id;
- }
-
- public Date findOracleSysdate() {
-
- return (Date) getSqlMapClientTemplate().queryForObject(
- "Common.findOracleSysdate", null);
- }
-
- }
- </span>
八。用到spring ,是基于接口的编程了。分别实现 service、dao层的接口以及其实现类。须要注意的是,每一个service、dao都要写进spring的相关配置文件去,实现spring对bean的管理。
九。crum的代码写好了,就到action层了。
- <span style="font-size:16px;">package org.mission.ctcoms.web.action.storage;
-
- import java.util.List;
-
- import org.apache.log4j.Logger;
- import org.mission.ctcoms.business.storage.IStoreProductService;
- import org.mission.ctcoms.web.code.BaseAction;
-
- public class StorageProductAction extends BaseAction {
-
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
-
- private Logger log4j = Logger.getLogger(StorageProductAction.class);
-
- private IStoreProductService storeProductService;
-
- private List<String> content; //传到前台显示用
-
- private String productName; // 产品名
-
-
- public String findStoreProdctListNameForJson() {
- try {
- String newProductName = new String(productName.getBytes("ISO-8859-1"),"utf-8"); // !!!解决参数乱码
- List<String> list = storeProductService.findStoreProdctListNameForJson(newProductName);
- this.setContent(list);
- } catch (Exception e) {
- log4j.error("findStoreProdctListNameForJson error", e);
- }
-
- return SUCCESS;
-
- }
-
-
-
- public Logger getLog4j() {
- return log4j;
- }
-
- public void setLog4j(Logger log4j) {
- this.log4j = log4j;
- }
-
-
- public IStoreProductService getStoreProductService() {
- return storeProductService;
- }
-
- public void setStoreProductService(IStoreProductService storeProductService) {
- this.storeProductService = storeProductService;
- }
-
- public String getProductName() {
- return productName;
- }
-
- public void setProductName(String productName) {
- this.productName = productName;
- }
-
- public List<String> getContent() {
- return content;
- }
-
- public void setContent(List<String> content) {
- this.content = content;
- }
-
-
- }
- </span>
而后,该action查询到的数据库数据是以json方传递到前台的,因此该action注册到struts的配置文件以下:
- <span style="font-size:16px;"><?xml version="1.0" encoding="UTF-8" ?>
- <!DOCTYPE struts PUBLIC
- "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
- "http://struts.apache.org/dtds/struts-2.0.dtd">
-
- <struts>
-
- <package name="json-storage"
- extends="json-default">
- <action name="findStoreProdctListNameForJson" method="findStoreProdctListNameForJson"
- class="storageProductAction">
- <result type="json">
- <param name="root">content</param>
- </result>
- </action>
- </package>
- <constant name="struts.action.extension" value="do" />
- </struts>
- </span>
其中 content是json的标识,与action的content和稍后说起的jquery调用 相对应。extends="json-default" 是继承 struts-json插件的方法。
注: 该action 继承了封装好了的BaseAction,该类以下:
- <span style="font-size:16px;">package org.mission.ctcoms.web.code;
-
- import java.io.IOException;
- import java.io.PrintWriter;
-
- import javax.servlet.ServletContext;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
-
- import org.apache.log4j.Logger;
- import org.apache.struts2.ServletActionContext;
-
- import com.opensymphony.xwork2.ActionSupport;
-
- /**
- *
- * @author 黄宇强
- * @date 2011-8-5 上午09:25:04
- * @description 抽象类
- */
- public class BaseAction extends ActionSupport {
- /**
- *
- */
- private static final long serialVersionUID = -4025716041310497629L;
-
- private Logger log4j = Logger.getLogger(BaseAction.class);
-
- public String jsonString;
-
- public void outJsonString(String str) {
- getResponse().setContentType("text/javascript;charset=UTF-8");
- outString(str);
- }
-
- public void outString(String str) {
- try {
- PrintWriter out = getResponse().getWriter();
- out.write(str);
- } catch (IOException e) {
- e.printStackTrace();
- log4j.error("out print failed:" + e);
- }
- }
-
- public void outXMLString(String xmlStr) {
- getResponse().setContentType("application/xml;charset=UTF-8");
- outString(xmlStr);
- }
-
- /**
- * 得到request
- *
- * @return
- */
- public HttpServletRequest getRequest() {
- return ServletActionContext.getRequest();
- }
-
- /**
- * 得到response
- *
- * @return
- */
- public HttpServletResponse getResponse() {
- return ServletActionContext.getResponse();
- }
-
- /**
- * 得到session
- *
- * @return
- */
- public HttpSession getSession() {
- return getRequest().getSession();
- }
-
- /**
- * 得到servlet上下文
- *
- *
- *
- * @return
- */
- public ServletContext getServletContext() {
- return ServletActionContext.getServletContext();
- }
-
- public String getRealyPath(String path) {
- return getServletContext().getRealPath(path);
- }
-
- }
- </span>
十。最后一步了,就是到前台页面。如何调用jquery.autocomplete,这个很简单,下载官方的demo下来,很容易就看明白了。贴出jsp的实现页面:
- <span style="font-size:16px;"><%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
- <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
- <html>
- <head>
-
- <title>产品自动补全</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">
- <script type="text/javascript" src="jquery/jquery.js"></script>
- <script type="text/javascript" src="jquery/jquery.autocomplete.js"></script>
- <link rel="Stylesheet" type="text/css" href="jquery/jquery.autocomplete.css" />
- <script type="text/javascript">
- var v_product_Store ;
- $().ready(function() {
- $("#productName").autocomplete("findStoreProdctListNameForJson.do", { //当用户输入关键字的时候 ,经过 url的方式调用action的findStoreProdctListNameForJson方法
- minChars: 1, //最小显示条数
- max: 12, //最大显示条数
- autoFill: false,
- dataType : "json", //指定数据类型的渲染方式
- extraParams:
- {
- productName: function()
- {
- return $("#productName").val(); //url的参数传递
- }
- },
-
- //进行对返回数据的格式处理
- parse: function(data)
- {
- var rows = [];
- for(var i=; i<data.length; i++)
- {
- rows[rows.length] = {
- data:data[i],
- value:data[i],
- //result里面显示的是要返回到列表里面的值
- result:data[i]
- };
- }
- return rows;
- },
- formatItem: function(item) {
- //没有特殊的要求,直接返回了
- return item;
- }
- });
-
- });
- </script>
-
- </head>
-
- <body>
- <div>
- 产品名: <input type="text" id="productName" />
- </div>
- </body>
- </html>
- </span>
OK!搞定!再看一下效果图:
