首页 > 技术文章 > 微信扫码支付--servlet版本

ldwnana 2018-03-10 15:50 原文

@WebServlet("/PayServlet")
public class PayServlet extends javax.servlet.http.HttpServlet {
    protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        String Key = "javastruts2springhibernate2016tr";
        String appid = "wx2537437d11cdec0b";
        String mch_id = "1381483602";
        String spbill_create_ip = "49.221.62.131";
        String body = "测试微商城";
        String trade_type = "NATIVE";
        //String notify_url = "http://zhuzuohua.oicp.net/ercodePay/pay-huidao.action";
        String notify_url = "http://ldw1018.xicp.cn/PayHuiDiaoServlet";
        int total_fee = 1;

        String nonce_str = Util.getRandomString(20);
        String out_trade_no = Util.getCurrTime() + Util.getRandomString(4);

        SortedMap<Object, Object> params = new TreeMap<>();
        params.put("appid", appid);
        params.put("mch_id", mch_id);
        params.put("spbill_create_ip", spbill_create_ip);
        params.put("body", body);
        params.put("nonce_str", nonce_str);
        params.put("trade_type", trade_type);
        params.put("notify_url", notify_url);
        params.put("total_fee", total_fee);
        params.put("out_trade_no", out_trade_no);

        //生成签名
        String sign = SignUtil.sign(params, Key);
        System.out.println("====" + sign);

        //产省生成xml的实体类
        Pay pay = new Pay();
        pay.setAppid(appid);
        pay.setMch_id(mch_id);
        pay.setSpbill_create_ip(spbill_create_ip);
        pay.setBody(body);
        pay.setNonce_str(nonce_str);
        pay.setTrade_type(trade_type);
        pay.setNotify_url(notify_url);
        pay.setOut_trade_no(out_trade_no);
        pay.setTotal_fee(total_fee);
        pay.setSign(sign);


        //生成请求xml
        XStreamUtil.xstream.alias("xml", Pay.class);
        String reqXml = XStreamUtil.xstream.toXML(pay).replace("__", "_");
        System.out.println(reqXml);


        //发送https请求
        String respXml = null;
        String requestUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
        try {
            respXml = HttpsRequest.sendHttpsRequest(requestUrl, "POST", reqXml);
        } catch (Exception e) {
            e.printStackTrace();
        }


        //解析xml,获取微信返回的生成带有字符信息二维码连接
        String code_url = null;
        try {
            Document document = DocumentHelper.parseText(respXml);
            Element rootElement = document.getRootElement();
            List<Element> elements = rootElement.elements();
            for (Element element : elements) {
                if (element.getName().equals("code_url")) {
                    code_url = element.getTextTrim();

                }
            }
            System.out.println(code_url + "=============code_url======");
        } catch (DocumentException e) {
            e.printStackTrace();
        }

        //根据返回的url生成二维码
        String codeapiUrl="http://pan.baidu.com/share/qrcode?w=200&h=200&url=URL";
        String ercodeUrl=codeapiUrl.replaceAll("URL", code_url);

        System.out.println(ercodeUrl+"二维码");
        request.setAttribute("ercodeUrl",ercodeUrl);
        request.getRequestDispatcher("/success.jsp").forward(request,response);
    }

  里面用到的几个工具类:

1.生成随机数和随机字符串工具类

/**
 * 生成随机数  和 订单
 */
public class Util {
	 public static String getRandomString(int length){  
	        Random random = new Random();  
	          
	        StringBuffer sb = new StringBuffer();  
	          
	        for(int i = 0; i < length; ++i){  
	            int number = random.nextInt(3);  
	            long result = 0;  
	            switch(number){  
	            case 0:  
	                result = Math.round(Math.random() * 25 + 65);  
	                sb.append(String.valueOf((char)result));  
	                break;  
	            case 1:  
	                result = Math.round(Math.random() * 25 + 97);  
	                sb.append(String.valueOf((char)result));  
	                break;  
	            case 2:  
	                sb.append(String.valueOf(new Random().nextInt(10)));  
	                break;  
	            }  
	        }  
	        
	        return sb.toString();     
	    }  





	public static String getCurrTime() {
			Date now = new Date();
			SimpleDateFormat outFormat = new        
	        SimpleDateFormat("yyyyMMddHHmmss");
			String s = outFormat.format(now);
			return s;
		}
	
	
}

  第二个工具类:生成签名

