最近写了一个微信平台的架构,采用servlet + spring3.0 + hibernate4.1。整体架构由我负责建设,我尽可能的把业务模块分出来。趁着刚搭好的框架,留着这版。代码是大部份都由其他成熟框架直接 copy过来整合,去掉了一些没用的配置。部分我加入的设计也都是自己经过长时间项目提炼出来的,所有代码稳定性大可放心,并且难度不大。源码我也贴网上,希望有人帮我一起完善一下!不足处也请批评指正。

贴出部分代码,用到了部分设计模式,代码可读性比较好。没什么技术含量,里面有一些涉及微信平台的业务代码可能会有点难懂,如果您认为还不错,那就点个赞。如果认为还值得改进,那也麻烦提出来,我也近期慢慢改进。

代码贴在这里,如果有人愿意一同学习进步,后期就放到github上面去,现阶段我将持续改进。

下载地址

http://pan.baidu.com/s/1i320J3n

spring部分代码:

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
       ">

    <!-- 扫描注解Bean -->
    <context:component-scan base-package="com.cpic">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:resources.properties</value>
            </list>
        </property>
    </bean>

      <bean id="dataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource">
        <property name="alias" value="proxoolDataSource"/>
        <property name="driver" value="${connection.driver_class}" />
        <property name="driverUrl" value="${connection.url}" />
        <property name="user" value="${connection.username}" />
        <property name="password" value="${connection.password}" />
        <property name="maximumConnectionCount" value="${proxool.maximum.connection.count}"/>
        <property name="minimumConnectionCount" value="${proxool.minimum.connection.count}" />
        <property name="statistics" value="${proxool.statistics}" />
        <property name="simultaneousBuildThrottle" value="${proxool.simultaneous.build.throttle}"/>
    </bean>

      <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" >
        <property name="dataSource" ref="dataSource"/>
        <property name="packagesToScan">
            <list>
                <value>com.cpic</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.query.substitutions">${hibernate.query.substitutions}</prop>
                <prop key="hibernate.default_batch_fetch_size">${hibernate.default_batch_fetch_size}</prop>
                <prop key="hibernate.max_fetch_depth">${hibernate.max_fetch_depth}</prop>
                <prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop>
                <prop key="hibernate.bytecode.use_reflection_optimizer">${hibernate.bytecode.use_reflection_optimizer}</prop>

                <prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
                <prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
                <prop key="hibernate.cache.region.factory_class">${hibernate.cache.region.factory_class}</prop>
                <prop key="net.sf.ehcache.configurationResourceName">${net.sf.ehcache.configurationResourceName}</prop>
                <prop key="hibernate.cache.use_structured_entries">${hibernate.cache.use_structured_entries}</prop>
                <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>

                <!--
                <prop key="hibernate.connection.datasource">${hibernate.connection.datasource}</prop>
                <prop key="hibernate.connection.provider_class">${hibernate.connection.provider_class}</prop>
                <prop key="hibernate.jndi.class">${hibernate.jndi.class}</prop>
                -->

            </props>
        </property>
      </bean>

    <!-- 开启AOP监听 只对当前配置文件有效 -->
    <aop:aspectj-autoproxy expose-proxy="true"/>

    <!-- 开启注解事务 只对当前配置文件有效 -->
      <tx:annotation-driven transaction-manager="txManager"/>

    <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="save*" propagation="REQUIRED" />
            <tx:method name="add*" propagation="REQUIRED" />
            <tx:method name="create*" propagation="REQUIRED" />
            <tx:method name="insert*" propagation="REQUIRED" />
            <tx:method name="update*" propagation="REQUIRED" />
            <tx:method name="merge*" propagation="REQUIRED" />
            <tx:method name="del*" propagation="REQUIRED" />
            <tx:method name="remove*" propagation="REQUIRED" />
            <tx:method name="put*" propagation="REQUIRED" />
            <tx:method name="use*" propagation="REQUIRED"/>
            <tx:method name="send*" propagation="REQUIRED" />
            <!--hibernate4必须配置为开启事务 否则 getCurrentSession()获取不到-->
            <tx:method name="get*" propagation="REQUIRED" read-only="true" />
            <tx:method name="count*" propagation="REQUIRED" read-only="true" />
            <tx:method name="find*" propagation="REQUIRED" read-only="true" />
            <tx:method name="list*" propagation="REQUIRED" read-only="true" />
            <tx:method name="*"  read-only="true" />
        </tx:attributes>
    </tx:advice>
    <aop:config expose-proxy="true">
        <!-- 只对业务逻辑层实施事务 -->
        <aop:pointcut id="txPointcut" expression="execution(* com.cpic..service.*.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
    </aop:config>

    <!-- spring启动时加载spring工具类  -->
    <bean id="springUtils" class="com.cpic.common.util.SpringContextUtil"></bean>

</beans>

部分业务 spring配置:

