微信支付

controller

package com.youruan.examine.controller;

import com.youruan.examine.config.model.ResultData;
import com.youruan.examine.entity.vo.PayVo;
import com.youruan.examine.service.WeixinPayService;
import com.youruan.examine.service.WxOrderService;
import com.youruan.examine.util.*;
import com.youruan.examine.util.mobile.MobileUtil;
import org.apache.commons.lang3.StringUtils;
import org.jdom.JDOMException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.concurrent.TimeUnit;

/**
 * 描述类的功能
 *
 * @author zhy
 * @date 2019-01-14 20:08
 * @description
 * @see [相关类/方法]
 * @since V1.0.0
 */
@Controller
@RequestMapping(value = "/weixin")
public class WeixinPayContoller {

    private static final Logger logger = LoggerFactory.getLogger(WeixinPayContoller.class);

    @Autowired
    private WeixinPayService weixinPayService;

    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    private WxOrderService wxOrderService;

    @Value("${pay.wxpay.contextUrl}")
    private String serverUrl;
    @Value("${pay.wxpay.appID}")
    private String appId;
    @Value("${pay.wxpay.mchID}")
    private String mchID;
    @Value("${pay.wxpay.key}")
    private String apiKey;
    @Value("${pay.wxpay.contextUrl}")
    private String contextUrl;
    @Value("${pay.wxpay.appSecret}")
    private String appSecret;

    /**
     *
     * @param OutTradeNo    订单号
     * @param totalFee   金额
     * @param map
     * @return
     * @throws UnsupportedEncodingException
     */
    @RequestMapping("/pay")
    public String pay(String OutTradeNo, String totalFee, ModelMap map) throws UnsupportedEncodingException {
        logger.info("H5支付(需要公众号内支付)");
        String url = weixinPayService.weixinPayMobile(OutTradeNo, totalFee);
        return "redirect:" + url;
    }

    /**
     * 预下单(对于已经产生的订单)
     *
     * @param request
     *
     * @return
     *
     * @throws Exception String
     * @Author zhy
     * @Date 2017年7月31日 更新日志
     * 2017年7月31日  zhy 首次创建
     */
    @SuppressWarnings("rawtypes")
    @RequestMapping(value = "/dopay")
    public String dopay(HttpServletRequest request) throws Exception {
        String state = request.getParameter("state");
        String[] split = state.split("/");
        String orderNo = split[0];
        String totalFee = split[1];
        //获取code 这个在微信支付调用时会自动加上这个参数 无须设置
        String code = request.getParameter("code");
        logger.info("code:" + code);
        //获取用户openID(JSAPI支付必须传openid)
        String openId = MobileUtil.getOpenId(code, appId, appSecret);
        String createIp = AddressUtils.getIpAddr(request);
        wxOrderService.updateGiftId(orderNo, openId, createIp);
        String notify_url = serverUrl + "/weixin/WXPayBack";//回调接口
        String trade_type = "JSAPI";// 交易类型H5支付
        SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
        ConfigUtil.commonParams(packageParams);
        packageParams.put("appid", appId);
        packageParams.put("body", "buy");// 商品描述
        packageParams.put("mch_id", mchID);
        packageParams.put("notify_url", notify_url);// 回调地址
        packageParams.put("openid", openId);//用户openID
        packageParams.put("out_trade_no", orderNo);// 商户订单号
        packageParams.put("spbill_create_ip", createIp);// 发起人IP地址
        packageParams.put("total_fee", totalFee);// 总金额
        packageParams.put("trade_type", trade_type);// 交易类型
        String sign = PayCommonUtil.createSign("UTF-8", packageParams, apiKey);
        packageParams.put("sign", sign);// 签名
        logger.info(packageParams.toString());
        String requestXML = PayCommonUtil.getRequestXml(packageParams);
        String resXml = HttpUtil.postData(ConfigUtil.UNIFIED_ORDER_URL, requestXML);
        logger.info(resXml);
        Map map = XMLUtil.doXMLParse(resXml);
        String returnCode = (String) map.get("return_code");
        String returnMsg = (String) map.get("return_msg");
        StringBuffer url = new StringBuffer();
        ValueOperations<String, PayVo> ops = redisTemplate.opsForValue();
        if ("SUCCESS".equals(returnCode)) {
            String resultCode = (String) map.get("result_code");
            String errCodeDes = (String) map.get("err_code_des");
            if ("SUCCESS".equals(resultCode)) {
                //获取预支付交易会话标识
                String prepay_id = (String) map.get("prepay_id");
                String prepay_id2 = "prepay_id=" + prepay_id;
                String packages = prepay_id2;
                SortedMap<Object, Object> finalpackage = new TreeMap<Object, Object>();
                String timestamp = DateUtil.getTimestamp();
                String nonceStr = packageParams.get("nonce_str").toString();
                finalpackage.put("appId", appId);
                //finalpackage.put("mch_id", mchID);
                finalpackage.put("nonceStr", nonceStr);
                finalpackage.put("package", packages);
                finalpackage.put("signType", "MD5");
                finalpackage.put("timeStamp", timestamp);
                //这里很重要  参数一定要正确 狗日的腾讯 参数到这里就成大写了
                //可能报错信息(支付验证签名失败 get_brand_wcpay_request:fail)
                logger.info("签名前参数:" + finalpackage.toString());
                sign = PayCommonUtil.createSign("UTF-8", finalpackage, apiKey);
                logger.info("签名:" + sign);
                url.append("redirect:" + contextUrl + "weixin/payOrder.jsp?");
                url.append("timeStamp=" + timestamp + "&nonceStr=" + nonceStr);
                url.append("&signType=MD5" + "&paySign=" + sign + "&appId=" + appId);
                url.append("&orderNo=" + orderNo + "&totalFee=" + totalFee);
                url.append("&package=" + packages);
                logger.info(url.toString());
                PayVo payVo = new PayVo();
                payVo.setAppId(appId);
                payVo.setNonceStr(nonceStr);
                payVo.setOrderNo(orderNo);
                payVo.setPackages(packages);
                payVo.setSign(sign);
                payVo.setTotalFee(totalFee);
                payVo.setTimestamp(timestamp);
                payVo.setSignType("MD5");
                payVo.setUrl(url.toString());
                payVo.setState("SUCCESS");
                ops.set(orderNo, payVo, 1, TimeUnit.MINUTES);
            } else {
                logger.info("订单号:{}错误信息:{}", orderNo, errCodeDes);
                url.append("redirect:" + contextUrl + "weixin/error.jsp?code=0&orderNo=" + orderNo);//该订单已支付
                PayVo payVo = new PayVo();
                payVo.setUrl(url.toString());
                payVo.setState("FAIL");
                payVo.setMessage("订单号:" + orderNo + ";错误信息:" + returnMsg);
                ops.set(orderNo, payVo, 1, TimeUnit.MINUTES);
            }
        } else {
            logger.info("订单号:{}错误信息:{}", orderNo, returnMsg);
            url.append("redirect:" + contextUrl + "weixin/error.jsp?code=1&orderNo=" + orderNo);//系统错误
            PayVo payVo = new PayVo();
            payVo.setUrl(url.toString());
            payVo.setState("FAIL");
            payVo.setMessage("订单号:" + orderNo + ";错误信息:" + returnMsg);
            ops.set(orderNo, payVo, 1, TimeUnit.MINUTES);
        }
        return url.toString();
    }

    /**
     * 手机支付完成回调
     *
     * @param request
     * @param response platForm  void
     *
     * @Author zhy
     * @Date 2017年7月31日 更新日志
     * 2017年7月31日  zhy 首次创建
     */
    @RequestMapping(value = "/WXPayBack")
    public void WXPayBack(HttpServletRequest request, HttpServletResponse response) {
        String resXml = "";
        try {
            //解析XML
            Map<String, String> map = MobileUtil.parseXml(request);
            String return_code = map.get("return_code");//状态
            String out_trade_no = map.get("out_trade_no");//订单号
            if (return_code.equals("SUCCESS")) {
                if (out_trade_no != null) {
                    /*voteService.changePayStatus(out_trade_no, "支付中");*/
                    //处理订单逻辑
                    logger.info("微信手机支付回调成功订单号:{}", out_trade_no);
                    resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                }
            } else {
                if (StringUtils.isNotBlank(out_trade_no)) {
                    /*voteService.changePayStatus(out_trade_no, "取消");*/
                }
                logger.info("微信手机支付回调失败订单号:{}", out_trade_no);
                resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
            }
        } catch (Exception e) {
            logger.error("手机支付回调通知失败", e);
            resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
        }
        try {
            // ------------------------------
            // 处理业务完毕
            // ------------------------------
            BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());
            out.write(resXml.getBytes());
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @GetMapping("/checkOrder")
    public ResultData checkOrder() throws JDOMException, IOException {
        weixinPayService.checkOrder();
        return ResultData.ok200();
    }
}

service

package com.youruan.examine.service;

import com.youruan.examine.entity.WxOrder;
import java.util.List;

public interface WxOrderService {

    Integer saveWxOrder(WxOrder wxOrder);

    WxOrder getWxOrder(String merchantOrder);

    void updateGiftId(String merchantOrder, String openId, String createIp);