/**
 * @Author: bdqn
 * @Description: 生成参数传递的签名
 * @Date: created in 10:39 2018/3/10
 */

public class SignUtil {

    public static String sign( SortedMap<Object, Object> params,String key) {
        StringBuilder sb = new StringBuilder();
        Set<Map.Entry<Object, Object>> entries = params.entrySet();
        Iterator<Map.Entry<Object, Object>> iterator = entries.iterator();
        while (iterator.hasNext()) {
            Map.Entry<Object, Object> entry = iterator.next();
            String k = (String) entry.getKey();
            Object v = entry.getValue();
            if (null != v && !"".equals(v) && !"sign".equals(k) && !"key".equals(k)) {

                sb.append(k + "=" + v + "&");
            }
        }
        sb.append("key="+key);
        System.out.println(sb.toString());

        String sign = MD5.MD5Encode(sb.toString(), "UTF-8").toUpperCase();
        System.out.println(sign);
        return sign;

    }


}

  第三个:对象生成xml

/**
 * 扩展xstram  加入CDATA区域
 */
public class XStreamUtil {


    public static XStream xstream = new XStream(new XppDriver() {
        public HierarchicalStreamWriter createWriter(Writer out) {
            return new PrettyPrintWriter(out) {
                boolean cdata = true;

                public void startNode(String name, Class clazz) {
                    super.startNode(name, clazz);
                }

                protected void writeText(QuickWriter writer, String text) {
                    if (cdata) {
                        writer.write("<![CDATA[");
                        writer.write(text);
                        writer.write("]]>");
                    } else {
                        writer.write(text);
                    }
                }
            };
        }
    });


}

  第四个:发送http请求

/**
 * @Author: bdqn
 * @Description: 发送https请求
 * @Date: created in 13:52 2018/3/10
 */

public class HttpsRequest {
    public static String sendHttpsRequest(String requestUrl, String requestMethod, String outStr) throws Exception {
        //创建	SSLContext
        SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
        TrustManager[] tm = {new MyX509TrustManager()};
        //初始化
        sslContext.init(null, tm, new java.security.SecureRandom());
        //获取sslSOCKETfactory对象
        SSLSocketFactory ssf = sslContext.getSocketFactory();

        //设置当前实例使用sslSOCKETfactory
        StringBuffer buffer = null;
        URL url = new URL(requestUrl);
        HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();

        conn.setRequestMethod(requestMethod);
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setSSLSocketFactory(ssf);
        conn.connect();


        //向服务端发送数据
        if (outStr != null) {
            OutputStream os = conn.getOutputStream();
            os.write(outStr.getBytes("UTF-8"));
            os.close();

        }


        //读取服务端的内容
        InputStream is = conn.getInputStream();
        InputStreamReader isr = new InputStreamReader(is, "utf-8");
        BufferedReader br = new BufferedReader(isr);
        buffer = new StringBuffer();
        String line = null;
        while ((line = br.readLine()) != null) {
            buffer.append(line);
        }

        //打印返回的参数
        System.out.println(buffer.toString());

        //打印数据
        return buffer.toString();
    }

  

 

 

 

第二部分 :回调函数

**
 * 微信回调函数
 */

@WebServlet("/PayHuiDiaoServlet")
public class PayHuiDiaoServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("回调函数");
        //接收微信的调用
        InputStream inputStream = request.getInputStream();
        StringBuffer sb = new StringBuffer();
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        String line = "";
        while ((line = bufferedReader.readLine()) != null) {
            sb.append(line);
        }

        bufferedReader.close();
        inputStream.close();
        String respXml = sb.toString();
        System.out.println(respXml + "respons");


        //回复消息给微信
        //1.解析xml
        try {
            String code = "";
            Document document = DocumentHelper.parseText(respXml);
            Element rootElement = document.getRootElement();
            List<Element> elements = rootElement.elements();
            for (Element element : elements) {
                if (element.getName().equals("result_code")) {
                    code = element.getTextTrim();
                    System.out.println("成功code" + code);

                    //第三步:返回信件涵
                    if ("SUCCESS".equals(code)) {
                        String resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                                + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
                        OutputStream outputStream = response.getOutputStream();
                        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
                        bufferedOutputStream.write(respXml.getBytes());
                        bufferedOutputStream.close();
                        outputStream.close();
                        System.out.println("回复成功");

                    }
                }
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }


    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }
}

  

推荐阅读