<bean id="textReceviService" class="com.cpic.basemsg.service.impl.TextReceviService"></bean>

    <bean id="eventReceviService" class="com.cpic.basemsg.service.impl.EventReceviService"></bean>

    <!-- 在线咨询 -->
    <bean id="onlineAskEventImpl" class="com.cpic.basemsg.service.event.impl.OnlineAskEventImpl"></bean>
    <!-- 卡单激活 -->
    <bean id="activeCareEventImpl" class="com.cpic.basemsg.service.event.impl.ActiveCareEventImpl"></bean>
    <!-- 客户回访 -->
    <bean id="custReVisEventImpl" class="com.cpic.basemsg.service.event.impl.CustReVisEventImpl"></bean>
    <!-- 道路救援 -->
    <bean id="roadHelpEventImpl" class="com.cpic.basemsg.service.event.impl.RoadHelpEventImpl"></bean>
    <!-- 自助报案 -->
    <bean id="selfPoliceEventImpl" class="com.cpic.basemsg.service.event.impl.SelfPoliceEventImpl"></bean>

    <bean id="wechatMng" class="com.cpic.basemsg.service.WeChatMng">
        <property name="map">
            <map>
                <entry key="text">
                    <ref local="textReceviService"/>
                </entry>
                <entry key="event">
                    <ref local="eventReceviService"/>
                </entry>
            </map>
        </property>

        <property name="baseMap">
            <map>
                <entry key="btn13">
                    <ref local="onlineAskEventImpl"/>
                </entry>
                <entry key="btn21">
                    <ref local="roadHelpEventImpl"/>
                </entry>
                <entry key="btn22">
                    <ref local="selfPoliceEventImpl"/>
                </entry>
                <entry key="btn23">
                    <ref local="custReVisEventImpl"/>
                </entry>
                <entry key="btn24">
                    <ref local="activeCareEventImpl"/>
                </entry>
            </map>
        </property>
    </bean>

业务解耦类

package com.cpic.basemsg.service;

import java.util.Map;

/**
 * 设计这个类,主要是为了解耦,可实现对逻辑层的配置,将业务更细化
 * 将一些共同特性统一处理
 * @author wuxw
 *
 */
public class WeChatMng {

    static Logger logger = Logger.getLogger(WeChatMng.class);

    @SuppressWarnings("unchecked")
    public WeChatService weChatService;

    @SuppressWarnings("unchecked")
    private Map<String,WeChatService> map;

    private Map<String,BaseEventService> baseMap;

    /** 点击事件*/
    public BaseEventService baseEventService;

    public void setMap(Map<String, WeChatService> map) {
        this.map = map;
    }

    public void setBaseMap(Map<String, BaseEventService> baseMap) {
        this.baseMap = baseMap;
    }

    /**
     * 对不同消息类型的控制转发
     * @param msgType
     * @param wxMsgXml
     * @return
     */
    public String process(String msgType,String wxMsgXml) throws BaseMsgException{
        if(msgType == null || msgType == ""){
            logger.error("请求消息:" + msgType);
            throw new BaseMsgException("请求消息为空!");
        }
        weChatService = map.get(msgType);
        if(null == weChatService){
            throw new BaseMsgException("不支持的接口类型:" + msgType);
        }
        return weChatService.process(wxMsgXml);
    }

    /**
     * 对不同事件的控制转发
     * @parama clickKey  按钮编号
     * @return
     * @throws BaseMsgException 业务异常
     */
    public String processEvent(String click,EventMsgModel model) throws BaseMsgException{
        if(click == null){
            throw new BaseMsgException("不存在的点击事件:" + click);
        }
        if(model == null){
            throw new BaseMsgException("传入的事件消息为null!" );
        }
        baseEventService = baseMap.get(click);
        if(baseEventService == null){
            throw new BaseMsgException("暂时不支持的点击参数:" + click);
        }
        return baseEventService.process(model);
    }

}

部分类的核心设计

/**
 * 抽象出功能模块
 * 信息的处理流程分三步依次进行:
 *         1. 接收信息
 *         2. 处理信息
 *         3. 返回信息
 * 并且这个顺序不能变,强制使用处理信息的流程
 * 我们只需要关心业务处理的方式
 * @author wuxw
 *
 */
public abstract class WeChatServiceAbs<T extends BaseMsgModel> extends CommonHibernateDao implements WeChatService<BaseMsgModel> {

    /**
     * 处理消息,用模版的形式对各模块独立
     * @param xmlMsg    传入消息
     * @return            返回处理后的消息
     * @throws WeChatException
     */
    public String process(String xmlMsg) throws BaseMsgException{
        MsgModel msg = reviceMsg(xmlMsg);
        return processMsg(msg).toString();
    }
}