    List<WxOrder> payFailOrder();
    /*
    Integer saveWxOrder(String openId, String clientIp, String orderId, String merchantOrder, BigDecimal amount, String payStatus, String remark);

    List<WxOrderVo> currWxOrders(Integer userId, String payStatus);

    WxOrderVo getWxOrderVo(String merchantOrder);

    void sendWxOrderVo(WxOrderVo wxOrderVo);

    Integer payCount(Integer userId, String payStatus);


    void changeOrderState();*/


}

package com.youruan.examine.service.impl;

import com.youruan.examine.entity.WxOrder;
import com.youruan.examine.mapper.WxOrderMapper;
import com.youruan.examine.service.WxOrderService;
import com.youruan.examine.util.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;

/**
 * 描述类的功能
 *
 * @author zhy
 * @date 2018-12-29 18:37
 * @description
 * @see [相关类/方法]
 * @since V1.0.0
 */
@Transactional
@Service
public class WxOrderServiceImpl implements WxOrderService{

    @Autowired
    private WxOrderMapper wxOrderMapper;
    /*@Autowired
    private RedisTemplate redisTemplate;*/
    private Logger logger = LoggerFactory.getLogger(WxOrderServiceImpl.class);
    @Override
    public Integer saveWxOrder(WxOrder wxOrder) {
        if (wxOrder.getId() == null) {
            wxOrderMapper.insert(wxOrder);
        } else {
            wxOrderMapper.updateByPrimaryKeySelective(wxOrder);
        }
        return wxOrder.getId();
    }

    @Override
    public List<WxOrder> payFailOrder() {
        Example example = new Example(WxOrder.class);
        Date myDate = DateUtil.calcDateByMinute(new Date(), -5);
        example.createCriteria().andIsNull("isPay").andLessThan("orderTime", myDate);
        return wxOrderMapper.selectByExample(example);
    }

    @Override
    public void updateGiftId(String merchantOrder, String openId, String createIp) {
        WxOrder wxOrder = getWxOrder(merchantOrder);
        Integer wxOrderId = wxOrder.getId();
        wxOrder = new WxOrder();
        wxOrder.setId(wxOrderId);
        wxOrder.setOpenId(openId);
        wxOrder.setClientIp(createIp);
        wxOrderMapper.updateByPrimaryKeySelective(wxOrder);
    }

    @Override
    public WxOrder getWxOrder(String merchantOrder) {
        WxOrder wxOrder = new WxOrder();
        wxOrder.setMerchantOrder(merchantOrder);
        return wxOrderMapper.selectOne(wxOrder);
    }

    /*
    @Override
    public Integer saveWxOrder(String openId, String clientIp, String orderId, String merchantOrder, BigDecimal amount, String payStatus, String remark) {
        WxOrder wxOrder = new WxOrder();
        //wxOrder.setPlayerId(playerId);
        //wxOrder.setGiftId(giftId);
        wxOrder.setOpenId(openId);
        wxOrder.setOrderId(orderId);
        wxOrder.setMerchantOrder(merchantOrder);
        wxOrder.setClientIp(clientIp);
        wxOrder.setAmount(amount);
        wxOrder.setPayStatus(payStatus);
        wxOrder.setOrderTime(new Date());
        wxOrder.setRemark(remark);
        return saveWxOrder(wxOrder);
    }

    @Override
    public List<WxOrderVo> currWxOrders(Integer userId, String payStatus) {
        String temp = StringUtils.isBlank(payStatus) ? payStatus : "";
        String key = "currWxOrderVo" + "_" + userId + "_" + temp;
        ValueOperations<String, List<WxOrderVo>> ops = redisTemplate.opsForValue();
        if (redisTemplate.hasKey(key)) {
            return ops.get(key);
        }
        List<WxOrderVo> wxOrderVos = wxOrderMapper.currWxOrders(userId, payStatus);
        ops.set(key, wxOrderVos, 30, TimeUnit.SECONDS);
        return wxOrderVos;
    }

    @Override
    public WxOrderVo getWxOrderVo(String merchantOrder) {
        return wxOrderMapper.getWxOrder(merchantOrder);
    }

    @Override
    public void sendWxOrderVo(WxOrderVo wxOrderVo) {
        Integer userId = wxOrderVo.getUserId();
        logger.info("***********推送的登陆人员ID为:" + userId);
        if (userId == null) return;
        ChannelGroup channels = MyWebSocketServerHandler.chanelIdMap.get(userId.toString());
        if (channels == null || channels.isEmpty()) {
            logger.info("************推送的登陆人员的连接数为空,请检查************");
            return;
        }
        logger.info("*************推送的登陆人员的连接数为:" + channels.size());
        channels.writeAndFlush(new TextWebSocketFrame(JSON.toJSONString(wxOrderVo)));
    }


    @Override
    public Integer payCount(Integer userId, String payStatus) {
        return wxOrderMapper.payCount(userId, payStatus);
    }

    @Override
    public WxOrder getWxOrder(String merchantOrder) {
        WxOrder wxOrder = new WxOrder();
        wxOrder.setMerchantOrder(merchantOrder);
        return wxOrderMapper.selectOne(wxOrder);
    }

    @Override
    public void changeOrderState() {
        wxOrderMapper.changeOrderState();
    }*/


}

package com.youruan.examine.service;

import org.jdom.JDOMException;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;

public interface WeixinPayService {

    /**
     * 微信公众号支付返回一个url地址
     *
     * @param OutTradeNo
     *
     * @param totalFee
     * @return String
     *
     * @Author zhy
     * @Date 2017年7月31日 更新日志
     * 2017年7月31日  zhy 首次创建
     */
    String weixinPayMobile(String OutTradeNo, String totalFee) throws UnsupportedEncodingException;

    /**
     * 微信分享信息
     *
     * @param url
     *
     * @return
     */
    Map<String, Object> getTicketData(String url);

    /**
     * 查询订单是否完成
     */
    void checkOrder() throws JDOMException, IOException;

    /*void checkOnline() throws JDOMException, IOException;*/


}

package com.youruan.examine.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.youruan.examine.entity.WxOrder;
import com.youruan.examine.entity.vo.PayVo;
import com.youruan.examine.service.WeixinPayService;
import com.youruan.examine.service.WxOrderService;
import com.youruan.examine.util.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.jdom.JDOMException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.*;

@Service
public class WeixinPayServiceImpl implements WeixinPayService {

    private static final Logger logger = LoggerFactory.getLogger(WeixinPayServiceImpl.class);
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private WxOrderService wxOrderService;

    @Value("${pay.wxpay.notifyUrl}")
    private String notify_url;
    @Value("${pay.wxpay.contextUrl}")
    private String serverUrl;
    @Value("${pay.wxpay.key}")
    private String apiKey;
    @Value("${pay.wxpay.appID}")
    private String appID;
    @Value("${pay.wxpay.mchID}")
    private String mchID;
    @Value("${pay.wxpay.appSecret}")
    private String appSecret;
    private String accessTokeUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
    private String jsapiTicketUrl = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESSTOKEN&type=jsapi";

    // 5分钟,可以根据需要来设置
    private Long time = 300L;

    //处理缓存时间
    public static Map<String, Object> dataMap = new HashMap<String, Object>();

    @Override
    public String weixinPayMobile(String OutTradeNo, String totalFee) throws UnsupportedEncodingException {
        StringBuffer url = new StringBuffer();
        //redirect_uri 需要在微信支付端添加认证网址
        totalFee = CommonUtil.subZeroAndDot(totalFee);
        url.append("http://open.weixin.qq.com/connect/oauth2/authorize?");
        url.append("appid=" + appID);
        String redirectUri = serverUrl + "weixin/dopay";
        redirectUri = redirectUri + "?state=" + OutTradeNo + "/" + totalFee;
        //url.append("&redirect_uri=" + URLEncoder.encode(redirectUri,"utf-8"));
        url.append("&response_type=code&scope=snsapi_base&state=");
        url.append(OutTradeNo + "/" + totalFee);//订单号/金额(单位是分)
        url.append("&redirect_uri=" + redirectUri);
        url.append("#wechat_redirect");
        return url.toString();
    }

    @Override
    public Map<String, Object> getTicketData(String url) {
        String accessToken = "";
        String jsapiTicket = "";
        try {
            accessToken = getToken();
            jsapiTicket = getJsapiTicket(accessToken);
        } catch (Exception e) {
            System.out.println("系统异常:" + e.getMessage());
        }
        Map<String, Object> ret = new HashMap<String, Object>();
        String nonce_str = create_nonce_str();
        String timestamp = create_timestamp();
        String encyptStr;
        String signature = "";

        //注意这里参数名必须全部小写,且必须有序
        encyptStr = "jsapi_ticket=" + jsapiTicket +
                "&noncestr=" + nonce_str +
                "&timestamp=" + timestamp +
                "&url=" + url;
        logger.info(encyptStr);
        signature = DigestUtils.sha1Hex(encyptStr.getBytes());
       /*
        try
        {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(encyptStr.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
        }
        catch (Exception e)
        {
            System.out.println(e.getMessage());
        }
        */

        logger.info("signature:" + signature);
        ret.put("url", url);
        ret.put("jsapi_ticket", jsapiTicket);
        ret.put("nonceStr", nonce_str);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);

        return ret;
    }

    /**
     * 查询订单是否完成
     */
    @Override
    public void checkOrder() throws JDOMException, IOException {
        List<WxOrder> wxOrders = wxOrderService.payFailOrder();
        for (WxOrder wxOrder : wxOrders) {
            //通过微信支付平台查询订单状态
            WxOrder wxOrderTemp = dealwithOrder(wxOrder.getMerchantOrder(), wxOrder.getId(), wxOrder.getAmount());
            if (wxOrderTemp != null) {
                wxOrderService.saveWxOrder(wxOrderTemp);
            }
        }
    }

