精华内容
参与话题
问答
  • 《期货交易记录资金管理风险控制系统》也叫爆仓价计算器。 本软件是进行期货保证金类投资的工具,网络上所有的期货软件没有和这款软件雷同的功能, 市面上期货类软件大多是行情或预测行情走势的,本软件从记录交易...
  • 主要介绍了python交易记录整合交易类详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • 期货交易记录表.xlsx

    2020-03-06 18:42:51
    良好的交易记录习惯是成功的基础。期货交易记录表是记录决策过程和交易结果的必要表格,通过分析总结不断提高交易水平和交易自律性。
  • 《期货交易记录资金管理风险控制系统》也叫爆仓价计算器。 本软件是进行期货保证金类投资的工具,市面上期货类软件大多是行情或预测行情走势的,本软件独辟蹊径从记录交易信息开始,根据资金变化测算账户风险程度,...
  • 自动导微信交易记录

    2018-02-24 02:36:19
    自动导出微信交易记录到表格,方便对账和查账! 信息非常全,包你满意!不会用的加群或者单独加我。 需要的可以进行下载,遇到问题可以联系我。 软件包内包含使用教程。 软件运行要求:电脑 + 网络 + office或wps ...
  • 主要介绍了python交易记录链的实现过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • 主要为大家详细介绍了Python如何抓取天猫商品详细信息及交易记录,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
  • 微信助手(自动导微信交易记录)是一款也已帮助微信用户自动导出微信交易记录到表格的辅助工具,方便对账和查账,该软件功能出色,方便易用,需要的朋友欢迎前来下载体验! 使用教程 一、下载软件 下载最新压缩包,...
  • 如何分析交易记录

    2020-09-17 21:00:00
    【题目】某商场为了分析用户购买渠道。表1是用户交易记录表,记录了用户id、交易日期、交易类型和交易金额。表2是用户类型表,记录了用户支付类型(微信、支付宝、信用卡等),分别有type1、...

    【题目】

    某商场为了分析用户购买渠道。表1是用户交易记录表,记录了用户id、交易日期、交易类型和交易金额。

    表2是用户类型表,记录了用户支付类型(微信、支付宝、信用卡等),分别有type1、type2。

    要求:

    1.请在 type1的用户类型中,找出总交易金额最大的用户。

    2.筛选每个用户的第2笔交易记录。

    3.如下表:如何实现表3的数据格式?

    4.两表做关联时,其中一张表的关联键有大量的null值会造成什么影响?如何规避?

    【解题思路】

    1.type1的用户类型中,找出单用户的总交易金额最大的一位用户?

    我们先来把这个业务需求翻译成大白话:

    1)表中的字段要有用户类型、交易金额、用户id

    2)“单用户的总交易金额”是指每种类型用户的总交易金额

    3)找出用户类型=type1,总交易金额最大的用户

    1)表中的字段要有用户类型、交易金额、用户id

    交易金额、用户id在用户交易记录表中,用户类型在用户类型表中,涉及到两个表的字段,所以需要进行多表联结。

    观察两个表,得知两表的相同字段为用户id ,所以通过用户id联结两张表。

    使用哪种联结呢?拿出《猴子 从零学会SQL》里面的多表联结图。

    因为后面要分析“每种类型用户的总交易金额”,所以保留左表(用户交易记录表)中的全部用户数据。

    select 用户交易记录表.* ,用户类型表.用户类型
    from 用户交易记录表
    left join 用户类型表
    on 用户交易记录表.用户id=用户类型表.用户id;
    

    查询结果:

    2)每种类型用户的总交易金额

    当有“每个”出现的时候,要想到《猴子 从零学会SQL》中讲过的用分组汇总来实现该业务问题。

    根据各用户类型、用户id分组 (group by),统计每个用户数总费用(求和函数sum)

    select 用户交易记录表.*,用户类型表.用户类型,
           sum(用户交易记录表.交易金额) as 总金额
    from 用户交易记录表
    left join 用户类型表
    on 用户交易记录表.用户id=用户类型表.用户id
    group by 用户类型表.用户类型,用户交易记录表.用户id;
    

    查询结果:

    3)找出用户类型=type1,总交易金额最大的用户

    用where 筛选用户类型=type1的用户,按照总金额降序排序(order by decs),找出的第一行(limit 1)记录即为交易金额最大的用户。

    select 用户类型表.用户类型,  用户交易记录表.用户id,
           sum(用户交易记录表.交易金额) as 总金额
    from 用户交易记录表
    left join 用户类型表
    on  用户交易记录表.用户id  = 用户类型表.用户id
    where 用户类型表.用户类型  =  'type1'
    group by 用户类型表.用户类型,  用户交易记录表.用户id
    order by 总金额 desc  limit 1;
    

    查询结果:

    2.筛选每个用户的第2笔交易记录?

    1)题目要求查询“每个用户”,当每个出现的时候,就要想到分组汇总(group by或者窗口函数的partiotion  by)。

    2)第2笔交易记录,是指按照交易时间对每个用户的交易记录进行排名,然后取出排名第2的数据。

    又涉及到分组,又涉及到排名的问题,要想到用《猴子 从零学会SQL》里讲过的窗口函数来实现。

    所以使用分组(窗口函数partiotion by 用户id),并按最后交易时间升序排列(order by交易时间 asc),套入窗口函数的语法,得出下面的sql语句:

    select 用户交易记录表.*,
            row_number() over(partition by 用户交易记录表.用户id 
                              order by 用户交易记录表.交易日期 asc) as 交易笔数
    from 用户交易记录表;
    


    查询结果:

    2)用where 筛选出每个用户的第2条记录,就是每个用户的第2笔交易记录

     

    select * from
    (select 用户交易记录表.*,
    row_number() over(
                     partition by 用户交易记录表.用户id 
                     order  by 用户交易记录表.交易日期 asc ) as 交易笔数
    from 用户交易记录表) as a
    where 交易笔数=2;
    

    查询结果:

    3.如下表:如何实现表3的数据格式?

    题目要求将同一用户、不用的交易时间和交易类型多行合并为一行,用group_concat函数可解决。

    sql入下:

    select 用户id,
    group_concat(交易日期), group_concat(交易类型) 
    from 用户交易记录表
    group by 用户id;
    

    4.两表做关联时,其中一张表的关联键有大量的null值会造成什么影响?如何规避?

    因为在关联表中的全部数据不一定在另一张表都匹配,这样没有匹配到的话就会出现null,避免出现表连接出现null值,只要在表关联时加一个where条件进行判断(not null ),具体见下图

    【本题考点】

    1.如何将复杂的业务问题,使用多维度拆解分析方法,翻译成大白话的能力。

    2.遇到排名问题,要想到使用窗口函数来实现。

    3.多表联结各个情况如何去实现?把上图看懂就可以解决99%的多表联结问题了。

    推荐:如何从零学会sql?

    展开全文
  • AOP记录接口交易记录

    千次阅读 2018-01-11 22:26:27
    影响工作效率,因此考虑把部分关键接口的交易报文存储到一张表中,这样每次都可以直接去数据库查询。实现思路如下: 1.最简单的做法可能是在接口入口处获取下请求报文,请求时间等等,在出口处获取下响应报文,响应...

    做了一个新项目,与周边系统交互比较多,随之而来的一个问题,就是当交互异常的时候不是很好分析具体原因。每次都需要去服务器拉去日志,然后分析。影响工作效率,因此考虑把部分关键接口的交易报文存储到一张表中,这样每次都可以直接去数据库查询。实现思路如下:

    1.最简单的做法可能是在接口入口处获取下请求报文,请求时间等等,在出口处获取下响应报文,响应时间等等,然后保存下数据库。这样带来的一个弊端就是,记录日志与接口的业务逻辑耦合到了一起,影响代码的结构。而且维护不方便,假设有一百个接口需要加,难道要在100个地方写这种重复的代码?因此,针对这种系统共性的问题,在我理解来就属于一个切面。我们可以通过spring aop的思想来解决这个问题。

    2.提到spring aop最开始想到的是使用spring框架中的interceptor,理论上讲使用interceptor是可以解决上面问题的。我们可以配置下需要拦截的接口,在preHandle和方法中分别得到请求报文和响应报文。本人最开始的时候也是采用的这种办法,在preHandle中获取请求报文是可以做到的,获取HttpServletRequest中的输入流,然后读取输入流即可获得请求报文。但是在获取响应报文的时候不好实现,因为HttpServletResponse中包含的是一个输出流。理论上讲输出流只能写,输入流只能读。因此我们是无法获取输出流中的内容的(可能也有办法获取,但是个人觉得不好实现,所以放弃。),所以此时就要考虑别的方式。

    3.上面两种方式都有弊端,这时候要考虑别的实现方式,其实我们需要的就是监控一下目标接口,获取入参和出参。这种场景下,动态代理是最合适的。通过查找资料,找到了一种相对比较合理的解决方式。代码如下:

         1)首先在pom文件中引入如下包:

            <dependency>
                <groupId>cglib</groupId>
                <artifactId>cglib-nodep</artifactId>
                <version>3.1</version>
            </dependency>
    
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjrt</artifactId>
                <version>1.6.9</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.7.2</version>
            </dependency>
            <dependency>
                <groupId>org.reflections</groupId>
                <artifactId>reflections</artifactId>
                <version>0.9.10</version>
            </dependency>
       2)定义日志对象

    package cn.insurtech.claim.base.entity.tradelog;
    
    import javax.persistence.Entity;
    import javax.persistence.Id;
    import javax.persistence.Table;
    @Entity
    @Table(name = "u_interface_trade_log", schema = "")
    @SuppressWarnings("serial")
    public class UInterfaceTradeLog {
        @Id
        private String id;
    
        private String businessNo;
    
        private String interfaceNo;
    
        private String url;
    
        private Integer timeSpan;
    
        private String requestTime;
    
        private String responseTime;
    
        private String tradeStatus;
    
        private String isServer;
    
        private String method;
    
        private String remoteAddr;
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id == null ? null : id.trim();
        }
    
        public String getBusinessNo() {
            return businessNo;
        }
    
        public void setBusinessNo(String businessNo) {
            this.businessNo = businessNo == null ? null : businessNo.trim();
        }
    
        public String getInterfaceNo() {
            return interfaceNo;
        }
    
        public void setInterfaceNo(String interfaceNo) {
            this.interfaceNo = interfaceNo == null ? null : interfaceNo.trim();
        }
    
        public String getUrl() {
            return url;
        }
    
        public void setUrl(String url) {
            this.url = url == null ? null : url.trim();
        }
    
        public Integer getTimeSpan() {
            return timeSpan;
        }
    
        public void setTimeSpan(Integer timeSpan) {
            this.timeSpan = timeSpan;
        }
    
        public String getRequestTime() {
            return requestTime;
        }
    
        public void setRequestTime(String requestTime) {
            this.requestTime = requestTime == null ? null : requestTime.trim();
        }
    
        public String getResponseTime() {
            return responseTime;
        }
    
        public void setResponseTime(String responseTime) {
            this.responseTime = responseTime == null ? null : responseTime.trim();
        }
    
        public String getTradeStatus() {
            return tradeStatus;
        }
    
        public void setTradeStatus(String tradeStatus) {
            this.tradeStatus = tradeStatus == null ? null : tradeStatus.trim();
        }
    
        public String getIsServer() {
            return isServer;
        }
    
        public void setIsServer(String isServer) {
            this.isServer = isServer == null ? null : isServer.trim();
        }
    
        public String getMethod() {
            return method;
        }
    
        public void setMethod(String method) {
            this.method = method == null ? null : method.trim();
        }
    
        public String getRemoteAddr() {
            return remoteAddr;
        }
    
        public void setRemoteAddr(String remoteAddr) {
            this.remoteAddr = remoteAddr == null ? null : remoteAddr.trim();
        }
    
        private String requestBody;
    
        private String responseBody;
    
        private String exceptionStackTrace;
    
        public String getRequestBody() {
            return requestBody;
        }
    
        public void setRequestBody(String requestBody) {
            this.requestBody = requestBody == null ? null : requestBody.trim();
        }
    
        public String getResponseBody() {
            return responseBody;
        }
    
        public void setResponseBody(String responseBody) {
            this.responseBody = responseBody == null ? null : responseBody.trim();
        }
    
        public String getExceptionStackTrace() {
            return exceptionStackTrace;
        }
    
        public void setExceptionStackTrace(String exceptionStackTrace) {
            this.exceptionStackTrace = exceptionStackTrace == null ? null : exceptionStackTrace.trim();
        }
    }
          3)编写拦截器,拦截器是重点。这个类中用到了下面一些技术点:

    自定义注解:自定义注解可以很方便的获取我们要拦截的接口的一些信息,并且可以在拦截的方法上面配置一些需要保存的属性,比如接口编号等。

            局部线程变量:spring创建的拦截器是单例的,我们可能需要在拦截器中定义一个全局变量,供多个方法使用。考虑到并发情况,因此不能使用普通的局部变量,需要使用ThreadLocal来避免并发带来的问题。

    反射:我们需要记录日志的时候保存当前请求报文中的业务号,可以配置下业务号所在的位置,通过反射获取。具体需要看下面代码:

    package cn.insurtech.aop;
    
    import cn.insurtech.bean.UInterfaceTradeLogWithBLOBs;
    import cn.insurtech.dao.UInterfaceTradeLogMapper;
    import com.alibaba.fastjson.JSON;
    import org.apache.log4j.Logger;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.web.context.request.RequestAttributes;
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    
    import javax.servlet.http.HttpServletRequest;
    import java.io.PrintWriter;
    import java.io.StringWriter;
    import java.lang.reflect.Method;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Map;
    import java.util.UUID;
    
    /**
     * Created by sxb-gt on 2017/12/30.
     */
    @Aspect
    @Component
    public class TradeLogAspect {
        Logger LOGGER = Logger.getLogger(TradeLog.class);
        /** 建立日志对象线程变量 **/
        private ThreadLocal<UInterfaceTradeLogWithBLOBs> threadLocal = new ThreadLocal<UInterfaceTradeLogWithBLOBs>();
        @Autowired
        private UInterfaceTradeLogMapper uInterfaceTradeLogMapper;
        private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
        private final static Map<String, TradeLogProperties> TRADE_LOG_PROPERTIES_MAP = TradeLogAnnotationParse.getUriTradelogMap();
        @Before("@annotation(TradeLog)")
        public void logBefore(JoinPoint point) {
            try{
                /** 获取请求对象 **/
                RequestAttributes ra = RequestContextHolder.getRequestAttributes();
                ServletRequestAttributes sra = (ServletRequestAttributes)ra;
                HttpServletRequest request = sra.getRequest();
                String uri = request.getRequestURI();
                String url = request.getRequestURL().toString();
                TradeLogProperties tradeLogProperties = TRADE_LOG_PROPERTIES_MAP.get(uri);
                UInterfaceTradeLogWithBLOBs uInterfaceTradeLog = new UInterfaceTradeLogWithBLOBs();
                /** 设置UUID为主键 **/
                uInterfaceTradeLog.setId(UUID.randomUUID().toString().replace("-", ""));
                /** 请求路径 **/
                uInterfaceTradeLog.setUrl(url);
                /** 业务号 **/
                uInterfaceTradeLog.setBusinessNo(getBusinessNo(tradeLogProperties,point.getArgs()[0]));
                /** 接口编号 **/
                uInterfaceTradeLog.setInterfaceNo(tradeLogProperties.getInterfaceNo());
                /** 请求时间 **/
                uInterfaceTradeLog.setRequestTime(sdf.format(new Date()));
                /** 请求报文 **/
                if (point.getArgs() != null && point.getArgs().length > 0) {
                    Object parameterObject = point.getArgs()[0];
                    if (parameterObject instanceof String) {
                        uInterfaceTradeLog.setRequestBody((String) parameterObject);
                    }else {
                        uInterfaceTradeLog.setRequestBody(JSON.toJSONString(parameterObject));
                    }
                }
                /** 请求对应的controller及method名称 **/
                uInterfaceTradeLog.setMethod(point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName());
                /** 存储用户的IP **/
                uInterfaceTradeLog.setRemoteAddr(getIpAddress(request));
                /** “是否当前系统为服务方” **/
                uInterfaceTradeLog.setIsServer("1");
                threadLocal.set(uInterfaceTradeLog);
            }catch (Exception e) {
                LOGGER.error("日志记录报错!");
                e.printStackTrace();
            }
        }
    
        /**
         * 此处execution表达式,拦截所有的方法。暂时没找到合适的表达式拦截多个制定的方法。
         */
        @Pointcut("@annotation(TradeLog)")
        public void resultMapAspect() {
    
        }
    
        @AfterReturning(value = "resultMapAspect()", returning = "resultMap")
        public void logAfterReturning(JoinPoint joinpoint, Object resultMap) throws Throwable {
            try{
                /** 从当前线程中取出日志记录对象 **/
                UInterfaceTradeLogWithBLOBs uInterfaceTradeLog = threadLocal.get();
                /** 如果uInterfaceTradeLog为null说明该方法不需要拦截 **/
                if (uInterfaceTradeLog == null) {
                    return;
                }
                Date responseTime = new Date();
                /** 响应时间 **/
                uInterfaceTradeLog.setResponseTime(sdf.format(responseTime));
                /** 响应报文 **/
                if (resultMap instanceof String) {
                    uInterfaceTradeLog.setResponseBody((String)resultMap);
                }else {
                    uInterfaceTradeLog.setResponseBody(JSON.toJSONString(resultMap));
                }
                /** 交互状态,有返回代表交互成功,状态为1。抛异常代表交互失败,状态为0 **/
                uInterfaceTradeLog.setTradeStatus("1");
                /** 接口交互消耗时长 **/
                uInterfaceTradeLog.setTimeSpan((int)(responseTime.getTime()- sdf.parse(uInterfaceTradeLog.getRequestTime()).getTime()));
                System.out.println("插入开始:" + System.currentTimeMillis());
                uInterfaceTradeLogMapper.insertSelective(uInterfaceTradeLog);
                System.out.println("插入结束:" + System.currentTimeMillis());
            }catch (Exception e) {
                LOGGER.error("日志记录报错!");
                e.printStackTrace();
            }
        }
        @AfterThrowing(throwing="ex"
                , pointcut=("@annotation(TradeLog)"))
        // 声明ex时指定的类型会限制目标方法必须抛出指定类型的异常
        // 此处将ex的类型声明为Throwable,意味着对目标方法抛出的异常不加限制
        public void logException(Throwable ex)
        {
            try {
                /** 从当前线程中取出日志记录对象 **/
                UInterfaceTradeLogWithBLOBs uInterfaceTradeLog = threadLocal.get();
                /** 如果uInterfaceTradeLog为null说明该方法不需要拦截 **/
                if (uInterfaceTradeLog == null) {
                    return;
                }
                Date responseTime = new Date();
                /** 响应时间 **/
                uInterfaceTradeLog.setResponseTime(sdf.format(responseTime));
                /** 响应报文 **/
                uInterfaceTradeLog.setResponseBody(ex.toString());
                /** 交互状态,有返回代表交互成功,状态为1。抛异常代表交互失败,状态为0 **/
                uInterfaceTradeLog.setTradeStatus("0");
                /** 接口交互消耗时长 **/
                try {
                    uInterfaceTradeLog.setTimeSpan((int)(responseTime.getTime()- sdf.parse(uInterfaceTradeLog.getRequestTime()).getTime()));
                } catch (ParseException e) {
                    uInterfaceTradeLog.setTimeSpan(999999);
                }
                StringWriter stringWriter = new StringWriter();
                PrintWriter printWriter = new PrintWriter(stringWriter);
                ex.printStackTrace(printWriter);
                StringBuffer exceptionStackTrace = stringWriter.getBuffer();
                /** 异常堆栈 **/
                uInterfaceTradeLog.setExceptionStackTrace(exceptionStackTrace.toString());
                System.out.println("插入开始:" + System.currentTimeMillis());
                uInterfaceTradeLogMapper.insertSelective(uInterfaceTradeLog);
                System.out.println("插入结束:" + System.currentTimeMillis());
            }catch (Exception e) {
                LOGGER.error("日志记录报错!");
                e.printStackTrace();
            }
    
        }
        /**
         * 获取用户真实IP地址,不使用request.getRemoteAddr();的原因是有可能用户使用了代理软件方式避免真实IP地址,
         * 参考文章: http://developer.51cto.com/art/201111/305181.htm
         *
         * 可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP值,究竟哪个才是真正的用户端的真实IP呢?
         * 答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。
         *
         * 如:X-Forwarded-For:192.168.1.110, 192.168.1.120, 192.168.1.130,
         * 192.168.1.100
         *
         * 用户真实IP为: 192.168.1.110
         *
         * @param request
         * @return
         */
        public static String getIpAddress(HttpServletRequest request) {
            String ip = request.getHeader("x-forwarded-for");
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }
            return ip;
        }
    
        /**
         * 通过反射获取业务单号
         * @param tradeLogProperties  接口日志记录相关属性对象
         * @param inputParameter  controller入参
         * @return
         */
        private String getBusinessNo(TradeLogProperties tradeLogProperties,Object inputParameter){
            String businessNo = "";
            /** 获取businessno 所在位置 **/
            String[] filedArray = tradeLogProperties.getBusinessNo().split("\\.");
            /** controller的入参要么是string,要么是json对象 **/
            if (inputParameter instanceof String) {
                /** 入参对象对应的JSON对象CLASS类型 **/
                String className = tradeLogProperties.getParameterClass();
                /** businessno为空代表入参即为业务号**/
                if ("".equals(tradeLogProperties.getBusinessNo())) {
                    return (String) inputParameter;
                }else {
                    try {
                        inputParameter = JSON.parseObject((String)inputParameter,Class.forName(className));
                    }catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            for (String filed : filedArray) {
                try {
                    Method method = inputParameter.getClass().getDeclaredMethod("get" + filed,null);
                    inputParameter = method.invoke(inputParameter,null);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (inputParameter instanceof String) {
                businessNo = (String ) inputParameter;
            }
            return businessNo;
        }
    }
    上面这个类,只是提供了一个思路。针对具体的项目,还是需要调整的。

          4)自定义注解,自定义注解有两个好处:第一,是可以取代配置文件。最开始的时候我考虑的也是写一个配置文件,通过读取配置文件的方式来获取需要拦截的方法,但是感觉配置文件比较麻烦,没有注解方便。 第二,是方便上面的拦截器拦截,如果不通过拦截注解的方式,我们每次写完配置文件,还需要编写一个execution拦截表达式,比较繁琐。

    package cn.insurtech.aop;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * Created by sxb-gt on 2018/1/3.
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD})
    public @interface TradeLog {
        /** 接口编号,不能重复 **/
        String interfaceno();
        /** 业务号位置 **/
        String businessno()default "";
        /** 入参对象类型 **/
        String parameterclass() default "";
    }
    
    5)在需要拦截的controller上面配置自定义注解

     @RequestMapping(value = "/sendClaimInfo", method = RequestMethod.POST)
        @TradeLog(interfaceno = "CL001",parameterclass = "cn.insurtech.externalentity.liveneo.cld01.SendClaimInfoRequest",businessno = "BusinessBody.SendClaimInfo.RegistNo")
        public String sendClaimInfo(@RequestBody String jsonDate) {
           /** 业务逻辑部分 **/
        }

    6)自定义注解扫描,这个类是在系统启动的时候扫描指定目录下所有配置自定义注解的方法。

    package cn.insurtech.aop;
    
    import org.apache.commons.lang.StringUtils;
    import org.reflections.Reflections;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Component;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.lang.reflect.Method;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;
    
    /**
     * Created by sxb-gt on 2018/1/3.
     */
    @Component
    //@PropertyScource("application.properties")
    public class TradeLogAnnotationParse {
        /** uri与日志记录配置对象映射map **/
        private final static Map<String, TradeLogProperties> URI_TRADELOG_MAP = new HashMap<String, TradeLogProperties>();
        private static boolean IS_INIT = false;
    
        private static String basePackage;
        private static String projectName;
    
        @Value("${tradelog.basepackage}")
        public  void setBasePackage(String basePackage) {
            TradeLogAnnotationParse.basePackage = basePackage;
        }
        @Value("${tradelog.projectname}")
        public  void setProjectName(String projectName) {
            TradeLogAnnotationParse.projectName = projectName;
        }
    
        /** 加载配置文件 **/
        private static void init() {
            try {
                Reflections reflections = new Reflections(basePackage);
                Set<Class<?>> classesList = reflections.getTypesAnnotatedWith(RestController.class);
                classesList.addAll(reflections.getTypesAnnotatedWith(Controller.class));
                for (Class classes : classesList) {
                    //得到该类下面的所有方法
                    Method[] methods = classes.getDeclaredMethods();
                    for (Method method : methods) {
                        if (method.isAnnotationPresent(TradeLog.class)) {
                            //得到该类下面的RequestMapping注解
                            RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
                            TradeLog tradeLog = method.getAnnotation(TradeLog.class);
                            String uri = projectName + requestMapping.value()[0];
                            Class parameterClass = method.getParameterTypes()[0];
                            String interfaceno = tradeLog.interfaceno();
                            String businessno = tradeLog.businessno();
                            TradeLogProperties tradeLogProperties = new TradeLogProperties();
                            tradeLogProperties.setUri(uri);
                            if (StringUtils.isBlank(tradeLog.parameterclass())) {
                                tradeLogProperties.setParameterClass(parameterClass.getName());
                            }else {
                                tradeLogProperties.setParameterClass(tradeLog.parameterclass());
                            }
    
                            tradeLogProperties.setInterfaceNo(interfaceno);
                            tradeLogProperties.setBusinessNo(businessno);
                            System.out.println("url=============" + uri);
                            System.out.println("parameterclass=="+parameterClass.getName());
                            System.out.println("interfaceno====="+interfaceno);
                            System.out.println("businessno====="+businessno);
                            URI_TRADELOG_MAP.put(uri,tradeLogProperties);
                        }
                    }
                }
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
        public static Map<String, TradeLogProperties> getUriTradelogMap() {
            if (!IS_INIT) {
                init();
            }
            return URI_TRADELOG_MAP;
        }
    }
    

    以上只是部分关键代码,主要是提供一个思路。通过本次实现这个功能,对AOP,自定义注解还是有了更多一点的认识,记录一下方便以后再需要用到的时候查阅。

    展开全文
  • 区块链中有两把钥匙,一把公钥,一把私钥。这两个钥匙是通过一种数学算法得出来的,有关联的一对钥匙。说的简单点,就是私钥可以生成公钥,而公钥是无法推导出私钥的,所以来说很安全。 在区块链中,公钥是公开的...

    区块链中有两把钥匙,一把公钥,一把私钥。这两个钥匙是通过一种数学算法得出来的,有关联的一对钥匙。说的简单点,就是私钥可以生成公钥,而公钥是无法推导出私钥的,所以来说很安全。

     

    区块链中,公钥是公开的钥匙,是要公开发行配送的,只要有要求谁都能取得。私钥就是私人才拥有的了,就像你的保险柜钥匙,你不可能拿给别人保管吧。

     

    公钥私钥是配对的,在区块链中,如果利用公钥给信息加密,这时候必须要用私钥才能打开,如果用私钥给信息加了密,则必须用公钥来打开,不然的话是根本打不开的。这个系统的优势是两个用户能够安全地沟通,而不用互相交换秘密钥匙。例如一个人要将一条信息传给另一个人,而这信息的内容是保密级别的,为了防止别人打开,送信者用公钥加密,而要解密就必须要收信者动用自己的公钥才行。我举个栗子。

     

    张三给李四转了一笔钱,然后给大家广播说我转了钱了啊,大家把它记在区块链中。可这时王麻子跳出来说:“我为什么相信你转了钱啊,你有证据吗。”张三就说:“我的公钥在这儿呢,这个公钥可以证明我是有私钥的人,你看这个信息加了公钥,我真的转了。”然后王麻子就将这笔交易记录下来了。

     

     

    区块链中的交易记录能撤销吗?

     

    区块链中有个很大的特点,那就是交易是不可撤销的。

     

    区块链只会向前生成区块,不会向后取消区块。也就是说,区块链中是没有后悔药卖的。还有一点,区块链中是点对点的交易,所有交易都要广播。而且区块链是全网记账,交易明细既记在你的电脑账本上,也记在别人的电脑账本上,但是别人是不知道你是谁的,就算你要想撤销,你也不可能跑去连入其中的电脑上都删除这条交易吧。

    展开全文
  • 表格模板-个人股票交易记录.ett
  • 接着上一篇博客,这里继续整合交易类。 import datetime #交易类,后期需要整合公钥,私钥 class Transaction: #payer 付款方,receiver收款方 def __init__(self,payer,receiver,money): self.payer = payer...

    接着上一篇博客,这里继续整合交易类。

    import datetime
    
    #交易类,后期需要整合公钥,私钥
    class Transaction:
        #payer 付款方,receiver收款方
        def __init__(self,payer,receiver,money):
            self.payer = payer
            self.receiver = receiver
            self.money = money
            self.timestamp = datetime.datetime.now() #交易时间
    
        def __repr__(self):
            return str(self.payer)+" pay "+str(self.receiver)+" "+str(self.money)+" "+str(self.timestamp)
    
    if __name__=="__main__":
        t = Transaction("yicheng","ddd",100)
        print(t)
    
    

    测试模块:

    if __name__=="__main__":
    
        t1 = Transaction("yicheng", "ddd1", 100)
        t2 = Transaction("yicheng", "ddd2", 200)
        t3 = Transaction("yicheng", "ddd3", 300)
    
        m1 = DaDaMessage(t1)
        m2 = DaDaMessage(t2)
        m3 = DaDaMessage(t3)
        try:
    
            m1.seal()
            m2.link(m1)
    
            m2.seal()
            m3.link(m2)
    
            m3.seal()
    
            #m1.hash = "0xaaaajjjjj"
            #m1.data = "I don't love "
    
            m1.validate()
            m2.validate()
            m3.validate()
    
            print(m1)
            print(m2)
            print(m3)
        except InvalidateMessage as e:
            print(e)
    

    查看打印结果:
    这里写图片描述

    展开全文
  • 一:保存书店每日交易记录架构 二:项目架构 三:代码详情 1:ModelBooks类 package BookPurchasingSystem; import java.util.Date; /* * 图书实体类 */ public class ModelBooks { //图书编号 private int id; ...
  • 区块链中,假设有十条交易广播,编号一到十,会不会出现矿工A 对编号1到7的广播进行区块计算,...如果可以生成各自的区块,那么编号5,6,7的交易可能就同时在两个不同的区块中,区块链中的交易记录是否存在重复问题?
  • 如何查询比特币交易记录

    万次阅读 2019-06-15 20:57:54
    经过前面的学习,你应该理解区块链以及比特币...比特币系统中记录了一条条的交易记录,多条交易记录打包成一个区块,一个个区块按照时间顺序连接起来。整个区块链上的每一个区块中的每一笔交易对于每个人都是可以查...
  • 本文介绍如何将OKEx交易所成交记录数据中的日期时间转毫秒级时间戳。...1. OKEx交易记录格式 [ { "time":"2019-09-14T10:29:20.142Z", "timestamp":"2019-09-14T10:29:20.142Z", "trade_id":"1650300...
  • 使用 python + selenium + mongodb实时监控个人支付宝交易账单变化 支付宝目前国内最大最流行的支付软件,风控做的很好,这些年车开的也很稳,为生活提供很大便利。祖国崛起啊!!! 注:只能爬取个人支付宝...
  • 保存书店每日交易记录程序设计

    千次阅读 2020-01-05 18:33:55
    编写一个保存书店每日交易记录的程序,使用字节流将书店的交易信息记录在本地的csv文件中。文件命名格式为“销售记录”加上当天日期加上“.csv”后缀 实现: (1)为方便保存图书的信息,可以将图书信息封装成一个...
  • 链家二手房信息、交易记录爬虫,部分数据分析
  • android实现或者web3j实现,大神们来帮帮忙!!!!!!!!!!
  • ATM交易记录

    2018-05-10 00:02:27
    #include&lt;bits/stdc++.h&gt; using namespace std; class Time { int month; int day; int hour; int minute; public: Time(){ month=0;day=0;hour=0;minute=0;... Time(int ...

空空如也

1 2 3 4 5 ... 20
收藏数 6,256
精华内容 2,502
关键字:

交易记录