去年搞完了oa系统,今年一开始公司就准备做大数据,公司原来数据已经有些是上亿的了,如果还是用关系型数据库又不分区分表的话,即使用了读写分离也很难保证性能了。
于是得搞个基础数据存储,这样过了一段时间后业务系统的数据就可以清掉了,基础系统里保留所有历史数据,以后要做统计啥的就从这边拿。
想法分三部分,第一是原始数据,此数据不经过任何逻辑,全部入库。第二是清洗数据,经过一定的逻辑筛选出有用数据保存起来。第三是应用数据,根据业务需要生成应用数据,提供接口给业务系统调用。
前期先搭框架,以前公司系统就是用springmvc+mybatis的框架,所以这次直接就在原有框架上剥离基本的框架再来集成,第一部分的数据库最后确认是用mongodb,这部分数据特别大,如果用关系型数据库的话不好搞,性能也太差。
本来接口是想用rmi实现的,不过公司有国内(java),国际(.net)不同语言,还是用webservice好点,免得国际的以后不好调。
所以最后确定系统框架需要用到的技术就是srpingmvc+mybatis+mongodb+cxf。
srpingmvc+mybatis这里就不介绍了,主要讲mongodb。
本来想用spring 自己的mongodb封装的,发现配起来跟公司原来spring版本不一样,上头又催得紧。
那就只能自己封装一层mongodb的dao层了,最终目的就是要封装成像使用hiberante一样。
主要难点在于如何根据类映射成表,这个当时还搞了蛮久的,以前还用了个baseService去调dao,然后其它service去调baseService,发现根据没办法在dao里取得传进去的泛型T的类型,这要就没办法取得类名也就没办法映射表了。最后去掉了baseService层,直接service就继承dao的实现类。然后把dao的实现类定义成抽象类abstract,一定要定义成abstract,不然无法获取泛型T的类型。
package base.dao.mongo; import java.net.UnknownHostException; import com.mongodb.MongoClient; import com.mongodb.MongoException; import com.mongodb.MongoOptions; public class MongoManager extends MongoClient{ /* private String host ="127.0.0.1"; private int port =27017;*/ /*private String host ="172.16.6.40";*/ private String host ="172.16.6.16"; private int port =9901; private int poolSize = 100; private int blockSize = 40; private MongoClient mongoClient; private MongoManager() throws UnknownHostException{ super(); } public String getHost() { return host; } public void setHost(String host) { this.host = host; } public int getPort() { return port; } public void setPort(int port) { this.port = port; } public int getPoolSize() { return poolSize; } public void setPoolSize(int poolSize) { this.poolSize = poolSize; } public int getBlockSize() { return blockSize; } public void setBlockSize(int blockSize) { this.blockSize = blockSize; } public MongoClient getMongoClient() { try { mongoClient = new MongoClient(host, port); MongoOptions opt = mongoClient.getMongoOptions(); opt.connectionsPerHost = poolSize; opt.threadsAllowedToBlockForConnectionMultiplier = blockSize; //opt.autoConnectRetry = true; }/* catch (UnknownHostException e) { throw new RuntimeException(e); } */catch (MongoException e) { throw new RuntimeException(e); } return mongoClient; } }
dao接口类
package base.dao.mongo; import java.util.List; import java.util.Map; import org.bson.types.ObjectId; import org.springframework.dao.DataAccessException; import base.vo.DivPageVO; import com.mongodb.BasicDBObject; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBObject; import com.mongodb.WriteResult; /** * 基础数据库操作类 * * 其他DAO继承此类获取常用的数据库操作方法,基本上你能用到的方法这里都有了,不需要自己建立DAO了。 * * @author miraclerz * * @param <T> * 模型 */ public interface MongoBaseDaoI<T> { /** * 得到数据库 */ public DB getDB(String dbName); /** * 得到表 */ public DBCollection getCollection(String dbName, String collName); /** * 转为mongo类型数据 classType实体类类型 */ public DBObject toDBObject(T vo); /** * 转为实体数据 * * @throws IllegalAccessException * @throws InstantiationException */ public T toModel(DBObject dbObject) throws InstantiationException, IllegalAccessException; /** * 查询所有分页 * @param page * @return * @throws DataAccessException * @throws InstantiationException * @throws IllegalAccessException */ public List<T> findAll( DivPageVO page) throws DataAccessException, InstantiationException, IllegalAccessException; /** * 查询所有 * @return * @throws DataAccessException * @throws InstantiationException * @throws IllegalAccessException */ public List<T> findAll() throws DataAccessException, InstantiationException, IllegalAccessException; /** * 批量删除 * @param list * @throws DataAccessException */ public WriteResult deleteList(List<ObjectId> list) throws DataAccessException; /** * 单条删除 * * @param objectId * @throws DataAccessException */ public WriteResult deleteOne(ObjectId objectId) throws DataAccessException; /** * 单条插入 * * @param T * @throws DataAccessException */ public WriteResult insertOne(T t) throws DataAccessException; /** * 批量插入 * * @param list * @throws DataAccessException */ public WriteResult insertList(List<T> list) throws DataAccessException; /** * 清空本表数据 小心了 * * @throws DataAccessException */ public WriteResult clear() throws DataAccessException; /** * 查询一条数据 转为实体 * * @param objectId * @return */ public T findOne(ObjectId objectId) throws InstantiationException, IllegalAccessException; /** * 查询一条数据 * * @param objectId * @return */ public DBObject findOneByDbObject(ObjectId objectId); public DBCollection getTable(); /** * 查询数量 * @return * @throws DataAccessException * @throws InstantiationException * @throws IllegalAccessException */ public int countAll() throws DataAccessException, InstantiationException, IllegalAccessException; /** * 不分页查询 * @param param * @param map * @param field * @param asc * @return * @throws InstantiationException * @throws IllegalAccessException */ public List<T> find(T param,Map<String, BasicDBObject> map,String field,boolean asc) throws InstantiationException, IllegalAccessException; /** * 分页查询 * @param param * @param map * @param page * @param field * @param asc * @return * @throws InstantiationException * @throws IllegalAccessException */ public List<T> find(T param,Map<String, BasicDBObject> map, DivPageVO page,String field,boolean asc) throws InstantiationException, IllegalAccessException; /** * 根据条件计数 * @param param * @param map * @return */ public int count(T param,Map<String, BasicDBObject> map); /** * 查询条件组合,默认有实现,也可以在自己的具体类里重写自己的实现 * @param param * @param map * @return */ public abstract DBObject getCondition(T param,Map<String, BasicDBObject> map); /** * 创建索引 * @param dbObject */ public void createIndex(BasicDBObject dbObject); }
实现类
package base.dao.mongo.impl; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import org.bson.types.ObjectId; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.dao.DataAccessException; import org.springframework.stereotype.Repository; import base.dao.mongo.MongoBaseDaoI; import base.vo.DivPageVO; import com.mongodb.BasicDBList; import com.mongodb.BasicDBObject; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBObject; import com.mongodb.MongoClient; import com.mongodb.WriteResult; @Repository public abstract class MongoBaseDaoImpl<T> implements MongoBaseDaoI<T> { private ConcurrentMap<String, Method> READ_METHODS = new ConcurrentHashMap<String, Method>(); private ConcurrentMap<String, Method> WRITE_METHODS = new ConcurrentHashMap<String, Method>(); private String GET_PREFIX = "get"; private String SET_PREFIX = "set"; private String IS_PREFIX = "is"; @Autowired @Qualifier("mongoClient") private MongoClient mongoClient; final String dbName = "baseData"; private Class<T> classType; public MongoBaseDaoImpl(){ //利用反射 得到T的具体子类的类型,从而实现类到表的自动映射,这里MongoBaseDaoImpl一定要是abstract类,不然下面是获取不到类型的(搞了几天、、、) Type genType = this.getClass().getGenericSuperclass(); Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); classType = (Class<T>) params[0]; GetMethods();//初始化泛形类的get set 属性方法 } /** * 得到所有方法 * * @param vo */ public void GetMethods() { if (READ_METHODS.size() > 0) return;// 如果已经有数据就直接返回了 Method[] methods = classType.getDeclaredMethods(); for (Method method : methods) { String name = method.getName(); method.setAccessible(true); if (name.startsWith(SET_PREFIX)) { WRITE_METHODS.putIfAbsent(uncapitalize(SET_PREFIX, name), method); } else if (name.startsWith(IS_PREFIX)) { READ_METHODS.putIfAbsent(uncapitalize(IS_PREFIX, name), method); } else if (name.startsWith(GET_PREFIX)) { READ_METHODS .putIfAbsent(uncapitalize(GET_PREFIX, name), method); } } } /** * 得到数据库 */ public DB getDB(String dbName) { DB db = mongoClient.getDB(dbName); return db; } /** * 得到表 */ public DBCollection getCollection(String dbName, String collName) { return getDB(dbName).getCollection(collName); } public static String uncapitalize(String prefix, String str) { String _str = str.substring(prefix.length()); return Character.toLowerCase(_str.charAt(0)) + _str.substring(1); } /** * 转为mongo类型数据 */ public DBObject toDBObject(T vo) { //GetMethods(); DBObject dbObject = new BasicDBObject(); for (Entry<String, Method> entry : READ_METHODS.entrySet()) { try { dbObject.put(entry.getKey(), entry.getValue().invoke(vo)); } catch (Exception e) { e.printStackTrace(); } } return dbObject; } /** * 转为实体数据 * * @throws IllegalAccessException * @throws InstantiationException */ public T toModel(DBObject dbObject) throws InstantiationException, IllegalAccessException { T t = (T) classType.newInstance(); //GetMethods(); for (Entry<String, Method> entry : WRITE_METHODS.entrySet()) { try { entry.getValue().invoke(t, dbObject.get(entry.getKey())); } catch (Exception e) { e.printStackTrace(); } } return t; } public MongoClient getMongoClient() { return mongoClient; } public void setMongoClient(MongoClient mongoClient) { this.mongoClient = mongoClient; } /** * 查询一条数据 * * @param objectId * @return */ public DBObject findOneByDbObject(ObjectId objectId) { DBObject objVO = new BasicDBObject(); objVO.put("_id", objectId); return getTable().findOne(objVO);// } /** * 查询一条数据 转为实体 * * @param objectId * @return */ public T findOne(ObjectId objectId) throws InstantiationException, IllegalAccessException { DBObject dBObject = findOneByDbObject(objectId); T t = null; if (dBObject != null) { t = toModel(dBObject); } return t; } /** * 清空数据 小心了 * * @throws DataAccessException */ public WriteResult clear() throws DataAccessException { return getTable().remove(new BasicDBObject()); } /** * 批量插入 * * @param list * @throws DataAccessException */ public WriteResult insertList(List<T> list) throws DataAccessException { if (list != null&&list.size()>0) { List<DBObject> listInsert = new ArrayList<>(); for (T t : list) { listInsert.add(toDBObject(t)); } return insertByDbObject(listInsert); } return null; } public WriteResult insertByDbObject(List<DBObject> list) throws DataAccessException { return getTable().insert(list); } /** * 单条插入 * * @param T * @throws DataAccessException */ public WriteResult insertOne(T t) throws DataAccessException { if (t != null) { return getTable().insert(toDBObject(t)); } return null; } /** * 单条删除 * * @param list * @throws DataAccessException */ public WriteResult deleteOne(ObjectId objectId) throws DataAccessException { DBObject objVO = new BasicDBObject(); objVO.put("_id", objectId); return getTable().remove(objVO); } /** * 批量 * @param list * @throws DataAccessException */ public WriteResult deleteList(List<ObjectId> list) throws DataAccessException { DBObject obj = new BasicDBObject(); BasicDBList values = new BasicDBList(); for(int i=0;i<list.size();i++) { values.add(new BasicDBObject("_id",list.get(i))); } obj.put("$or", values); return getTable().remove(obj); } /** * 查询所有分页 * @param page * @return * @throws DataAccessException * @throws InstantiationException * @throws IllegalAccessException */ public List<T> findAll( DivPageVO page) throws DataAccessException, InstantiationException, IllegalAccessException{ DBObject obj = new BasicDBObject(); int pos = page.getStartPos(); int pageSize = page.getPageSize(); Iterator<DBObject> dbList= getTable().find(obj).skip(pos).limit(pageSize); List<T> list = new ArrayList<T>(); for (Iterator iter = dbList; iter.hasNext();) { DBObject dbo = (DBObject) iter.next(); T vo = toModel(dbo); list.add(vo); } return list; } public List<T> findAll() throws DataAccessException, InstantiationException, IllegalAccessException { Iterator<DBObject> dbList= getTable().find( new BasicDBObject()); List<T> list = new ArrayList<T>(); for (Iterator iter = dbList; iter.hasNext();) { DBObject dbo = (DBObject) iter.next(); T vo = toModel(dbo); list.add(vo); } return list; } public DBCollection getTable(){ return getDB(dbName).getCollection(classType.getName().split("\\.")[classType.getName().split("\\.").length-1].toLowerCase()); } public int countAll() throws DataAccessException, InstantiationException, IllegalAccessException { return getTable().find().count(); } public List<T> find(T param,Map<String, BasicDBObject> map,String field,boolean asc) throws InstantiationException, IllegalAccessException { Iterator<DBObject> dbList=null; if(field!=null) {//排序 int sort=-1; if(asc)sort=1; dbList= getTable().find(getCondition( param, map)).sort(new BasicDBObject(field,sort)); }else{//不排序 dbList=getTable().find(getCondition( param, map)); } List<T> list = new ArrayList<T>(); for (Iterator iter = dbList; iter.hasNext();) { DBObject dbo = (DBObject) iter.next(); T vo = toModel(dbo); list.add(vo); } return list; } public List<T> find(T param,Map<String, BasicDBObject> map, DivPageVO page,String field,boolean asc) throws InstantiationException, IllegalAccessException { int pos = page.getStartPos(); int pageSize = page.getPageSize(); Iterator<DBObject> dbList=null; if(field!=null) {//排序 int sort=-1; if(asc)sort=1; dbList=getTable().find(getCondition( param, map)).sort(new BasicDBObject(field,sort)).skip(pos).limit(pageSize); }else{//不排序 dbList=getTable().find(getCondition( param, map)); } List<T> list = new ArrayList<T>(); for (Iterator iter = dbList; iter.hasNext();) { DBObject dbo = (DBObject) iter.next(); T vo = toModel(dbo); list.add(vo); } return list; } public int count(T param,Map<String, BasicDBObject> map) { return getTable().find(getCondition( param, map)).count(); } public DBObject getCondition(T param,Map<String, BasicDBObject> map){ DBObject obj = new BasicDBObject(); for (Entry<String, Method> entry : READ_METHODS.entrySet()) { try {//利用反射,这里所有的条件都是等于的,如果有其它条件如大于小于的条件就放到下面的map里,或者在子类实现里重写这个方法 if(entry.getValue().invoke(param)!=null) { obj.put(entry.getKey(), entry.getValue().invoke(param)); } } catch (Exception e) { e.printStackTrace(); } } if(map!=null) { for (Map.Entry<String, BasicDBObject> entry : map.entrySet()) { //entry.getKey() 如是 starttime 则starttime是字段 格式如下 //Map<String, BasicDBObject> map=new HashMap<String, BasicDBObject>(); //map.put("updatetime", new BasicDBObject("$gte","2015-01-29 10:20:00")); //map.put("updatetime", new BasicDBObject("$gte","2015-10-29 10:20:00").append("$lte","2015-11-29 15:21:00")); obj.put(entry.getKey(), entry.getValue()); } } return obj; } public void createIndex(BasicDBObject dbObject){ getTable().createIndex(dbObject); } }
mongo的配置文件
<?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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <!--本机 --> <bean id="mongoManage" class="base.dao.mongo.MongoManager"> <property name="host" value="127.0.0.1" /> <property name="port" value="27017" /> <property name="poolSize" value="100" /> <property name="blockSize" value="40" /> </bean> <bean id="mongoClient" factory-bean="mongoManage" factory-method="getMongoClient" /> </beans>
这样在service层就每次基本上都是直接调方法,以类的形式来调用mongo了。
接口采用apache 的cxf
接口验证类
package base.service.cxf; public class BaseAuthorization { private String userName; private String password; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
公共返回类
package base.service.cxf; import java.io.Serializable; import java.util.List; /** * 接口调用返回统一结果 * @author miraclerz * */ public class RespResult<T> implements Serializable { /** * */ private static final long serialVersionUID = 1L; private String flag="F";//正常 "T" 不正常 "F" private String msg; private List<T> data;//返回的数据 public String getFlag() { return flag; } public void setFlag(String flag) { this.flag = flag; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public List<T> getData() { return data; } public void setData(List<T> data) { this.data = data; } }
接口类
package base.service.cxf.gn.ttlog.logorder; import javax.jws.WebService; import base.model.gn.dtom.GnLogOrder; import base.service.cxf.BaseAuthorization; import base.service.cxf.RespResult; /** * * @author miraclerz * */ @WebService public interface WsGnLogOrderServiceI { /** * 得到最大或最小值 * * @param field 以哪个字段排序 * @param asc true表示升序,查出最小值;false或null表示降序,查出最大值 * @return */ public RespResult<GnLogOrder> getLimit(BaseAuthorization authorization,String field,boolean asc); /** * 根据订单id取得日志 * * @param field 以哪个字段排序 * @param asc true表示升序,查出最小值;false或null表示降序,查出最大值 * @return */ public RespResult<GnLogOrder> getLogByOrderId(BaseAuthorization authorization,Integer orderid); /** * 批量插入 如果开放给外面插入就把下面的注释去掉 * @param list * @return */ /* public RespResult<GnLogOrder> insertList(BaseAuthorization authorization,List<GnLogOrder> list);*/ }
实现类
package base.service.cxf.gn.ttlog.logorder.impl; import java.util.List; import javax.jws.WebService; import org.springframework.beans.factory.annotation.Autowired; import base.model.gn.dtom.GnLogOrder; import base.service.cxf.BaseAuthorization; import base.service.cxf.RespResult; import base.service.cxf.gn.ttlog.logorder.WsGnLogOrderServiceI; import base.service.mongo.gn.dtom.MongoGnLogOrderServiceI; import base.vo.DivPageVO; import com.mongodb.WriteResult; /** * * @author miraclerz * */ @WebService(endpointInterface = "base.service.cxf.gn.ttlog.logorder.WsGnLogOrderServiceI", serviceName = "wsGnLogOrderService") public class WsGnLogOrderServiceImpl implements WsGnLogOrderServiceI { @Autowired private MongoGnLogOrderServiceI mongoGnLogOrderServiceI; @Override public RespResult<GnLogOrder> getLimit(BaseAuthorization authorization,String field, boolean asc) { RespResult<GnLogOrder> respResult =new RespResult<GnLogOrder>(); DivPageVO page =new DivPageVO(); page.setStartPos(0); page.setPageSize(1); try { List<GnLogOrder> list=mongoGnLogOrderServiceI.find(new GnLogOrder(), null, page, field, asc); if(list!=null&&list.size()>0) { respResult.setData(list); } respResult.setFlag("T"); respResult.setMsg("正常"); } catch (InstantiationException e) { respResult.setFlag("F"); respResult.setMsg("接口异常"); e.printStackTrace(); } catch (IllegalAccessException e) { respResult.setFlag("F"); respResult.setMsg("接口异常"); e.printStackTrace(); } return respResult; } //@Override public RespResult<GnLogOrder> insertList(BaseAuthorization authorization,List<GnLogOrder> list) { RespResult<GnLogOrder> respResult =new RespResult<GnLogOrder>(); WriteResult writeResult=mongoGnLogOrderServiceI.insertList(list); if(writeResult!=null) { respResult.setFlag("T"); respResult.setMsg("插入成功"); } return respResult; } @Override public RespResult<GnLogOrder> getLogByOrderId(BaseAuthorization authorization, Integer orderid) { RespResult<GnLogOrder> respResult =new RespResult<GnLogOrder>(); if(orderid==null) { respResult.setFlag("F"); respResult.setMsg("订单ID不能为空!"); return respResult; } GnLogOrder param=new GnLogOrder(); param.setOrderid(orderid); try { List<GnLogOrder> list=mongoGnLogOrderServiceI.find(param, null, "id", true); respResult.setData(list); respResult.setFlag("T"); respResult.setMsg("正常"); } catch (Exception e) { respResult.setFlag("F"); respResult.setMsg("接口异常"); e.printStackTrace(); } return respResult; } }
cxf配置文件
<?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:c="http://www.springframework.org/schema/c" xmlns:cache="http://www.springframework.org/schema/cache" xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:lang="http://www.springframework.org/schema/lang" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xmlns:task="http://www.springframework.org/schema/task" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xmlns:jaxws="http://cxf.apache.org/jaxws" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd "> <import resource="classpath*:META-INF/cxf/cxf.xml" /> <import resource="classpath*:META-INF/cxf/cxf-extension-soap.xml" /> <import resource="classpath*:META-INF/cxf/cxf-servlet.xml" /> <!-- 对外提供的WebService接口访问地址 --> <!-- jaxws:endpoint可以有多个,自己配置;implementor指定到你的实现类,address是webservice相对于你项目的访问路径 --> <!-- 下面这个示例服务访问地址就是http://localhost:9999/base/ws/webServiceDemo?wsdl,为什么前面要加一个ws,请看web.xml里面的cxfService配置 --> <!-- webService一定要有接口和实现类,否则会出错 --> <jaxws:endpoint implementor="base.service.cxf.gn.ttlog.logorder.impl.WsGnLogOrderServiceImpl" address="/wsGnLogOrderService" /> </beans>
cxf接口类里会调用service层,service层有mysql和mongo等业务数据调用各自数据库的实现。
用spring 的aop实现用户验证
package base.aop; import java.lang.reflect.Method; import org.apache.cxf.interceptor.Fault; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.aop.AfterReturningAdvice; import org.springframework.aop.MethodBeforeAdvice; import org.springframework.aop.ThrowsAdvice; import base.exception.ServiceException; import base.service.cxf.BaseAuthorization; /** * AOP切面类 * @author miraclerz */ public class AuthAdvice implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice { public static final Logger logger = LoggerFactory.getLogger(AuthAdvice.class); // service方法执行之前被调用 public void before(Method method, Object[] args, Object target) throws Throwable { // System.out.println("切入点: " + target.getClass().getName() + "类中" + method.getName() + "方法"); boolean isAuth=false; for (Object object : args) { if(object!=null&&"baseauthorization".equals(object.getClass().getName().split("\\.")[object.getClass().getName().split("\\.").length-1].toLowerCase())){ //如果有带验证参数 BaseAuthorization auth=(BaseAuthorization) object; if("admin".equals(auth.getUserName())&&"123456".equals(auth.getPassword())) { isAuth=true; } } } if(!isAuth) { Fault fault=new Fault(new ServiceException("用户名或密码错误")); //fault.setStatusCode(403); // throw fault; } } // service方法执行完之后被调用 public void afterReturning(Object arg0, Method method, Object[] args, Object target) throws Throwable { } // 抛出Exception之后被调用 public void afterThrowing(Method method, Object[] args, Object target, Exception ex) throws Throwable { } }
aop配置
<!-- 用户权限 --> <bean id="authAdvice" class="base.aop.AuthAdvice" /> <aop:config> <aop:advisor pointcut="(execution(* base.service.cxf..*Impl.*(..)))" advice-ref="authAdvice" /> </aop:config>
今天的记录就到这!