    /*@Override
    public void checkOnline() throws JDOMException, IOException {
        for (WxOrderVo wxOrderVo : VoteServiceImpl.currWxOrderVo.values()) {
            logger.info("订单号发起轮询查询:" + wxOrderVo.getMerchantOrder());
            WxOrder wxOrder = dealwithOrder(wxOrderVo.getMerchantOrder(), wxOrderVo.getWxOrderId(), wxOrderVo.getPlayerId(), wxOrderVo.getAmount());
            if (wxOrder == null) continue;
            if (wxOrder.getIsPay()) {
                wxOrderVo.setPayStatus(wxOrder.getPayStatus());
                wxOrderService.sendWxOrderVo(wxOrderVo);
                wxOrderService.saveWxOrder(wxOrder);
                VoteServiceImpl.currWxOrderVo.remove(wxOrderVo.getMerchantOrder());
            } else {
                Integer step = wxOrderVo.getStep();
                step = step == null ? 0 : step + 2;
                wxOrderVo.setStep(step);
                if (step > 60) {
                    wxOrderVo.setPayStatus("取消");
                    wxOrderService.sendWxOrderVo(wxOrderVo);
                    wxOrder.setIsPay(null);
                    wxOrderService.saveWxOrder(wxOrder);
                    VoteServiceImpl.currWxOrderVo.remove(wxOrderVo.getMerchantOrder());
                }
            }
        }
    }*/

    private WxOrder dealwithOrder(String merchantOrder, Integer wxOrderId, BigDecimal amount) throws JDOMException, IOException {
        WxOrder wxOrderTemp = new WxOrder();
        wxOrderTemp.setMerchantOrder(merchantOrder);
        Integer stateId = checkOrderFromWx(wxOrderTemp);
        //解析并修改订单状态
        if (stateId > -1) {
            wxOrderTemp.setId(wxOrderId);
            wxOrderTemp.setIsPay(false);
            wxOrderTemp.setPayStatus("取消");
            if (stateId == 1) {
                wxOrderTemp.setIsPay(true);
                wxOrderTemp.setPayStatus("已支付");
                Integer tickets = amount.intValue() * 3;
                /*playerService.addVoting(playerId, tickets);
                playerService.addGiftCount(playerId, amount);*/
            }
            return wxOrderTemp;
        }
        return null;
    }

    private Integer checkOrderFromWx(WxOrder wxOrder) throws JDOMException, IOException {
        String nonce_str = create_nonce_str();
        SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
        ConfigUtil.commonParams(packageParams);
        packageParams.put("appid", appID);
        packageParams.put("mch_id", mchID);
        packageParams.put("nonce_str", nonce_str);// 随机字符串
        packageParams.put("out_trade_no", wxOrder.getMerchantOrder());// 商户订单号
        String sign = PayCommonUtil.createSign("UTF-8", packageParams, apiKey);
        packageParams.put("sign", sign);// 签名
        logger.info(packageParams.toString());
        String requestXML = PayCommonUtil.getRequestXml(packageParams);
        String resXml = HttpUtil.postData(ConfigUtil.CHECK_ORDER_URL, requestXML);
        logger.info(resXml);
        Map map = XMLUtil.doXMLParse(resXml);
        String returnCode = (String) map.get("return_code");
        String returnMsg = (String) map.get("return_msg");
        StringBuffer url = new StringBuffer();
        ValueOperations<String, PayVo> ops = redisTemplate.opsForValue();
        if ("SUCCESS".equals(returnCode)) {
            String resultCode = (String) map.get("result_code");
            String errCodeDes = (String) map.get("err_code_des");
            if ("SUCCESS".equals(resultCode)) {
                //获取预支付交易会话标识
                String trade_state = (String) map.get("trade_state");
                trade_state = trade_state.toUpperCase();
                SortedMap<Object, Object> finalpackage = new TreeMap<Object, Object>();
                String timestamp = DateUtil.getTimestamp();
                finalpackage.put("timeStamp", timestamp);
                finalpackage.put("appId", appID);
                finalpackage.put("mch_id", mchID);
                finalpackage.put("out_trade_no", wxOrder.getMerchantOrder());
                wxOrder.setRemark(trade_state);
                logger.info("订单状态查询,订单号为:" + wxOrder.getMerchantOrder() + ";支付状态为:" + trade_state);
                if ("SUCCESS".equals(trade_state)) {
                    finalpackage.put("device_info", (String) map.get("device_info"));
                    finalpackage.put("openid", (String) map.get("openid"));
                    finalpackage.put("is_subscribe", (String) map.get("is_subscribe"));
                    finalpackage.put("trade_type", (String) map.get("trade_type"));
                    finalpackage.put("bank_type", (String) map.get("bank_type"));
                    finalpackage.put("total_fee", (String) map.get("total_fee"));
                    finalpackage.put("fee_type", (String) map.get("fee_type"));
                    finalpackage.put("transaction_id", (String) map.get("transaction_id"));
                    finalpackage.put("attach", (String) map.get("attach"));
                    finalpackage.put("time_end", (String) map.get("time_end"));
                    finalpackage.put("trade_state_desc", (String) map.get("trade_state_desc"));
                    logger.info("支付成功订单返回信息:" + finalpackage.toString());
                    return 1;
                } else if ("USERPAYING".equals(trade_state)) {
                    logger.info("支付中返回信息:" + finalpackage.toString());
                    return -1;
                } else {
                    finalpackage.put("trade_state", trade_state);
                    logger.info("支付其他状态返回信息:" + finalpackage.toString());
                    return 0;
                }
            } else {
                logger.info("订单号:{}错误信息:{}", wxOrder.getMerchantOrder(), errCodeDes);
                wxOrder.setRemark(errCodeDes);
                return 0;
            }
        } else {
            logger.info("订单号:{}错误信息:{}", wxOrder.getMerchantOrder(), returnMsg);
            wxOrder.setRemark(returnMsg);
            return 0;
        }
    }


    public String getJsapiTicket(String accesstoken) throws Exception {
        String jsapiTicket = "";
        Long nowDate = (new Date()).getTime();
        if (dataMap != null && dataMap.get("jsapiTicket") != null
                && dataMap.get("ticketTime") != null
                && (nowDate - Long.parseLong(String.valueOf(dataMap.get("ticketTime"))) < time * 1000)) {
            jsapiTicket = (String) dataMap.get("jsapiTicket");
        } else {
            String reqUrl = jsapiTicketUrl.replace("ACCESSTOKEN", accesstoken);
            System.out.println("jsapiReqUrl:" + reqUrl);
            JSONObject dataJson = JSONObject.parseObject(doGet(reqUrl));
            System.out.println("jsapiTicket:" + dataJson.toJSONString());
            dataMap.put("jsapiTicket", dataJson.getString("ticket"));
            dataMap.put("ticketTime", (new Date()).getTime() + "");
            System.out.println("time:" + (new Date()).getTime());
            jsapiTicket = (String) dataMap.get("jsapiTicket");
        }
        return jsapiTicket;
    }

    public String getToken() throws Exception {
        String accessToken = "";
        Long nowDate = (new Date()).getTime();
        if (dataMap != null && dataMap.get("accessToken") != null
                && dataMap.get("tokenTime") != null
                && (nowDate - Long.parseLong(String.valueOf(dataMap.get("tokenTime"))) < time * 1000)) {
            accessToken = (String) dataMap.get("accessToken");
        } else {
            String reqUrl = accessTokeUrl.replace("APPID", appID).replace("APPSECRET", appSecret);
            System.out.println("reqUrl:" + reqUrl);
            JSONObject dataJson = JSONObject.parseObject(doGet(reqUrl));
            System.out.println("accessToken:" + dataJson);
            dataMap.put("accessToken", dataJson.getString("access_token"));
            dataMap.put("tokenTime", (new Date()).getTime() + "");
            accessToken = (String) dataMap.get("accessToken");
        }
        return accessToken;
    }

    public String doGet(String url) throws Exception {
        URL localURL = new URL(url);
        URLConnection connection = localURL.openConnection();
        HttpURLConnection httpURLConnection = (HttpURLConnection) connection;
        httpURLConnection.setRequestProperty("Accept-Charset", "utf-8");
        httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        InputStream inputStream = null;
        InputStreamReader inputStreamReader = null;
        BufferedReader reader = null;
        StringBuffer resultBuffer = new StringBuffer();
        String tempLine = null;
        if (httpURLConnection.getResponseCode() >= 300) {
            throw new Exception("HTTP Request is not success, Response code is " + httpURLConnection.getResponseCode());
        }
        try {
            inputStream = httpURLConnection.getInputStream();
            inputStreamReader = new InputStreamReader(inputStream);
            reader = new BufferedReader(inputStreamReader);

            while ((tempLine = reader.readLine()) != null) {
                resultBuffer.append(tempLine);
            }
        } finally {
            if (reader != null) {
                reader.close();
            }
            if (inputStreamReader != null) {
                inputStreamReader.close();
            }
            if (inputStream != null) {
                inputStream.close();
            }
        }
        return resultBuffer.toString();
    }

    private String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash) {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }

    private String create_nonce_str() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    private String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }
}

实体类

package com.youruan.examine.entity.vo;

/**
 * 描述类的功能
 *
 * @author zhy
 * @date 2019-01-17 10:38
 * @description
 * @see [相关类/方法]
 * @since V1.0.0
 */
public class PayVo {

    private String state;
    private String timestamp;
    private String nonceStr;
    private String packages;
    private String signType;
    private String sign;
    private String appId;
    private String orderNo;
    private String totalFee;
    private String url;
    private String message;

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(String timestamp) {
        this.timestamp = timestamp;
    }

    public String getNonceStr() {
        return nonceStr;
    }

    public void setNonceStr(String nonceStr) {
        this.nonceStr = nonceStr;
    }

    public String getPackages() {
        return packages;
    }

