發送郵件實現(使用QQ郵箱發送到指定郵箱)javascript
須要的jarcss
郵件發送類代碼:html
1 package util; 2 3 import java.util.Properties; 4 5 import javax.mail.Authenticator; 6 import javax.mail.Message; 7 import javax.mail.MessagingException; 8 import javax.mail.PasswordAuthentication; 9 import javax.mail.Session; 10 import javax.mail.Transport; 11 import javax.mail.internet.AddressException; 12 import javax.mail.internet.InternetAddress; 13 import javax.mail.internet.MimeMessage; 14 import javax.mail.internet.MimeMessage.RecipientType; 15 //用於發送郵件 16 public class MailUtils { 17 18 public static void sendMail(String email, String emailMsg) 19 throws AddressException, MessagingException { 20 // 1.建立一個程序與郵件服務器會話對象 Session 21 22 Properties props = new Properties(); 23 props.setProperty("mail.transport.protocol", "SMTP");//郵件發送協議 24 props.setProperty("mail.host", "smtp.qq.com");//使用哪一個郵件服務器進行郵件的發送 25 props.setProperty("mail.smtp.auth", "true");// 指定驗證爲true 26 //props.setProperty("mail.smtp.port","465"); 27 props.setProperty("mail.smtp.ssl.enable","true"); 28 29 // 建立驗證器 30 Authenticator auth = new Authenticator() { 31 public PasswordAuthentication getPasswordAuthentication() { 32 //第一個參數是發送人帳戶,第二個是受權碼(須要在郵箱中開啓POP3/SMTP服務 而後得到 33 return new PasswordAuthentication("1085974196", "lzwzaasabwqxgaai"); 34 } 35 }; 36 37 Session session = Session.getInstance(props, auth); 38 39 // 2.建立一個Message,它至關因而郵件內容 40 Message message = new MimeMessage(session); 41 message.setFrom(new InternetAddress("1085974196@qq.com")); // 設置發送者 42 System.out.println("發送的目標地址是:"+email); 43 message.setRecipient(RecipientType.TO, new InternetAddress(email)); // 設置發送方式與接收者 44 45 message.setSubject("好易購商城註冊-用戶激活"); 46 // message.setText("這是一封激活郵件,請<a href='#'>點擊</a>"); 47 48 message.setContent(emailMsg, "text/html;charset=utf-8"); 49 50 // 3.建立 Transport用於將郵件發送 51 52 Transport.send(message); 53 } 54 }
發送郵件時直接調用該方法,而且傳遞目標地址參數以及發送的內容前端
-------------------------------java
隨機碼:node
單元測試,打印:jquery
調用得到(static類型,直接經過類名稱進行調用):ajax
---------------------------算法
短信驗證碼的發送(這裏使用雲片短息服務平臺)數據庫
導入jar
經過ajax異步操做,在用戶滑動滑塊的時候向指定action中傳遞在表單中得到的電話號碼
//TODO //********發送手機驗證碼使用Ajax 跳入action 執行指定方法 在action中調用第三方平臺 發送短信******* $.post( "/shop/SendSMS.action", {"phone":$("#phone").val()} );
跳到指定的action中,發送驗證碼以後不須要任何跳轉,以下代碼:
package util; import java.io.IOException; import java.net.URLEncoder; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.ResourceBundle; import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; //在滑動滑塊以後,調用js代碼,經過異步的方式進入該action 進行驗證碼的發送 經過第三方平臺的支持(這裏使用雲片短信服務) public class SendSMSAction extends ActionSupport { //智能匹配模版發送接口的http地址 private static String URI_SEND_SMS = "https://sms.yunpian.com/v2/sms/single_send.json"; //編碼格式。發送編碼格式統一用UTF-8 private static String ENCODING = "UTF-8"; public String execute()throws Exception{ System.out.println("進入發送驗證碼action,經過第三方平臺"); //獲取手機號碼 String phone = ServletActionContext.getRequest().getParameter("phone"); //獲取src下的sms.properties文件 ResourceBundle rb = ResourceBundle.getBundle("sms"); //得到第三方短信平臺 給與標識 String apikey = rb.getString("apiKey"); //對手機號進行編碼 String mobile = URLEncoder.encode(phone,ENCODING); //產生隨機的驗證碼 String smsCode = (""+Math.random()*1000000).substring(0,6); //拼接短信信息 必須使用雲片服務平臺審覈經過的模板和簽名 否則沒法完成發送 String text ="【好易購】歡迎您註冊,您的驗證碼是"+smsCode+"。如非本人操做,請忽略本短信"; System.out.println(text); //短信發送 String sendSms = sendSms(apikey, text, mobile); //將驗證碼存到session域中 ServletActionContext.getRequest().getSession().setAttribute("smsCode", smsCode); System.out.println("發送驗證碼action執行完畢,驗證碼已經發送。"); return NONE; } /** * 智能匹配模版接口發短信 * * @param apikey apikey * @param text 短信內容 * @param mobile 接受的手機號 * @return json格式字符串 * @throws IOException */ public String sendSms(String apikey, String text, String mobile) throws IOException { Map<String, String> params = new HashMap<String, String>(); params.put("apikey", apikey); params.put("text", text); params.put("mobile", mobile); return post(URI_SEND_SMS, params); } /** * 基於HttpClient 4.3的通用POST方法 * * @param url 提交的URL * @param paramsMap 提交<參數,值>Map * @return 提交響應 */ public String post(String url, Map<String, String> paramsMap) { CloseableHttpClient client = HttpClients.createDefault(); String responseText = ""; CloseableHttpResponse response = null; try { HttpPost method = new HttpPost(url); if (paramsMap != null) { List<NameValuePair> paramList = new ArrayList<NameValuePair>(); for (Map.Entry<String, String> param : paramsMap.entrySet()) { NameValuePair pair = new BasicNameValuePair(param.getKey(), param.getValue()); paramList.add(pair); } method.setEntity(new UrlEncodedFormEntity(paramList, ENCODING)); } response = client.execute(method); HttpEntity entity = response.getEntity(); if (entity != null) { responseText = EntityUtils.toString(entity); } } catch (Exception e) { e.printStackTrace(); } finally { try { response.close(); } catch (Exception e) { e.printStackTrace(); } } return responseText; } }
上面須要注意的是,使用短信服務,須要註冊一個短信服務平臺,這裏使用雲片短信服務平臺
就是上面這個apikey(註冊免費送10條,用完的話你能夠花50大洋,購買1000條短信服務)
而後表單中輸入正確的驗證碼,既能夠完成註冊
------------------------------
MD5加密
1 package util; 2 3 import java.math.BigInteger; 4 import java.security.MessageDigest; 5 import java.security.NoSuchAlgorithmException; 6 7 import org.junit.Test; 8 9 public class MD5Utils { 10 /** 11 * 使用md5的算法進行加密 12 */ 13 public static String md5(String plainText) { 14 byte[] secretBytes = null; 15 try { 16 secretBytes = MessageDigest.getInstance("md5").digest( 17 plainText.getBytes()); 18 } catch (NoSuchAlgorithmException e) { 19 throw new RuntimeException("沒有md5這個算法!"); 20 } 21 String md5code = new BigInteger(1, secretBytes).toString(16);// 16進制數字 22 // 若是生成數字未滿32位,須要前面補0 23 for (int i = 0; i < 32 - md5code.length(); i++) { 24 md5code = "0" + md5code; 25 } 26 return md5code; 27 } 28 @Test 29 public void test(){ 30 System.out.println(md5("12345")); 31 } 32 }
單元測試結果:
827ccb0eea8a706c4c34a16891f84e7b
經過類.方法名 直接調用類中的靜態方法
-------------------------------------------------------------------------------
jquery焦點事件,判斷用戶輸入的手機號是否已經註冊
(表單失去焦點以後,經過post異步方式,把手機號提交給相應action,而後作判斷,並把後端數據,傳給前端)
jsp頁面:
1 <div id="phonecheck"> 2 3 </div> 4 <div class="cell"> 5 <input id="phone" type="text" value="${user.username }" placeholder="請輸入手機號碼" name="username" id="js-mobile_ipt" class="text" maxlength="11" /> 6 7 </div> 8 <script type="text/javascript"> 9 $('#phone').blur(function(){//使用post異步方式進行手機檢查 是否註冊過了 10 //先檢查位數是否爲11位 若是是那麼就進行異步判斷 11 var pattern=/1[0-9]{10}/; 12 var phone=$('#phone').val(); 13 var flag=pattern.test(phone); 14 15 if(flag){//位數是正確的 16 $.post( 17 "/shop/UserAction_check.action",//url 18 {"phone":$("#phone").val()},//value 若是多個參數,中間使用逗號分隔 19 function(data){//回調函數 data就是後端返回的數據 20 //data是action中返回的數據checkresult 21 // ServletActionContext.getResponse().getWriter().write(checkresult); 22 23 if(data=="true"){// 可使用 24 $("#phonecheck").html("能夠的使用手機號!").css("color","#76bf48"); 25 }else{//不能使用 26 $("#phonecheck").html("對不起,該手機號已經註冊,如忘記密碼,能夠找回!").css("color","red"); 27 //號碼已經註冊,不能繼續使用,因此把表單中的內容清空,讓用戶從新輸入號碼 28 $("#phone").val(""); 29 } 30 } 31 32 ); 33 }else{//位數不正確 34 35 $("#phonecheck").html("手機號格式不正確!").css("color","red"); 36 //格式不正確,清空表單中的手機號碼,讓用戶從新輸入 37 $("#phone").val(""); 38 } 39 40 41 }); 42 </script>
傳給後臺多個參數(參數名 加不加引號都無所謂)
struts.xml
action中代碼:
//檢查手機號是否已經註冊了 並把查詢結果按照字符串的方式傳遞到前端 在ajax回調函數獲取 public void check(){ String phone=ServletActionContext.getRequest().getParameter("phone"); String checkresult=null; if(!userService.check(phone)){ checkresult="false"; }else{ checkresult="true"; } try { ServletActionContext.getResponse().setCharacterEncoding("utf-8");//設置字符編碼 ServletActionContext.getResponse().getWriter().write(checkresult);//把傳遞的內容傳遞到前端 在回調函數中能夠得到 } catch (IOException e) { e.printStackTrace(); } }
ServletActionContext.getResponse().getWriter().write(checkresult);//把傳遞的內容傳遞到前端 在回調函數中能夠得到
運行效果:
--------------------------------------------------------
動態設置標籤的id值,而且單擊該標籤以後,得到設置的id
------------------------------------------------------
點擊button,跳轉到後臺action
----------------------------------
巧妙設置id
先看下面的截圖:
使用例子:
<c:forEach items="${listCart }" var="entry" varStatus="vs"> <tr id="product1" class="${entry.product.pid}" style="height:150px"> <td class="cart_td_1" width="5%"><input name="cartCheckBox" type="checkbox" value="product1" onclick="selectSingle()" /></td> <td class="cart_td_2" width="18%"><img src="${pageContext.request.contextPath }/${entry.product.pimage}" alt="shopping"/></td> <td class="cart_td_3" width="33%"><a href="#">${entry.product.pname}</a><br /> 顏色:棕色 尺碼:37<br /> 保障:<img src="images/taobao_icon_01.jpg" alt="icon" /></td> <td class="cart_td_4" width="5%">5</td> <td class="cart_td_5" width="10%">${entry.product.shop_price}</td> <td class="cart_td_6" width="10%"> <img src="images/taobao_minus.jpg" alt="minus" onclick="changeNum('num_${vs.count}','minus','${entry.product.pid}','${sessionScope.user.uid}')" class="hand"/> <input id="num_${vs.count }" type="text" value="${entry.number}" class="num_input" readonly="readonly"/> <img src="images/taobao_adding.jpg" alt="add" onclick="changeNum('num_${vs.count}','add','${entry.product.pid}','${sessionScope.user.uid}')" class="hand"/> </td> <td class="cart_td_7" width="10"></td> <!-- <td class="cart_td_8" width="10"><a href="javascript:deleteRow('product1');">刪除</a></td> --> <td class="cart_td_8" width="10"><a id="${entry.product.pid}" onclick="GetPid(this)">刪除</a></td> </tr> </c:forEach>
js代碼:
//購物車計算
function changeNum(numId,flag,pid,uid){
var numId=document.getElementById(numId);
if(flag=="minus"){
if(numId.value<=1){
//alert("商品不能小於一件");
win.alert("好易購-商品數量警告", "商品不能小於一件!");
return false;
}
else{
//發送ajax減小購物車中的商品數量
$.post(
"${pageContext.request.contextPath}/CartAction_changeNumber",
{"product.pid":pid,"flag":flag,"user.uid":uid},
function(data){
if(data=="UpdateSuccess"){
numId.value=parseInt(numId.value)-1;//點擊減號 頁面上的數值-1 雖然數據庫改變了 可是不刷新頁面該值是不會變化的 因此就在更新數據以後 直接改變頁面上的顯示值
productCount();//調整數量以後,執行該函數把訂單總價改變
}
}
);
}
}else{
//發送ajax添加購物車中的商品數量
$.post(
"${pageContext.request.contextPath}/CartAction_changeNumber",
{"product.pid":pid,"flag":flag,"user.uid":uid},
function(data){
if(data=="UpdateSuccess"){
numId.value=parseInt(numId.value)+1;
productCount();//調整數量以後,執行該函數把訂單總價改變
}
}
);
}
}
首先須要明確 ,不管遍歷了多少個對象,'num_${vs.count}'的值在某一行上的值是固定的
好比遍歷出的第一行數據,它的
<input id="num_${vs.count }" type="text" value="${entry.number}" class="num_input" readonly="readonly"/>
該行的id永遠爲1,並且
<img src="images/taobao_minus.jpg" alt="minus" onclick="changeNum('num_${vs.count}','minus','${entry.product.pid}','${sessionScope.user.uid}')" class="hand"/>
<img src="images/taobao_adding.jpg" alt="add" onclick="changeNum('num_${vs.count}','add','${entry.product.pid}','${sessionScope.user.uid}')" class="hand"/>
在單擊以後,會調用changeNum函數,傳遞的第一個參數也是1,這三行的vs。count永遠是保持一致的
遍歷出的頁面
上面的三條語句在頁面的顯示效果就是圖中的三個標記,一個+,一個-,還有一c個就是input
使用varStatus屬性就是爲了保證在單擊每一行的時候,在js中得到的input表單對象
【
var numId=document.getElementById(numId);
】
爲當前點擊的這一行。
好比單擊第一行的時候(單擊 - 號),調用函數,而且傳遞了參數給該函數,參數此時以下
changeNum(numId,flag,pid,uid)
changeNum('1','minus',xx,xx)
執行該代碼:
var numId=document.getElementById(numId);
numId的值爲1,至關於:
var numId=document.getElementById(1);
由於單擊的是第一行,因此
<input id="num_${vs.count }" type="text" value="${entry.number}" class="num_input" readonly="readonly"/>
這裏的id的值就是1,因此單擊某一行時,得到的表單對象正好就是當前 「單擊行」 的input
經過這個例子,還能夠知道,onclick函數中傳遞參數的格式,而且還能夠傳遞動態參數
<img src="images/taobao_minus.jpg" alt="minus" onclick="changeNum('num_${vs.count}','minus','${entry.product.pid}','${sessionScope.user.uid}')" class="hand"/>
---------------------------------------------------------------
使用El表達式在遍歷中實現累加的功能
代碼實踐:
<c:set var="count" value="0.0"></c:set> <c:forEach items="${listCart }" var="entry"> <dd class="item clearfix"> <div class="item-row"> <div class="col col-1"> <div class="g-pic"> <img src="${pageContext.request.contextPath }/${entry.product.pimage}" width="40" height="40" /> </div> <div class="g-info"> ${entry.product.pname} </div> </div> <div class="col col-2">${entry.univalence}元</div> <div class="col col-3">${entry.number}</div> <div class="col col-4">${entry.subtotal}元</div> </div> </dd> <c:set var="count" value="${count+entry.subtotal }"></c:set> </c:forEach>
運行效果:
--------------------------------------------
js傳遞數組給後臺(一)
![](http://static.javashuo.com/static/loading.gif)
代碼實踐
1 var s=["1","2"]; 2 location.href="${pageContext.request.contextPath}/OrderAction_ensure.action?s="+s;
1 String[] array = ServletActionContext.getRequest().getParameterValues("s"); 2 for (String string : array) { 3 System.out.println(string); 4 }
輸出結果:
--------------------------------------
js傳遞數組給後臺(二)-------動態傳遞(數組內容動態設置)
複選框中的value是當前循環商品的商品id
提交,調用js代碼:
在js中完成數據的設置,而後傳遞給action
循環輸出:
或者:
打印結果:
須要注意的是,這個循環只循環了一次,爲何呢,由於從前端獲得的數據是一個字符數組,並且全部的數據所有在下標爲0的地方,即arrty[0]="21,49,36"
因此要想使用這些數據,還須要進一步轉化,把他編程一個一個數字,放在list集合中
1 //獲得前端傳遞過來的數據 2 String[] pidstr = ServletActionContext.getRequest().getParameterValues("s"); 3 //得到字符串 4 String str=pidstr[0]; 5 //把字符串轉換爲字符數組 6 String[] pidstring=new String[]{};//建立字符數組 7 pidstring=str.split(",");//把str字符串按分號進行分割 把分割獲得每個部分存入字符串數組中 8 //須要把字符串數組轉換成list數組 9 List pidList=Arrays.asList(pidstring);
而後對list集合就能夠方便的進行遍歷,取出其中的每個值了
-----------------------------------------
時間格式化
-------------
------------------------------------------------------------------------
接入第三方支付平臺,完成真正的支付
支付平臺(固然像淘寶,京東這樣的大公司都有本身的支付平臺):
1.易寶支付
2.連連支付
3.國付寶
支付流程:
接入的時候是須要企業級資質的
註冊以後 得到一個key=帳號(區別不一樣的企業,未來轉帳的RMB都將流向該企業註冊時填寫的帳號上) 以及value=祕鑰(用於加密對比 防止數據被篡改)
這個key和value是可使用的
訂單提交以後,選擇在線支付
選擇對應銀行以後,點擊下一步:提交表單
銀行標識發送給目標action,完成數據的封裝準備,以及數據的加密
下面看該action中的代碼:
1 package util; 2 import java.util.ResourceBundle; 3 import org.apache.struts2.ServletActionContext; 4 import org.model.Orders; 5 import com.opensymphony.xwork2.ActionSupport; 6 //支付action 經過第三方平臺的支持(這裏使用易寶支付,固然須要外網) 7 public class PayOrderAction extends ActionSupport { 8 public String execute()throws Exception{ 9 System.out.println("進入支付action"); 10 // 得到 支付必須基本數據 11 Orders orders=(Orders) ServletActionContext.getRequest().getSession().getAttribute("Orders"); 12 String orderid = orders.getOid();//得到訂單編號 13 //String money =orders.getTotal()+"";//得到訂單總額 即支付的金額 14 //這裏作模擬 支付0.01元 15 String money="0.01"; 16 17 //得到銀行標識 即選擇的是哪個銀行進行支付 18 String pd_FrpId =ServletActionContext.getRequest().getParameter("pd_FrpId"); 19 20 21 // 發給支付公司(易寶支付平臺 )須要哪些數據 22 String p0_Cmd = "Buy"; 23 //得到項目src下 merchantInfo.properties文件中 key="p1_MerId"對應的值 即獲取企業帳戶p1_MerId=10001126856 24 //未來交易的金額 流向了該帳戶的銀行卡中(企業註冊使用平臺服務的時候 確定預留的有銀行卡帳號 平臺返給企業一個帳號 用於區別不一樣的企業) 25 String p1_MerId = ResourceBundle.getBundle("merchantInfo").getString("p1_MerId"); 26 String p2_Order = orderid; 27 String p3_Amt = money; 28 String p4_Cur = "CNY"; 29 String p5_Pid = ""; 30 String p6_Pcat = ""; 31 String p7_Pdesc = "";//必需要填寫的字段使用""代替 32 // 支付成功回調地址 ---- 第三方支付公司會訪問、用戶訪問 33 // 第三方支付能夠訪問網址 34 String p8_Url = ResourceBundle.getBundle("merchantInfo").getString("callback"); 35 String p9_SAF = ""; 36 String pa_MP = ""; 37 String pr_NeedResponse = "1"; 38 // 加密hmac 須要密鑰 merchantInfo.properties文件中獲取key="keyValue"對應的值 39 String keyValue = ResourceBundle.getBundle("merchantInfo").getString( 40 "keyValue"); 41 //PaymentUtil.buildHmac第三平臺提供的加密方法 42 //在支付平臺把傳遞過去的【A部分.明文數據】也作加密 與hmac【B部分.加密以後的密文】作對比 防止數據被篡改 43 String hmac = PaymentUtil.buildHmac(p0_Cmd, p1_MerId, p2_Order, p3_Amt, 44 p4_Cur, p5_Pid, p6_Pcat, p7_Pdesc, p8_Url, p9_SAF, pa_MP, 45 pd_FrpId, pr_NeedResponse, keyValue); 46 // 把數據進行保存在request域中 跳到confirm.jsp中進行確認 而後提交 提交的地址 47 //https://www.yeepay.com/app-merchant-proxy/node 是第三方支付平臺 攜帶的數據 就是下面封裝的 48 //數據,想要完成支付首先須要鏈接外網 由於這個地址目標不是本地上的頁面 49 /* 50 //A部分.明文數據 51 ServletActionContext.getRequest().setAttribute("pd_FrpId", pd_FrpId); 52 ServletActionContext.getRequest().setAttribute("p0_Cmd", p0_Cmd); 53 ServletActionContext.getRequest().setAttribute("p1_MerId", p1_MerId); 54 ServletActionContext.getRequest().setAttribute("p2_Order", p2_Order); 55 ServletActionContext.getRequest().setAttribute("p3_Amt", p3_Amt); 56 ServletActionContext.getRequest().setAttribute("p4_Cur", p4_Cur); 57 ServletActionContext.getRequest().setAttribute("p5_Pid", p5_Pid); 58 ServletActionContext.getRequest().setAttribute("p6_Pcat", p6_Pcat); 59 ServletActionContext.getRequest().setAttribute("p7_Pdesc", p7_Pdesc); 60 ServletActionContext.getRequest().setAttribute("p8_Url", p8_Url); 61 ServletActionContext.getRequest().setAttribute("p9_SAF", p9_SAF); 62 ServletActionContext.getRequest().setAttribute("pa_MP", pa_MP); 63 ServletActionContext.getRequest().setAttribute("pr_NeedResponse", pr_NeedResponse); 64 //B部分.加密以後的密文 65 ServletActionContext.getRequest().setAttribute("hmac", hmac); 66 //跳轉頁面 67 ServletActionContext.getRequest().getRequestDispatcher("/confirm.jsp").forward(ServletActionContext.getRequest(),ServletActionContext.getResponse()); 68 */ 69 //第三方支付平臺(易寶支付)url 而且攜帶支付數據 直接跳到該地址 刪除中間頁confirm.jsp 70 String ThirdpartyUrl="https://www.yeepay.com/app-merchant-proxy/node?pd_FrpId="+pd_FrpId 71 +"&p0_Cmd="+p0_Cmd 72 +"&p1_MerId="+p1_MerId 73 +"&p2_Order="+p2_Order 74 +"&p3_Amt="+p3_Amt 75 +"&p4_Cur="+p4_Cur 76 +"&p5_Pid="+p5_Pid 77 +"&p6_Pcat="+p6_Pcat 78 +"&p7_Pdesc="+p7_Pdesc 79 +"&p8_Url="+p8_Url 80 +"&p9_SAF="+p9_SAF 81 +"&pa_MP="+pa_MP 82 +"&pr_NeedResponse="+pr_NeedResponse 83 +"&hmac="+hmac; 84 //重定向到第三方支付平臺 而後根據傳遞的數據 連接到對應銀行支付頁面 85 ServletActionContext.getResponse().sendRedirect(ThirdpartyUrl); 86 return NONE; 87 } 88 89 }
PaymentUtil.buildHmac是第三平臺提供的加密算法工具類
1 package util; 2 3 import java.io.UnsupportedEncodingException; 4 import java.security.MessageDigest; 5 import java.security.NoSuchAlgorithmException; 6 import java.util.Arrays; 7 //支付過程當中須要對傳遞的數據進行加密 這是第三方支付平臺給的加密代碼 直接使用便可 8 public class PaymentUtil { 9 10 private static String encodingCharset = "UTF-8"; 11 12 /** 13 * 生成hmac方法 14 * 15 * @param p0_Cmd 業務類型 16 * @param p1_MerId 商戶編號 17 * @param p2_Order 商戶訂單號 18 * @param p3_Amt 支付金額 19 * @param p4_Cur 交易幣種 20 * @param p5_Pid 商品名稱 21 * @param p6_Pcat 商品種類 22 * @param p7_Pdesc 商品描述 23 * @param p8_Url 商戶接收支付成功數據的地址 24 * @param p9_SAF 送貨地址 25 * @param pa_MP 商戶擴展信息 26 * @param pd_FrpId 銀行編碼 27 * @param pr_NeedResponse 應答機制 28 * @param keyValue 商戶密鑰 29 * @return 30 */ 31 public static String buildHmac(String p0_Cmd,String p1_MerId, 32 String p2_Order, String p3_Amt, String p4_Cur,String p5_Pid, String p6_Pcat, 33 String p7_Pdesc,String p8_Url, String p9_SAF,String pa_MP,String pd_FrpId, 34 String pr_NeedResponse,String keyValue) { 35 StringBuilder sValue = new StringBuilder(); 36 // 業務類型 37 sValue.append(p0_Cmd); 38 // 商戶編號 39 sValue.append(p1_MerId); 40 // 商戶訂單號 41 sValue.append(p2_Order); 42 // 支付金額 43 sValue.append(p3_Amt); 44 // 交易幣種 45 sValue.append(p4_Cur); 46 // 商品名稱 47 sValue.append(p5_Pid); 48 // 商品種類 49 sValue.append(p6_Pcat); 50 // 商品描述 51 sValue.append(p7_Pdesc); 52 // 商戶接收支付成功數據的地址 53 sValue.append(p8_Url); 54 // 送貨地址 55 sValue.append(p9_SAF); 56 // 商戶擴展信息 57 sValue.append(pa_MP); 58 // 銀行編碼 59 sValue.append(pd_FrpId); 60 // 應答機制 61 sValue.append(pr_NeedResponse); 62 63 return PaymentUtil.hmacSign(sValue.toString(), keyValue); 64 } 65 66 /** 67 * 返回校驗hmac方法 68 * 69 * @param hmac 支付網關發來的加密驗證碼 70 * @param p1_MerId 商戶編號 71 * @param r0_Cmd 業務類型 72 * @param r1_Code 支付結果 73 * @param r2_TrxId 易寶支付交易流水號 74 * @param r3_Amt 支付金額 75 * @param r4_Cur 交易幣種 76 * @param r5_Pid 商品名稱 77 * @param r6_Order 商戶訂單號 78 * @param r7_Uid 易寶支付會員ID 79 * @param r8_MP 商戶擴展信息 80 * @param r9_BType 交易結果返回類型 81 * @param keyValue 密鑰 82 * @return 83 */ 84 public static boolean verifyCallback(String hmac, String p1_MerId, 85 String r0_Cmd, String r1_Code, String r2_TrxId, String r3_Amt, 86 String r4_Cur, String r5_Pid, String r6_Order, String r7_Uid, 87 String r8_MP, String r9_BType, String keyValue) { 88 StringBuilder sValue = new StringBuilder(); 89 // 商戶編號 90 sValue.append(p1_MerId); 91 // 業務類型 92 sValue.append(r0_Cmd); 93 // 支付結果 94 sValue.append(r1_Code); 95 // 易寶支付交易流水號 96 sValue.append(r2_TrxId); 97 // 支付金額 98 sValue.append(r3_Amt); 99 // 交易幣種 100 sValue.append(r4_Cur); 101 // 商品名稱 102 sValue.append(r5_Pid); 103 // 商戶訂單號 104 sValue.append(r6_Order); 105 // 易寶支付會員ID 106 sValue.append(r7_Uid); 107 // 商戶擴展信息 108 sValue.append(r8_MP); 109 // 交易結果返回類型 110 sValue.append(r9_BType); 111 String sNewString = PaymentUtil.hmacSign(sValue.toString(), keyValue); 112 return sNewString.equals(hmac); 113 } 114 115 /** 116 * @param aValue 117 * @param aKey 118 * @return 119 */ 120 public static String hmacSign(String aValue, String aKey) { 121 byte k_ipad[] = new byte[64]; 122 byte k_opad[] = new byte[64]; 123 byte keyb[]; 124 byte value[]; 125 try { 126 keyb = aKey.getBytes(encodingCharset); 127 value = aValue.getBytes(encodingCharset); 128 } catch (UnsupportedEncodingException e) { 129 keyb = aKey.getBytes(); 130 value = aValue.getBytes(); 131 } 132 133 Arrays.fill(k_ipad, keyb.length, 64, (byte) 54); 134 Arrays.fill(k_opad, keyb.length, 64, (byte) 92); 135 for (int i = 0; i < keyb.length; i++) { 136 k_ipad[i] = (byte) (keyb[i] ^ 0x36); 137 k_opad[i] = (byte) (keyb[i] ^ 0x5c); 138 } 139 140 MessageDigest md = null; 141 try { 142 md = MessageDigest.getInstance("MD5"); 143 } catch (NoSuchAlgorithmException e) { 144 145 return null; 146 } 147 md.update(k_ipad); 148 md.update(value); 149 byte dg[] = md.digest(); 150 md.reset(); 151 md.update(k_opad); 152 md.update(dg, 0, 16); 153 dg = md.digest(); 154 return toHex(dg); 155 } 156 157 public static String toHex(byte input[]) { 158 if (input == null) 159 return null; 160 StringBuffer output = new StringBuffer(input.length * 2); 161 for (int i = 0; i < input.length; i++) { 162 int current = input[i] & 0xff; 163 if (current < 16) 164 output.append("0"); 165 output.append(Integer.toString(current, 16)); 166 } 167 168 return output.toString(); 169 } 170 171 /** 172 * 173 * @param args 174 * @param key 175 * @return 176 */ 177 public static String getHmac(String[] args, String key) { 178 if (args == null || args.length == 0) { 179 return (null); 180 } 181 StringBuffer str = new StringBuffer(); 182 for (int i = 0; i < args.length; i++) { 183 str.append(args[i]); 184 } 185 return (hmacSign(str.toString(), key)); 186 } 187 188 /** 189 * @param aValue 190 * @return 191 */ 192 public static String digest(String aValue) { 193 aValue = aValue.trim(); 194 byte value[]; 195 try { 196 value = aValue.getBytes(encodingCharset); 197 } catch (UnsupportedEncodingException e) { 198 value = aValue.getBytes(); 199 } 200 MessageDigest md = null; 201 try { 202 md = MessageDigest.getInstance("SHA"); 203 } catch (NoSuchAlgorithmException e) { 204 e.printStackTrace(); 205 return null; 206 } 207 return toHex(md.digest(value)); 208 209 } 210 211 // public static void main(String[] args) { 212 // System.out.println(hmacSign("AnnulCard1000043252120080620160450.0http://localhost/SZXpro/callback.asp榪?4564868265473632445648682654736324511","8UPp0KE8sq73zVP370vko7C39403rtK1YwX40Td6irH216036H27Eb12792t")); 213 // } 214 }
點擊下一步以後,跳轉到支付確認頁面confirm.jsp(完成數據的封裝)
1 <!-- 確認支付form --> 2 <form action="https://www.yeepay.com/app-merchant-proxy/node" method="post"> 3 <h3>訂單號:${p2_Order},付款金額 :${p3_Amt }</h3> 4 <input type="hidden" name="pd_FrpId" value="${pd_FrpId }" /> 5 <input type="hidden" name="p0_Cmd" value="${p0_Cmd }" /> 6 <input type="hidden" name="p1_MerId" value="${p1_MerId }" /> 7 <input type="hidden" name="p2_Order" value="${p2_Order }" /> 8 <input type="hidden" name="p3_Amt" value="${p3_Amt }" /> 9 <input type="hidden" name="p4_Cur" value="${p4_Cur }" /> 10 <input type="hidden" name="p5_Pid" value="${p5_Pid }" /> 11 <input type="hidden" name="p6_Pcat" value="${p6_Pcat }" /> 12 <input type="hidden" name="p7_Pdesc" value="${p7_Pdesc }" /> 13 <input type="hidden" name="p8_Url" value="${p8_Url }" /> 14 <input type="hidden" name="p9_SAF" value="${p9_SAF }" /> 15 <input type="hidden" name="pa_MP" value="${pa_MP }" /> 16 <input type="hidden" name="pr_NeedResponse" value="${pr_NeedResponse }" /> 17 <input type="hidden" name="hmac" value="${hmac }" /> 18 <input type="submit" value="確認支付" /> 19 </form>
這是銀行支付頁面,而後支付成功以後會跳入回調的地址,也在提交數據中包含(支付成功,自動執行該方法,前提:必須配置好,否則回調以後,出現404,可是此時已經支付成功了)
回調地址也做爲數據傳遞給了第三方平臺
Callback就是回調地址:支付成功以後,跳入該地址:因此須要配置好
回調action(在該action中,能夠完成支付成功以後須要進行的操做):
1 package util; 2 import java.util.ResourceBundle; 3 import org.apache.struts2.ServletActionContext; 4 import org.model.Orders; 5 import org.service.OrderService; 6 7 import com.opensymphony.xwork2.ActionSupport; 8 //支付完成以後調用的回調方法 該action會在支付成功後 進行調用----- 支付公司(第三方平臺 易寶支付) 、客戶 都將調用該action 9 //回調地址:http://localhost:8888/shop/CallBack 須要對該action進行配置 10 public class PayOrderCallBackAction extends ActionSupport { 11 //建立orderservice 而且完成注入 在訂單支付成功以後 須要調用方法 修改訂單標誌位 12 private OrderService orderService; 13 public void setOrderService(OrderService orderService) { 14 this.orderService = orderService; 15 } 16 public String execute()throws Exception{ 17 System.out.println("支付成功,(進入)執行回調action"); 18 // 得到回調全部數據 19 String p1_MerId = ServletActionContext.getRequest().getParameter("p1_MerId"); 20 String r0_Cmd = ServletActionContext.getRequest().getParameter("r0_Cmd"); 21 String r1_Code = ServletActionContext.getRequest().getParameter("r1_Code"); 22 String r2_TrxId = ServletActionContext.getRequest().getParameter("r2_TrxId"); 23 String r3_Amt = ServletActionContext.getRequest().getParameter("r3_Amt"); 24 String r4_Cur = ServletActionContext.getRequest().getParameter("r4_Cur"); 25 String r5_Pid = ServletActionContext.getRequest().getParameter("r5_Pid"); 26 String r6_Order = ServletActionContext.getRequest().getParameter("r6_Order"); 27 String r7_Uid = ServletActionContext.getRequest().getParameter("r7_Uid"); 28 String r8_MP = ServletActionContext.getRequest().getParameter("r8_MP"); 29 String r9_BType = ServletActionContext.getRequest().getParameter("r9_BType"); 30 String rb_BankId = ServletActionContext.getRequest().getParameter("rb_BankId"); 31 String ro_BankOrderId = ServletActionContext.getRequest().getParameter("ro_BankOrderId"); 32 String rp_PayDate = ServletActionContext.getRequest().getParameter("rp_PayDate"); 33 String rq_CardNo = ServletActionContext.getRequest().getParameter("rq_CardNo"); 34 String ru_Trxtime = ServletActionContext.getRequest().getParameter("ru_Trxtime"); 35 // 身份校驗 --- 判斷是否是支付公司通知你 36 String hmac = ServletActionContext.getRequest().getParameter("hmac"); 37 String keyValue = ResourceBundle.getBundle("merchantInfo").getString( 38 "keyValue"); 39 40 // 本身對上面數據進行加密 --- 比較支付公司發過來hamc 41 boolean isValid = PaymentUtil.verifyCallback(hmac, p1_MerId, r0_Cmd, 42 r1_Code, r2_TrxId, r3_Amt, r4_Cur, r5_Pid, r6_Order, r7_Uid, 43 r8_MP, r9_BType, keyValue); 44 if (isValid) { 45 /* 46 // 響應數據有效 47 if (r9_BType.equals("1")) { 48 // 瀏覽器重定向 49 ServletActionContext.getResponse().setContentType("text/html;charset=utf-8"); 50 ServletActionContext.getResponse().getWriter().println("<h1>付款成功!等待商城進一步操做!等待收貨...</h1>"); 51 } else if (r9_BType.equals("2")) { 52 // 服務器點對點 --- 支付公司通知你 53 System.out.println("付款成功!"); 54 // 修改訂單狀態 爲已付款 55 // 回覆支付公司 56 ServletActionContext.getResponse().getWriter().print("success"); 57 } 58 */ 59 //獲得session域中保存的訂單信息 60 Orders orders=(Orders) ServletActionContext.getRequest().getSession().getAttribute("Orders"); 61 //支付成功以後 須要激活訂單 修改訂單中的state字段爲1 表示該訂單用戶已經完成支付 62 this.orderService.orderReactivated(orders.getOid()); 63 //跳轉到支付結果頁面 給用戶反饋 64 ServletActionContext.getRequest().getRequestDispatcher("/payresult.jsp").forward(ServletActionContext.getRequest(),ServletActionContext.getResponse()); 65 } else { 66 // 數據無效 67 System.out.println("數據被篡改!"); 68 } 69 70 return NONE; 71 } 72 73 }
本代碼中,支付成功以後須要激活對應訂單,表示用戶完成該訂單的支付,至orders表中對應訂單的state字段爲1,而且跳頁給用戶反饋支付成功信息
讀秒以後,自動跳入反饋頁面/payresult.jsp
![](http://static.javashuo.com/static/loading.gif)
-----------------------------------------
讀取propperties文件中的內容
---------------------------------------------------------