JAVAEE網上商城項目總結

發送郵件實現(使用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"/>

 

鼠標移到button或者超連接上,沒有變手型指針,那麼在該標籤中加入style="cursor: pointer"屬性 便可完成變化,好比

<td class="cart_td_8" width="10"><a id="${entry.product.pid}" onclick="GetPid(this)">刪除</a></td>

中沒有href=「」屬性,那麼鼠標移到上邊就不會變成小手的形狀

---------------------------------------------------------------
使用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傳遞數組給後臺(一)

代碼實踐

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>

表單提交時候,https://www.yeepay.com/app-merchant-proxy/node

這是第三方平臺(易寶支付)的地址,會根據你選擇的銀行信息(提交數據中包含),跳轉到指定銀行支付頁面

 

 

 

 

這是銀行支付頁面,而後支付成功以後會跳入回調的地址,也在提交數據中包含(支付成功,自動執行該方法,前提:必須配置好,否則回調以後,出現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

 -----------------------------------------

讀取propperties文件中的內容

 

 

 ---------------------------------------------------------

相關文章
相關標籤/搜索