    public void setPackages(String packages) {
        this.packages = packages;
    }

    public String getSignType() {
        return signType;
    }

    public void setSignType(String signType) {
        this.signType = signType;
    }

    public String getSign() {
        return sign;
    }

    public void setSign(String sign) {
        this.sign = sign;
    }

    public String getAppId() {
        return appId;
    }

    public void setAppId(String appId) {
        this.appId = appId;
    }

    public String getOrderNo() {
        return orderNo;
    }

    public void setOrderNo(String orderNo) {
        this.orderNo = orderNo;
    }

    public String getTotalFee() {
        return totalFee;
    }

    public void setTotalFee(String totalFee) {
        this.totalFee = totalFee;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

package com.youruan.examine.entity.vo;

import com.youruan.examine.entity.WxOrder;

public class WxOrderVo extends WxOrder{

    /**
     * 用户ID
     */
    private Integer userId;

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }
}
package com.youruan.examine.entity;

import tk.mybatis.mapper.annotation.KeySql;

import java.math.BigDecimal;
import java.util.Date;
import javax.persistence.*;

@Table(name = "wx_order")
public class WxOrder {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @KeySql(useGeneratedKeys = true)
    private Integer id;

    /**
     * openId
     */
    @Column(name = "open_id")
    private String openId;

    /**
     * 订单号
     */
    @Column(name = "order_id")
    private String orderId;

    /**
     * 商户订单号
     */
    @Column(name = "merchant_order")
    private String merchantOrder;

    /**
     * ip地址
     */
    @Column(name = "client_ip")
    private String clientIp;

    /**
     * 购买时间
     */
    @Column(name = "order_time")
    private Date orderTime;

    /**
     * 金额
     */
    private BigDecimal amount;

    /**
     * 是否支付;0:否,1:是
     */
    @Column(name = "is_pay")
    private Boolean isPay;

    /**
     * 支付状态
     */
    @Column(name = "pay_status")
    private String payStatus;

    /**
     * 备注
     */
    private String remark;

    /**
     * 备用字段1
     */
    @Column(name = "column_1")
    private String column1;

    /**
     * 备用字段2
     */
    @Column(name = "column_2")
    private String column2;

    /**
     * @return id
     */
    public Integer getId() {
        return id;
    }

    /**
     * @param id
     */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
     * 获取openId
     *
     * @return open_id - openId
     */
    public String getOpenId() {
        return openId;
    }

    /**
     * 设置openId
     *
     * @param openId openId
     */
    public void setOpenId(String openId) {
        this.openId = openId;
    }

    /**
     * 获取订单号
     *
     * @return order_id - 订单号
     */
    public String getOrderId() {
        return orderId;
    }

    /**
     * 设置订单号
     *
     * @param orderId 订单号
     */
    public void setOrderId(String orderId) {
        this.orderId = orderId;
    }

    /**
     * 获取商户订单号
     *
     * @return merchant_order - 商户订单号
     */
    public String getMerchantOrder() {
        return merchantOrder;
    }

    /**
     * 设置商户订单号
     *
     * @param merchantOrder 商户订单号
     */
    public void setMerchantOrder(String merchantOrder) {
        this.merchantOrder = merchantOrder;
    }

    /**
     * 获取ip地址
     *
     * @return client_ip - ip地址
     */
    public String getClientIp() {
        return clientIp;
    }

    /**
     * 设置ip地址
     *
     * @param clientIp ip地址
     */
    public void setClientIp(String clientIp) {
        this.clientIp = clientIp;
    }

    /**
     * 获取购买时间
     *
     * @return order_time - 购买时间
     */
    public Date getOrderTime() {
        return orderTime;
    }

    /**
     * 设置购买时间
     *
     * @param orderTime 购买时间
     */
    public void setOrderTime(Date orderTime) {
        this.orderTime = orderTime;
    }

    /**
     * 获取金额
     *
     * @return amount - 金额
     */
    public BigDecimal getAmount() {
        return amount;
    }

    /**
     * 设置金额
     *
     * @param amount 金额
     */
    public void setAmount(BigDecimal amount) {
        this.amount = amount;
    }

    /**
     * 获取是否支付;0:否,1:是
     *
     * @return is_pay - 是否支付;0:否,1:是
     */
    public Boolean getIsPay() {
        return isPay;
    }

    /**
     * 设置是否支付;0:否,1:是
     *
     * @param isPay 是否支付;0:否,1:是
     */
    public void setIsPay(Boolean isPay) {
        this.isPay = isPay;
    }

    /**
     * 获取支付状态
     *
     * @return pay_status - 支付状态
     */
    public String getPayStatus() {
        return payStatus;
    }

    /**
     * 设置支付状态
     *
     * @param payStatus 支付状态
     */
    public void setPayStatus(String payStatus) {
        this.payStatus = payStatus;
    }

    /**
     * 获取备注
     *
     * @return remark - 备注
     */
    public String getRemark() {
        return remark;
    }

    /**
     * 设置备注
     *
     * @param remark 备注
     */
    public void setRemark(String remark) {
        this.remark = remark;
    }

    /**
     * 获取备用字段1
     *
     * @return column_1 - 备用字段1
     */
    public String getColumn1() {
        return column1;
    }

    /**
     * 设置备用字段1
     *
     * @param column1 备用字段1
     */
    public void setColumn1(String column1) {
        this.column1 = column1;
    }

    /**
     * 获取备用字段2
     *
     * @return column_2 - 备用字段2
     */
    public String getColumn2() {
        return column2;
    }

    /**
     * 设置备用字段2
     *
     * @param column2 备用字段2
     */
    public void setColumn2(String column2) {
        this.column2 = column2;
    }
}

util

package com.youruan.examine.util.mobile;

import com.google.gson.Gson;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import javax.servlet.http.HttpServletRequest;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 微信H5支付工具类
 * 创建者 zhy
 * 创建时间	2017年7月31日
 */
public class MobileUtil {

    /**
     * 获取用户openID
     *
     * @param code
     *
     * @return String
     *
     * @Author zhy
     * @Date 2017年7月31日 更新日志
     * 2017年7月31日  zhy 首次创建
     */
    public static String getOpenId(String code, String appId, String secret) {
        if (code != null) {
            String url = "https://api.weixin.qq.com/sns/oauth2/access_token?"
                    + "appid=" + appId
                    + "&secret=" + secret + "&code="
                    + code + "&grant_type=authorization_code";
            String returnData = getReturnData(url);
            Gson gson = new Gson();
            OpenIdClass openIdClass = gson.fromJson(returnData,
                    OpenIdClass.class);
            if (openIdClass.getOpenid() != null) {
                return openIdClass.getOpenid();
            }
        }
        return "**************";
    }