java微信平台,发源码的更多相关文章

  1. 沐雪多用户微信公众平台开发源码,商城小程序源码(2018年最新的asp.net C# 微信源码,小程序源码)

    现售价5400元,就可以搭建自己的微信平台啦 购买地址:https://item.taobao.com/item.htm?id=539102325336 该系统是由[上海沐雪网络]独家授权销售,其他地 ...

  2. Java微信公众平台开发_07_JSSDK图片上传

    一.本节要点 1.获取jsapi_ticket //2.获取getJsapiTicket的接口地址,有效期为7200秒 private static final String GET_JSAPITIC ...

  3. JAVA微信扫码支付模式二功能实现完整例子

    概述 本例子实现微信扫码支付模式二的支付功能,应用场景是,web网站微信扫码支付.实现从点击付费按钮.到弹出二维码.到用户用手机微信扫码支付.到手机上用户付费成功.web网页再自动调整到支付成功后的页 ...

  4. Java微信公众平台开发--番外篇,对GlobalConstants文件的补充

    转自:http://www.cuiyongzhi.com/post/63.html 之前发过一个[微信开发]系列性的文章,也引来了不少朋友观看和点评交流,可能我在写文章时有所疏忽,对部分文件给出的不是 ...

  5. Java微信公众平台开发_03_消息管理之被动回复消息

    GitHub源码:https://github.com/shirayner/weixin_gz 一.本节要点 1.回调url 上一节,我们启用服务器配置的时候,填写了一个服务器地址(url),如下图, ...

  6. java微信扫码支付Native(模式二)

    官方开发文档模式二的地址:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_5 pom文件的依赖: <?xml versio ...

  7. Java之微信支付(扫码支付模式二)案例实战

    摘要:最近的一个项目中涉及到了支付业务,其中用到了微信支付和支付宝支付,在做的过程中也遇到些问题,所以现在总结梳理一下,分享给有需要的人,也为自己以后回顾留个思路. 一:微信支付接入准备工作: 首先, ...

  8. Java中的微信支付(2):API V3 微信平台证书的获取与刷新

    1. 前言 在Java中的微信支付(1):API V3版本签名详解一文中胖哥讲解了微信支付V3版本API的签名,当我方(你自己的服务器)请求微信支付服务器时需要根据我方的API证书对参数进行加签,微信 ...

  9. java 微信公众服务平台 下发 模板消息

    java 微信公众服务平台 下发 模板消息 (一).部分截图 (二).部分代码 (一).部分截图: (二).部分代码: //此处 给用户微信发消息... Map<String,String> ...

随机推荐

  1. angularJS之站在jQuery的肩膀上

    jQuery:用更少的代码,实现更强悍的功能 托互联网日新月异发展的福,浏览器变成了人们接入互联网的入口,而JavaScript 这个曾经的小语种,终于成功地站到了舞台的中央,唤起了开发者的兴趣. 浏 ...

  2. javascritpt 原型链

    // 基类 var BaseCalculator = function(){ this.decimalDigits = 2; }; // public BaseCalculator.prototype ...

  3. Linux中iptables设置详细

    无论如何,iptables是一个需要特别谨慎设置的东西,万一服务器不在你身边,而你贸然设置导致无法SSH,那就等着被老板骂吧,呵呵... 一下内容是为了防止这种情况发生而写的,当然很初级,不过一般服务 ...

  4. bzoj 1799: [Ahoi2009]self 类似的分布 解读

    [原标题] 1799: [Ahoi2009]self 同类分布 Time Limit: 50 Sec  Memory Limit: 64 MB Submit: 554  Solved: 194 [id ...

  5. JavaScript中对数组的操作

    原文:JavaScript中对数组的操作 一:数组的使用 1.定义:JavaScript中对数组的定义有两种形式.如: .var arr = [12,3,5,8]; .var arr = new Ar ...

  6. Sql Server 主键由字母数字组成并按照数字自动增长

    在SQL SERVER 中如果我们想要使主键按照一定规则自动增长我们可以这样做: 这里我们新建一张研究表,里面有研究ID,研究人员姓名和研究医院. 我们使SicentificId 设为主键 并且从1开 ...

  7. 程序猿必要10免费的钱jquery小工具

    本周带来10款免费的jquery插件.假设你也有好的作品,欢迎分享到社区中来,在得到帮助的同一时候,也能与很多其它人分享来自你的作品. jQuery导航菜单置顶插件 - stickyUp . 在线演示 ...

  8. 2014年3I工作室成员的正式名单

    后3I认真审议和审查工作室的老师及相关人员,今天,新成员首次正式发布,如以下:博才文(11软件).黄彩云(11软件).朱小丹(11软件).海(11软件).欧剑灵(11此计).黄思源(12软件).黄龙营 ...

  9. Oracle中join left,join right,inner join,(+) 等

    Oracle中join left,join right,inner join,(+) 等 博客分类: Oracle   建表create table TEST1create table TEST1(  ...

  10. QTP知识总结(一)

    QTP知识总结(一) (2010-12-22 16:30:41) 转载▼ 标签: 杂谈 分类: QTP File menu Process guidance management,View > ...