    public static String getReturnData(String urlString) {
        String res = "";
        try {
            URL url = new URL(urlString);
            java.net.HttpURLConnection conn = (java.net.HttpURLConnection) url
                    .openConnection();
            conn.connect();
            java.io.BufferedReader in = new java.io.BufferedReader(
                    new java.io.InputStreamReader(conn.getInputStream(),
                            "UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                res += line;
            }
            in.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return res;
    }

    /**
     * 回调request 参数解析为map格式
     *
     * @param request
     *
     * @return
     *
     * @throws Exception Map<String,String>
     * @Author zhy
     * @Date 2017年7月31日 更新日志
     * 2017年7月31日  zhy 首次创建
     */
    @SuppressWarnings("unchecked")
    public static Map<String, String> parseXml(HttpServletRequest request)
            throws Exception {
        // 解析结果存储在HashMap
        Map<String, String> map = new HashMap<String, String>();
        InputStream inputStream = request.getInputStream();
        // 读取输入流
        SAXReader reader = new SAXReader();
        Document document = reader.read(inputStream);
        // 得到xml根元素
        Element root = document.getRootElement();
        // 得到根元素的所有子节点
        List<Element> elementList = root.elements();
        // 遍历所有子节点
        for (Element e : elementList)
            map.put(e.getName(), e.getText());
        // 释放资源
        inputStream.close();
        inputStream = null;
        return map;
    }
}

package com.youruan.examine.util.mobile;

/**
 * 微信用户信息
 * 创建者 zhy
 * 创建时间	2017年7月31日
 */
public class OpenIdClass {

    private String access_token;
    private String expires_in;
    private String refresh_token;
    private String openid;
    private String scope;
    private String unionid;

    public String getAccess_token() {
        return access_token;
    }

    public void setAccess_token(String access_token) {
        this.access_token = access_token;
    }

    public String getExpires_in() {
        return expires_in;
    }

    public void setExpires_in(String expires_in) {
        this.expires_in = expires_in;
    }

    public String getRefresh_token() {
        return refresh_token;
    }

    public void setRefresh_token(String refresh_token) {
        this.refresh_token = refresh_token;
    }

    public String getOpenid() {
        return openid;
    }

    public void setOpenid(String openid) {
        this.openid = openid;
    }

    public String getScope() {
        return scope;
    }

    public void setScope(String scope) {
        this.scope = scope;
    }

    public String getUnionid() {
        return unionid;
    }

    public void setUnionid(String unionid) {
        this.unionid = unionid;
    }

    public String getErrcode() {
        return errcode;
    }

    public void setErrcode(String errcode) {
        this.errcode = errcode;
    }

    public String getErrmsg() {
        return errmsg;
    }

    public void setErrmsg(String errmsg) {
        this.errmsg = errmsg;
    }

    private String errcode;
    private String errmsg;
}

package com.youruan.examine.util;

import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * 根据IP地址获取详细的地域信息
 * 创建者 zhy
 * 创建时间	2017年7月31日
 */
public class AddressUtils {

    /**
     * content
     * 请求的参数 格式为:name=xxx&pwd=xxx
     * encoding
     * 服务器端请求编码。如GBK,UTF-8等
     *
     * @return
     *
     * @throws UnsupportedEncodingException
     */
    public static String getAddresses(String ip) throws UnsupportedEncodingException {
        String urlStr = "http://ip.taobao.com/service/getIpInfo.php";
        String returnStr = getResult(urlStr, ip);
        if (returnStr != null) {
            // 处理返回的省市区信息
            String[] temp = returnStr.split(",");
            if (temp.length < 3) {
                return "0";// 无效IP,局域网测试
            }
            String region = (temp[5].split(":"))[1].replaceAll("\"", "");
            region = decodeUnicode(region);// 省份

            String country = "";
            String area = "";
            // String region = "";
            String city = "";
            String county = "";
            String isp = "";
            for (int i = 0; i < temp.length; i++) {
                switch (i) {
                    case 1:
                        country = (temp[i].split(":"))[2].replaceAll("\"", "");
                        country = decodeUnicode(country);// 国家
                        break;
                    case 3:
                        area = (temp[i].split(":"))[1].replaceAll("\"", "");
                        area = decodeUnicode(area);// 地区
                        break;
                    case 5:
                        region = (temp[i].split(":"))[1].replaceAll("\"", "");
                        region = decodeUnicode(region);// 省份
                        break;
                    case 7:
                        city = (temp[i].split(":"))[1].replaceAll("\"", "");
                        city = decodeUnicode(city);// 市区
                        break;
                    case 9:
                        county = (temp[i].split(":"))[1].replaceAll("\"", "");
                        county = decodeUnicode(county);// 地区
                        break;
                    case 11:
                        isp = (temp[i].split(":"))[1].replaceAll("\"", "");
                        isp = decodeUnicode(isp); // ISP公司
                        break;
                }
            }
            String address = region + city;
            if (StringUtils.isBlank(address)) {
                address = "地球村";
            }
            return address;
        }
        return null;
    }

    /**
     * @param urlStr 请求的地址
     *               content
     *               请求的参数 格式为:name=xxx&pwd=xxx
     *               encoding
     *               服务器端请求编码。如GBK,UTF-8等
     *
     * @return
     */
    private static String getResult(String urlStr, String ip) {
        URL url = null;
        HttpURLConnection connection = null;
        try {
            url = new URL(urlStr);
            connection = (HttpURLConnection) url.openConnection();// 新建连接实例
            /**
             * 超时错误 由 2s改为5s
             */
            connection.setConnectTimeout(5000);// 设置连接超时时间,单位毫秒
            connection.setReadTimeout(5000);// 设置读取数据超时时间,单位毫秒
            connection.setDoOutput(true);// 是否打开输出流 true|false
            connection.setDoInput(true);// 是否打开输入流true|false
            connection.setRequestMethod("POST");// 提交方法POST|GET
            connection.setUseCaches(false);// 是否缓存true|false
            connection.connect();// 打开连接端口
            DataOutputStream out = new DataOutputStream(connection.getOutputStream());// 打开输出流往对端服务器写数据
            out.writeBytes("ip=" + ip);// 写数据,也就是提交你的表单 name=xxx&pwd=xxx
            out.flush();// 刷新
            out.close();// 关闭输出流
            BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "utf-8"));// 往对端写完数据对端服务器返回数据
            // ,以BufferedReader流来读取
            StringBuffer buffer = new StringBuffer();
            String line = "";
            while ((line = reader.readLine()) != null) {
                buffer.append(line);
            }
            reader.close();
            return buffer.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (connection != null) {
                connection.disconnect();// 关闭连接
            }
        }
        return null;
    }

    /**
     * unicode 转换成 中文
     *
     * @param theString
     *
     * @return
     */
    public static String decodeUnicode(String theString) {
        char aChar;
        int len = theString.length();
        StringBuffer outBuffer = new StringBuffer(len);
        for (int x = 0; x < len; ) {
            aChar = theString.charAt(x++);
            if (aChar == '\\') {
                aChar = theString.charAt(x++);
                if (aChar == 'u') {
                    int value = 0;
                    for (int i = 0; i < 4; i++) {
                        aChar = theString.charAt(x++);
                        switch (aChar) {
                            case '0':
                            case '1':
                            case '2':
                            case '3':
                            case '4':
                            case '5':
                            case '6':
                            case '7':
                            case '8':
                            case '9':
                                value = (value << 4) + aChar - '0';
                                break;
                            case 'a':
                            case 'b':
                            case 'c':
                            case 'd':
                            case 'e':
                            case 'f':
                                value = (value << 4) + 10 + aChar - 'a';
                                break;
                            case 'A':
                            case 'B':
                            case 'C':
                            case 'D':
                            case 'E':
                            case 'F':
                                value = (value << 4) + 10 + aChar - 'A';
                                break;
                            default:
                                throw new IllegalArgumentException("Malformed      encoding.");
                        }
                    }
                    outBuffer.append((char) value);
                } else {
                    if (aChar == 't') {
                        aChar = '\t';
                    } else if (aChar == 'r') {
                        aChar = '\r';
                    } else if (aChar == 'n') {
                        aChar = '\n';
                    } else if (aChar == 'f') {
                        aChar = '\f';
                    }
                    outBuffer.append(aChar);
                }
            } else {
                outBuffer.append(aChar);
            }
        }
        return outBuffer.toString();
    }

    /**
     * 获取IP地址
     *
     * @param request
     *
     * @return String
     *
     * @Author zhy
     * @Date 2017年7月31日 更新日志
     * 2017年7月31日  zhy 首次创建
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("X-Real-IP");
        if (!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
            return ip;
        }
        ip = request.getHeader("X-Forwarded-For");
        if (!StringUtils.isBlank(ip) && !"unknown".equalsIgnoreCase(ip)) {
            int index = ip.indexOf(',');
            if (index != -1) {
                return ip.substring(0, index);
            } else {
                return ip;
            }
        }
        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;
    }
}  

package com.youruan.examine.util;


import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.UUID;

public class CommonUtil {

    /**
     * 用UUID生成十六位数唯一订单号
     * @return
     */
    public static String getOrderNumByUUId() {
        int machineId = 1;//最大支持1-9个集群机器部署
        int hashCodeV = UUID.randomUUID().toString().hashCode();
        if(hashCodeV < 0) {//有可能是负数
            hashCodeV = - hashCodeV;
        }
//         0 代表前面补充0
//         4 代表长度为4
//         d 代表参数为正数型
        return  machineId + String.format("%015d", hashCodeV);
    }

    /**
     * 判断一个对象中属性是否全 为空或空字符串
     * @param obj
     * @return
     * @throws IllegalAccessException
     */
    public  static boolean checkObjFieldIsNull(Object obj) throws IllegalAccessException {
        boolean flag = true;
        for(Field f : obj.getClass().getDeclaredFields()){
            f.setAccessible(true);
            //log.info(f.getName());
            if(f.get(obj) != null || !f.get(obj).equals("")){
                flag = false;
                return flag;
            }
        }
        return flag;
    }


    public static String httpRequest(String requestUrl, String requestMethod, String outputStr) {
        StringBuffer buffer = new StringBuffer();
        try {
            URL url = new URL(requestUrl);
            HttpURLConnection httpUrlConn = (HttpURLConnection) url.openConnection();
            httpUrlConn.setDoOutput(true);
            httpUrlConn.setDoInput(true);
            httpUrlConn.setUseCaches(false);
            // 设置请求方式(GET/POST)
            httpUrlConn.setRequestMethod(requestMethod);
            if ("GET".equalsIgnoreCase(requestMethod)) {
                httpUrlConn.connect();
            }
            // 当有数据需要提交时
            if (null != outputStr) {
                OutputStream outputStream = httpUrlConn.getOutputStream();
                // 注意编码格式,防止中文乱码
                outputStream.write(outputStr.getBytes("UTF-8"));
                outputStream.close();
            }
            // 将返回的输入流转换成字符串
            InputStream inputStream = httpUrlConn.getInputStream();
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
            String str = null;
            while ((str = bufferedReader.readLine()) != null) {
                buffer.append(str);
            }
            bufferedReader.close();
            inputStreamReader.close();
            // 释放资源
            inputStream.close();
            inputStream = null;
            httpUrlConn.disconnect();
            //jsonObject = JSONObject.fromObject(buffer.toString());
        } catch (ConnectException ce) {
            ce.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return buffer.toString();
    }

    /**
     * 使用java正则表达式去掉多余的.与0
     *
     * @param s
     *
     * @return
     */
    public static String subZeroAndDot(String s) {
        if (s.indexOf(".") > 0) {
            s = s.replaceAll("0+?$", "");// 去掉多余的0
            s = s.replaceAll("[.]$", "");// 如最后一位是.则去掉
        }
        return s;
    }
}

package com.youruan.examine.util;

import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;

import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * 相关配置参数
 * 创建者 zhy
 * 创建时间 2017年7月31日
 */
public class ConfigUtil {

    private static Configuration configs;
    public static String APP_ID;// 服务号的应用ID
    public static String APP_SECRET;// 服务号的应用密钥
    public static String TOKEN;// 服务号的配置token
    public static String MCH_ID;// 商户号
    public static String API_KEY;// API密钥
    public static String SIGN_TYPE;// 签名加密方式
    public static String CERT_PATH;//微信支付证书
    public static String TOKEN_KEY = "TOKEN_KEY";

    public static synchronized void init(String filePath) {
        if (configs != null) {
            return;
        }
        try {
            configs = new PropertiesConfiguration(filePath);
        } catch (ConfigurationException e) {
            e.printStackTrace();
        }

        if (configs == null) {
            throw new IllegalStateException("can`t find file by path:"
                    + filePath);
        }
        APP_ID = configs.getString("APP_ID");
        APP_SECRET = configs.getString("APP_SECRET");
        TOKEN = configs.getString("TOKEN");
        MCH_ID = configs.getString("MCH_ID");
        API_KEY = configs.getString("API_KEY");
        SIGN_TYPE = configs.getString("SIGN_TYPE");
        CERT_PATH = configs.getString("CERT_PATH");
    }

    /**
     * 微信基础接口地址
     */
    private String ACCESS_TOKEURL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
    //微信分享
    private String JSP_API_TICKEURL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESSTOKEN&type=jsapi";
    // 获取token接口(GET)
    public final static String TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
    // oauth2授权接口(GET)
    public final static String OAUTH2_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code";
    // 刷新access_token接口(GET)
    public final static String REFRESH_TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=APPID&grant_type=refresh_token&refresh_token=REFRESH_TOKEN";
    // 菜单创建接口(POST)
    public final static String MENU_CREATE_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
    // 菜单查询(GET)
    public final static String MENU_GET_URL = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN";
    // 菜单删除(GET)
    public final static String MENU_DELETE_URL = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN";
    /**
     * 微信支付接口地址
     */
    // 微信支付统一接口(POST)
    public final static String UNIFIED_ORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    // 微信退款接口(POST)
    public final static String REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund";
    // 订单查询接口(POST)
    public final static String CHECK_ORDER_URL = "https://api.mch.weixin.qq.com/pay/orderquery";
    // 关闭订单接口(POST)
    public final static String CLOSE_ORDER_URL = "https://api.mch.weixin.qq.com/pay/closeorder";
    // 退款查询接口(POST)
    public final static String CHECK_REFUND_URL = "https://api.mch.weixin.qq.com/pay/refundquery";
    // 对账单接口(POST)
    public final static String DOWNLOAD_BILL_URL = "https://api.mch.weixin.qq.com/pay/downloadbill";
    // 短链接转换接口(POST)
    public final static String SHORT_URL = "https://api.mch.weixin.qq.com/tools/shorturl";
    // 接口调用上报接口(POST)
    public final static String REPORT_URL = "https://api.mch.weixin.qq.com/payitil/report";

    /**
     * 基础参数
     *
     * @param packageParams void
     *
     * @Author zhy
     * @Date 2017年7月31日 更新日志
     * 2017年7月31日  zhy 首次创建
     */
    public static void commonParams(SortedMap<Object, Object> packageParams) {
        // 账号信息
        String appid = ConfigUtil.APP_ID; // appid
        String mch_id = ConfigUtil.MCH_ID; // 商业号
        // 生成随机字符串
        String currTime = PayCommonUtil.getCurrTime();
        String strTime = currTime.substring(8, currTime.length());
        String strRandom = PayCommonUtil.buildRandom(4) + "";
        String nonce_str = strTime + strRandom;
        packageParams.put("appid", appid);// 公众账号ID
        packageParams.put("mch_id", mch_id);// 商户号
        packageParams.put("nonce_str", nonce_str);// 随机字符串
    }

    /**
     * 该接口主要用于扫码原生支付模式一中的二维码链接转成短链接(weixin://wxpay/s/XXXXXX),减小二维码数据量,提升扫描速度和精确度
     *
     * @param urlCode void
     *
     * @Author zhy
     * @Date 2017年7月31日 更新日志
     * 2017年7月31日  zhy 首次创建
     */
    @SuppressWarnings("rawtypes")
    public static void shorturl(String urlCode) {
        try {
            String key = ConfigUtil.API_KEY; // key
            SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
            ConfigUtil.commonParams(packageParams);
            packageParams.put("long_url", urlCode);// URL链接
            String sign = PayCommonUtil.createSign("UTF-8", packageParams, key);
            packageParams.put("sign", sign);// 签名
            String requestXML = PayCommonUtil.getRequestXml(packageParams);
            String resXml = HttpUtil.postData(ConfigUtil.SHORT_URL, requestXML);
            Map map = XMLUtil.doXMLParse(resXml);
            String returnCode = (String) map.get("return_code");
            if ("SUCCESS".equals(returnCode)) {
                String resultCode = (String) map.get("return_code");
                if ("SUCCESS".equals(resultCode)) {
                    urlCode = (String) map.get("short_url");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
package com.youruan.examine.util;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 说明: 日期时间工具类
 */
public class DateUtil {

    private static Logger log = LoggerFactory.getLogger(DateUtil.class);

    public static final String PATTERN_YM = "yyyy-MM"; // pattern_ym
    public static final int PATTERN_YM_LENGTH = 7;

    public static final String PATTERN_YMD = "yyyy-MM-dd"; // pattern_ymd
    public static final int PATTERN_YMD_LENGTH = 10;

    public static final String PATTERN_YMD_HM = "yyyy-MM-dd HH:mm"; // pattern_ymd hm
    public static final int PATTERN_YMD_HM_LENGTH = 16;

    public static final String PATTERN_YMD_HMS = "yyyy-MM-dd HH:mm:ss"; // pattern_ymd time
    public static final int PATTERN_YMD_HMS_LENGTH = 19;

    public static final String PATTERN_YMD_HMS_S = "yyyy-MM-dd HH:mm:ss:SSS"; // pattern_ymd timeMillisecond
    public static final int PATTERN_YMD_HMS_S_LENGTH = 23;

    public static final String PATTERN_YMDHMS = "yyyyMMddHHmmss";

    /**
     * 返回年份
     *
     * @param date 日期
     *
     * @return 返回年份
     */
    public static int getYear(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return c.get(Calendar.YEAR);
    }

    /**
     * 返回 年 月  日
     */
    public static Map<String, Object> getDateMsg(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        Map<String, Object> map = new HashMap<>();
        map.put("year", calendar.get(Calendar.YEAR));
        map.put("month", calendar.get(Calendar.MONTH));
        map.put("day", calendar.get(Calendar.DAY_OF_MONTH));
        return map;
    }

    /**
     * 格式化
     *
     * @param date
     * @param pattern
     *
     * @return
     */
    public static String format(Date date, String pattern) {
        DateFormat format = new SimpleDateFormat(pattern);
        return format.format(date);
    }

    /**
     * 格式化
     *
     * @param date
     * @param pattern
     * @param timeZone
     *
     * @return
     */
    public static String format(Date date, String pattern, TimeZone timeZone) {
        DateFormat format = new SimpleDateFormat(pattern);
        format.setTimeZone(timeZone);
        return format.format(date);
    }

    /**
     * 格式化
     *
     * @param date
     * @param parsePattern
     * @param returnPattern
     *
     * @return
     */
    public static String format(String date, String parsePattern, String returnPattern) {
        return format(parse(date, parsePattern), returnPattern);
    }

    /**
     * 格式化
     *
     * @param date
     * @param parsePattern
     * @param returnPattern
     * @param timeZone
     *
     * @return
     */
    public static String format(String date, String parsePattern, String returnPattern, TimeZone timeZone) {
        return format(parse(date, parsePattern), returnPattern, timeZone);
    }

    /**
     * 时间戳转时间
     */
    public static Date timeToDate(Date date, String format) {
        if (date == null) {
            return null;
        }
        if (StringUtils.isBlank(format)) {
            format = "yyyy-MM-dd";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        String str = sdf.format(date.getTime());
        return sdf.parse(str, new ParsePosition(1));
    }

    /**
     * 解析
     *
     * @param date
     * @param pattern
     *
     * @return
     */
    public static Date parse(String date, String pattern) {
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        try {
            return format.parse(date);
        } catch (ParseException e) {
            log.error("ToolDateTime.parse异常:date值" + date + ",pattern值" + pattern);
            return null;
        }
    }

    /**
     * 解析
     *
     * @param date
     *
     * @return
     */
    public static Date parse(String date) {
        return parse(date, PATTERN_YMD_HMS);
    }

    /**
     * 解析
     *
     * @param date
     *
     * @return
     */
    public static Date parseYearAndDay(String date) {
        return parse(date, PATTERN_YMD);
    }

    /**
     * 两个日期的时间差,返回"X天X小时X分X秒"
     *
     * @param start
     * @param end
     *
     * @return
     */
    public static String getBetween(Date start, Date end) {
        long between = (end.getTime() - start.getTime()) / 1000;// 除以1000是为了转换成秒
        long day = between / (24 * 3600);
        long hour = between % (24 * 3600) / 3600;
        long minute = between % 3600 / 60;
        long second = between % 60 / 60;
        String sb = String.valueOf(day) + "天" + hour + "小时" + minute + "分";//second + "秒";
        return sb;
    }

    /**
     * 返回两个日期之间隔了多少秒
     *
     * @param start
     * @param end
     *
     * @return
     */
    public static int getDateSecondSpace(Date start, Date end) {
        return (int) ((end.getTime() - start.getTime()) / (1000));
    }

    /**
     * 返回两个日期之间隔了多少分钟
     *
     * @param start
     * @param end
     *
     * @return
     */
    public static int getDateMinuteSpace(Date start, Date end) {
        return (int) ((end.getTime() - start.getTime()) / (60 * 1000));
    }

    /**
     * 返回两个日期之间隔了多少小时
     *
     * @param start
     * @param end
     *
     * @return
     */
    public static int getDateHourSpace(Date start, Date end) {
        return (int) ((end.getTime() - start.getTime()) / (60 * 60 * 1000));
    }

    /**
     * 返回两个日期之间隔了多少天
     *
     * @param start
     * @param end
     *
     * @return
     */
    public static int getDateDaySpace(Date start, Date end) {
        return (int) ((end.getTime() - start.getTime()) / (60 * 60 * 24 * 1000));
    }

    public static boolean isSameDate(Date date1, Date date2) {
        Calendar cal1 = Calendar.getInstance();
        cal1.setTime(date1);

        Calendar cal2 = Calendar.getInstance();
        cal2.setTime(date2);

        boolean isSameYear = cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR);
        boolean isSameMonth = isSameYear && cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH);
        boolean isSameDate = isSameMonth && cal1.get(Calendar.DAY_OF_MONTH) == cal2.get(Calendar.DAY_OF_MONTH);
        return isSameDate;
    }

    //根据日期取得星期几
    public static String getWeek(Date date) {
        String[] weeks = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        int weekIndex = cal.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY;
        if (weekIndex < 0) {
            weekIndex = 0;
        }
        return weeks[weekIndex];
    }

    /**
     * 返回两个日期之间隔了多少天,包含开始、结束时间
     *
     * @param start
     * @param end
     *
     * @return
     */
    public static List<String> getDaySpaceDate(Date start, Date end) {
        Calendar fromCalendar = Calendar.getInstance();
        fromCalendar.setTime(start);
        fromCalendar.set(Calendar.HOUR_OF_DAY, 0);
        fromCalendar.set(Calendar.MINUTE, 0);
        fromCalendar.set(Calendar.SECOND, 0);
        fromCalendar.set(Calendar.MILLISECOND, 0);

        Calendar toCalendar = Calendar.getInstance();
        toCalendar.setTime(end);
        toCalendar.set(Calendar.HOUR_OF_DAY, 0);
        toCalendar.set(Calendar.MINUTE, 0);
        toCalendar.set(Calendar.SECOND, 0);
        toCalendar.set(Calendar.MILLISECOND, 0);

        List<String> dateList = new LinkedList<>();

        long dayCount = (toCalendar.getTime().getTime() - fromCalendar.getTime().getTime()) / (1000 * 60 * 60 * 24);
        if (dayCount < 0) {
            return dateList;
        }

        dateList.add(format(fromCalendar.getTime(), PATTERN_YMD));

        for (int i = 0; i < dayCount; i++) {
            fromCalendar.add(Calendar.DATE, 1);// 增加一天
            dateList.add(format(fromCalendar.getTime(), PATTERN_YMD));
        }

        return dateList;
    }

    /**
     * 时间按年相加减
     * 正值相加
     * 负值相减
     */
    public static Date calcDateByYear(Date date, int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, year);
        return calendar.getTime();
    }

    /**
     * 时间按年天相加减
     * 正值相加
     * 负值相减
     */
    public static Date calcDateByDay(Date date, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, day);
        return calendar.getTime();
    }

    /**
     * 时间按小时相加减
     * 正值相加
     * 负值相减
     */
    public static Date calcDateByHour(Date date, int hour) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR, hour);
        return calendar.getTime();
    }

    /**
     * 时间按分相加减
     * 正值相加
     * 负值相减
     */
    public static Date calcDateByMinute(Date date, int minutes) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minutes);
        return calendar.getTime();
    }

    /**
     * 判断时间是否在时间段内
     */
    public static boolean compareDate(Date start, Date end, Date date) {
        return date.after(start) && date.before(end);
    }

    /**
     * 获取开始时间
     *
     * @param start
     * @param end
     *
     * @return
     */
    public static Date startDateByDay(Date start, int end) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(start);
        calendar.add(Calendar.DATE, end);// 明天1,昨天-1
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取结束时间
     *
     * @param start
     *
     * @return
     */
    public static Date endDateByDay(Date start) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(start);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    /**
     * 获取开始时间
     *
     * @param start
     * @param end
     *
     * @return
     */
    public static Date startDateByHour(Date start, int end) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(start);
        calendar.set(Calendar.MINUTE, end);
        return calendar.getTime();
    }

    /**
     * 获取结束时间
     *
     * @param end
     *
     * @return
     */
    public static Date endDateByHour(Date end) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(end);
        calendar.set(Calendar.SECOND, 59);
        calendar.set(Calendar.MILLISECOND, 999);
        return calendar.getTime();
    }

    public static void main(String[] args) {
        System.out.println(DateUtil.format(DateUtil.calcDateByYear(new Date(), 1), "yyyy-MM-dd HH:mm:ss"));
        System.out.println(DateUtil.format(DateUtil.calcDateByDay(new Date(), 1), "yyyy-MM-dd HH:mm:ss"));
        System.out.println(DateUtil.format(DateUtil.calcDateByHour(new Date(), 1), "yyyy-MM-dd HH:mm:ss"));

        System.out.println(DateUtil.format(DateUtil.calcDateByYear(new Date(), -1), "yyyy-MM-dd HH:mm:ss"));
        System.out.println(DateUtil.format(DateUtil.calcDateByDay(new Date(), -1), "yyyy-MM-dd HH:mm:ss"));
        System.out.println(DateUtil.format(DateUtil.calcDateByHour(new Date(), -1), "yyyy-MM-dd HH:mm:ss"));

        System.out.println(DateUtil.format(DateUtil.startDateByDay(new Date(), 0), "yyyy-MM-dd HH:mm:ss"));
        System.out.println(DateUtil.format(DateUtil.endDateByDay(new Date()), "yyyy-MM-dd HH:mm:ss"));

        System.out.println(DateUtil.getDateDaySpace(DateUtil.parse("2015-01-01", "yyyy-MM-dd"), new Date()));

        System.out.println(DateUtil.getDaySpaceDate(DateUtil.parse("2016-04-01 8:00:00", "yyyy-MM-dd HH:mm:ss"), new Date()));

        System.out.println(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));

        System.out.println(DateUtil.parse("2015-11-21 12:34:56", "yyyy-MM-dd HH:mm:ss"));
    }
    public static String getTimestamp() {
        return String.valueOf(System.currentTimeMillis() / 1000);
    }
}

package com.youruan.examine.util;

import okhttp3.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;

/**
 * 说明: http请求客户端
 * @Author zhangsanfeng
 *
 * new HttpUtil().url(url)
 * .data("token", "76AF8B201FEC")
 * .data("body", json.toJSONString())
 * .post();
 *
 * new HttpUtil().url(url)
 * .data("token", "76AF8B201FEC")
 * .file("image", fileRootPath)
 * .postMultipart();
 */
public class HttpUtil {

    private final static int CONNECT_TIMEOUT = 5000; // in milliseconds
    private final static String DEFAULT_ENCODING = "UTF-8";

    private static Logger log = LoggerFactory.getLogger(HttpUtil.class);
    private static final MediaType MEDIA_TYPE_PNG = MediaType.parse("image/png");
    private static final MediaType MEDIA_TYPE_JPG = MediaType.parse("image/jpg");

    private OkHttpClient.Builder httpClient = new OkHttpClient().newBuilder().connectTimeout(10, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS).writeTimeout(30, TimeUnit.SECONDS);
    private Request.Builder requestBuilder = new Request.Builder();
    private FormBody.Builder formBodyBuilder = new FormBody.Builder();
    private MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);

    private String url = "";
    private Map<String, String> headers = new LinkedHashMap<>();
    private Map<String, String> queryParas = new LinkedHashMap<>();
    private Map<String, String> files = new LinkedHashMap<>();

    public HttpUtil url(String url) {
        this.url = url;
        return this;
    }

    public HttpUtil data(String key, String value) {
        this.queryParas.put(key, value);
        return this;
    }

    public HttpUtil files(Map<String, String> files) {
        this.files.putAll(files);
        return this;
    }

    public HttpUtil file(String key, String value) {
        this.files.put(key, value);
        return this;
    }

    public HttpUtil header(String key, String value) {
        this.headers.put(key, value);
        return this;
    }

    public HttpUtil userAgent(String userAgent) {
        header("User-Agent", userAgent);
        return this;
    }

    public HttpUtil contentType(String contentType) {
        header("Content-Type", contentType);
        return this;
    }

    public HttpUtil acceptEncoding(String acceptEncoding) {
        header("Accept-Encoding", acceptEncoding);
        return this;
    }

    /**
     * Send POST request
     *
     * @throws IOException
     */
    public String post() throws IOException {
        if (StringUtils.isEmpty(url)) {
            log.error("URL为空");
            return "";
        }

        for (Entry<String, String> entry : queryParas.entrySet()) {
            formBodyBuilder.add(entry.getKey(), entry.getValue());
        }

        requestBuilder.url(url);
        for (Entry<String, String> entry : headers.entrySet()) {
            requestBuilder.addHeader(entry.getKey(), entry.getValue());
        }

        Request request = requestBuilder.post(formBodyBuilder.build()).build();
        Response response = httpClient.build().newCall(request).execute();

        if (!response.isSuccessful()) {
            throw new IOException("POST请求服务器端错误: " + response);
        }

        return response.body().string();
    }

    /**
     * Send GET request
     *
     * @throws IOException
     */
    public String get() throws IOException {
        if (StringUtils.isEmpty(url)) {
            log.error("URL为空");
            return "";
        }

        requestBuilder.url(buildUrlWithQueryString(url, queryParas));
        for (Entry<String, String> entry : headers.entrySet()) {
            requestBuilder.addHeader(entry.getKey(), entry.getValue());
        }

        Request request = requestBuilder.build();
        Response response = httpClient.build().newCall(request).execute();

        if (!response.isSuccessful()) {
            throw new IOException("GET请求服务器端错误: " + response);
        }

        return response.body().string();
    }

    /**
     * Send POST request
     *
     * @throws IOException
     */
    public String postMultipart() throws IOException {
        if (StringUtils.isEmpty(url)) {
            log.error("URL为空");
            return "";
        }

        for (Entry<String, String> entry : files.entrySet()) {
            File file = new File(entry.getValue());
            if (file.exists()) {
                multipartBodyBuilder.addFormDataPart(entry.getKey(), file.getName(), RequestBody.create(MEDIA_TYPE_PNG, file));
            } else {
                log.warn("待上传文件没有在磁盘上找到, filePath = " + entry.getValue());
            }
        }

        for (Entry<String, String> entry : queryParas.entrySet()) {
            multipartBodyBuilder.addFormDataPart(entry.getKey(), entry.getValue());
        }

        requestBuilder.url(url);
        for (Entry<String, String> entry : headers.entrySet()) {
            requestBuilder.addHeader(entry.getKey(), entry.getValue());
        }

        Request request = requestBuilder.post(multipartBodyBuilder.build()).build();
        Response response = httpClient.build().newCall(request).execute();

        if (!response.isSuccessful()) {
            throw new IOException("服务器端错误: url=" + this.url + ", response=" + response.toString());
        }

        return response.body().string();
    }

    /**
     * Build queryString of the url
     */
    private static String buildUrlWithQueryString(String url, Map<String, String> queryParas) {
        if (queryParas == null || queryParas.isEmpty()) {
            return url;
        }

        StringBuffer sb = new StringBuffer(url);
        boolean isFirst;
        if (!url.contains("?")) {
            isFirst = true;
            sb.append("?");
        } else {
            isFirst = false;
        }

        for (Entry<String, String> entry : queryParas.entrySet()) {
            if (isFirst) {
                isFirst = false;
            } else {
                sb.append("&");
            }

            String key = entry.getKey();
            String value = entry.getValue();
            if (StringUtils.isEmpty(value)) {
                try {
                    value = URLEncoder.encode(value, "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    throw new RuntimeException(e);
                }
            }
            sb.append(key).append("=").append(value);
        }
        return sb.toString();
    }

    //发送响应流方法
    public static void setResponseHeader(HttpServletResponse response, String fileName) {
        try {
            try {
                fileName = new String(fileName.getBytes(), "ISO8859-1");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            response.setContentType("application/octet-stream;charset=ISO8859-1");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.addHeader("Pargam", "no-cache");
            response.addHeader("Cache-Control", "no-cache");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    public static String postData(String urlStr, String data) {
        return postData(urlStr, data, null);
    }

    public static String postData(String urlStr, String data, String contentType) {
        BufferedReader reader = null;
        try {
            URL url = new URL(urlStr);
            URLConnection conn = url.openConnection();
            conn.setDoOutput(true);
            conn.setConnectTimeout(CONNECT_TIMEOUT);
            conn.setReadTimeout(CONNECT_TIMEOUT);
            if (contentType != null)
                conn.setRequestProperty("content-type", contentType);
            OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream(), DEFAULT_ENCODING);
            if (data == null)
                data = "";
            writer.write(data);
            writer.flush();
            writer.close();

            reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), DEFAULT_ENCODING));
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
                sb.append("\r\n");
            }
            return sb.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (reader != null)
                    reader.close();
            } catch (IOException e) {
            }
        }
        return null;
    }

}


package com.youruan.examine.util;

import java.security.MessageDigest;

/**
 * MD5加密
 * 创建者 zhy
 * 创建时间	2017年7月31日
 */
public class MD5Util {

    private static String byteArrayToHexString(byte b[]) {
        StringBuffer resultSb = new StringBuffer();
        for (int i = 0; i < b.length; i++)
            resultSb.append(byteToHexString(b[i]));

        return resultSb.toString();
    }

    private static String byteToHexString(byte b) {
        int n = b;
        if (n < 0)
            n += 256;
        int d1 = n / 16;
        int d2 = n % 16;
        return hexDigits[d1] + hexDigits[d2];
    }

    public static String MD5Encode(String origin, String charsetname) {
        String resultString = null;
        try {
            resultString = new String(origin);
            MessageDigest md = MessageDigest.getInstance("MD5");
            if (charsetname == null || "".equals(charsetname))
                resultString = byteArrayToHexString(md.digest(resultString.getBytes()));
            else
                resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));
        } catch (Exception exception) {
        }
        return resultString;
    }

    private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
}

package com.youruan.examine.util;

import java.text.SimpleDateFormat;
import java.util.*;

public class PayCommonUtil {

    /**
     * 是否签名正确,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
     *
     * @param characterEncoding
     * @param packageParams
     * @param API_KEY
     *
     * @return boolean
     *
     * @Author zhy
     * @Date 2017年7月31日 更新日志
     * 2017年7月31日  zhy 首次创建
     */
    @SuppressWarnings({"rawtypes"})
    public static boolean isTenpaySign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {
        StringBuffer sb = new StringBuffer();
        Set es = packageParams.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if (!"sign".equals(k) && null != v && !"".equals(v)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + API_KEY);
        //算出摘要  
        String mysign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toLowerCase();
        String tenpaySign = ((String) packageParams.get("sign")).toLowerCase();
        return tenpaySign.equals(mysign);
    }

    /**
     * sign签名
     *
     * @param characterEncoding
     * @param packageParams
     * @param API_KEY
     *
     * @return String
     *
     * @Author zhy
     * @Date 2017年7月31日 更新日志
     * 2017年7月31日  zhy 首次创建
     */
    @SuppressWarnings({"rawtypes"})
    public static String createSign(String characterEncoding, SortedMap<Object, Object> packageParams, String API_KEY) {
        StringBuffer sb = new StringBuffer();
        Set es = packageParams.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {
                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key=" + API_KEY);
        String sign = MD5Util.MD5Encode(sb.toString(), characterEncoding).toUpperCase();
        return sign;
    }

    /**
     * 将请求参数转换为xml格式的string
     *
     * @param parameters
     *
     * @return String
     *
     * @Author zhy
     * @Date 2017年7月31日 更新日志
     * 2017年7月31日  zhy 首次创建
     */
    @SuppressWarnings({"rawtypes"})
    public static String getRequestXml(SortedMap<Object, Object> parameters) {
        StringBuffer sb = new StringBuffer();
        sb.append("<xml>");
        Set es = parameters.entrySet();
        Iterator it = es.iterator();
        while (it.hasNext()) {
            Map.Entry entry = (Map.Entry) it.next();
            String k = (String) entry.getKey();
            String v = (String) entry.getValue();
            if ("attach".equalsIgnoreCase(k) || "body".equalsIgnoreCase(k) || "sign".equalsIgnoreCase(k)) {
                sb.append("<" + k + ">" + "<![CDATA[" + v + "]]></" + k + ">");
            } else {
                sb.append("<" + k + ">" + v + "</" + k + ">");
            }
        }
        sb.append("</xml>");
        return sb.toString();
    }

    /**
     * 取出一个指定长度大小的随机正整数.
     *
     * @param length
     *
     * @return int
     *
     * @Author zhy
     * @Date 2017年7月31日 更新日志
     * 2017年7月31日  zhy 首次创建
     */
    public static int buildRandom(int length) {
        int num = 1;
        double random = Math.random();
        if (random < 0.1) {
            random = random + 0.1;
        }
        for (int i = 0; i < length; i++) {
            num = num * 10;
        }
        return (int) ((random * num));
    }

    /**
     * 获取当前时间 yyyyMMddHHmmss
     *
     * @return String
     */
    public static String getCurrTime() {
        Date now = new Date();
        SimpleDateFormat outFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        String s = outFormat.format(now);
        return s;
    }
}

package com.youruan.examine.util;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * XML解析
 * 创建者 zhy
 * 创建时间	2017年7月31日
 */
public class XMLUtil {

    /**
     * 解析xml,返回第一级元素键值对。如果第一级元素有子节点,则此节点的值是子节点的xml数据。
     *
     * @param strxml
     *
     * @return JDOMException
     *
     * @throws IOException
     */
    @SuppressWarnings({"rawtypes", "unchecked"})
    public static Map doXMLParse(String strxml) throws JDOMException, IOException {
        strxml = strxml.replaceFirst("encoding=\".*\"", "encoding=\"UTF-8\"");

        if (null == strxml || "".equals(strxml)) {
            return null;
        }

        Map m = new HashMap();

        InputStream in = new ByteArrayInputStream(strxml.getBytes("UTF-8"));
        SAXBuilder builder = new SAXBuilder();
        Document doc = builder.build(in);
        Element root = doc.getRootElement();
        List list = root.getChildren();
        Iterator it = list.iterator();
        while (it.hasNext()) {
            Element e = (Element) it.next();
            String k = e.getName();
            String v = "";
            List children = e.getChildren();
            if (children.isEmpty()) {
                v = e.getTextNormalize();
            } else {
                v = XMLUtil.getChildrenText(children);
            }

            m.put(k, v);
        }

        // 关闭流
        in.close();

        return m;
    }

    /**
     * 获取子结点的xml
     *
     * @param children
     *
     * @return String
     */
    @SuppressWarnings({"rawtypes"})
    public static String getChildrenText(List children) {
        StringBuffer sb = new StringBuffer();
        if (!children.isEmpty()) {
            Iterator it = children.iterator();
            while (it.hasNext()) {
                Element e = (Element) it.next();
                String name = e.getName();
                String value = e.getTextNormalize();
                List list = e.getChildren();
                sb.append("<" + name + ">");
                if (!list.isEmpty()) {
                    sb.append(XMLUtil.getChildrenText(list));
                }
                sb.append(value);
                sb.append("</" + name + ">");
            }
        }

        return sb.toString();
    }
}

配置文件

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值