java實現手機掃描二維碼進行登錄


轉自:http://www.daxueit.com/article/2581.html

 

項目結構:

實現流程:

pc端:

1:打開二維碼登錄網頁index.html

2:index.html調用GetQrCodeServlet

3:GetQrCodeServlet干2件事

  a:生成隨機的uuid,是一個唯一標識,該標識貫穿整個流程

  b:生成二維碼圖片,二維碼信息:http://60.28.201.37:8380/QrCodeLoginPro/Login.html?uuid=" + uuid

4:index頁面展示二維碼

5:index頁面調用LongConnectionCheckServlet進行長連接輪詢操作,參數為uuid

6:LongConnectionCheckServlet只干1件事

  a:拿到uuid后循環檢查loginUserMap中uuid是否不為null。

7:如果為null則代表沒有登錄,index.html將繼續進行輪詢

  ps: LongConnectionCheckServlet 一個長連接請求檢測登錄狀態

    loginUserMap 是一個靜態的map結構的登錄池,uuid為key , 登錄信息為value

手機端:

1:掃描pc端的二維碼

2:打開二維碼中的網頁 http://60.28.201.37:8380/QrCodeLoginPro/Login.html?uuid=" + uuid

3:登錄,將uname upwd uuid 傳遞給登錄程序PhoneLoginServlet

4:PhoneLoginServlet干2件事

  a:檢測登錄

  b:登錄成功后將登錄信息插入到loginUserMap中去,uuid為key

pc端:

  1:繼續輪詢檢測uuid中是否為null

  2:登錄后的uuid中就不為null了,此時LongConnectionCheckServlet停止循環,返回登錄狀態。

代碼:

cn.kuwo下的3個servlet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package cn.kuwo;
 
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.kuwo.util.TwoDimensionCode;
 
/**
  * 生成二維碼圖片以及uuid
  * @author zijuntang
  *
  */
public class GetQrCodeServlet extends HttpServlet {
     private static final long serialVersionUID = 1L;
     protected void doGet(HttpServletRequest request,
             HttpServletResponse response) throws ServletException, IOException {
         doPost(request, response);
     }
     protected void doPost(HttpServletRequest request,
             HttpServletResponse response) throws ServletException, IOException {
         PrintWriter out = response.getWriter();
         
         //生成唯一ID
         int uuid = ( int ) (Math.random() * 100000 );
         //二維碼內容
         String content = "http://60.28.201.37:8380/QrCodeLoginPro/Login.html?uuid=" + uuid;
         //生成二維碼
         String imgName =  uuid + "_" + ( int ) ( new Date().getTime() / 1000 ) + ".png" ;
         String imgPath = "/home/web/apache/htdocs/QrCodeLogin/" + imgName;
         TwoDimensionCode handler = new TwoDimensionCode();
         handler.encoderQRCode(content, imgPath, "png" );
         
         //生成的圖片訪問地址
         String qrCodeImg = "http://60.28.201.37/QrCodeLogin/" + imgName;
         String jsonStr = "{\"uuid\":" + uuid + ",\"qrCodeImg\":\"" + qrCodeImg + "\"}" ;
         out.print(jsonStr);
         out.flush();
         out.close();
     }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package cn.kuwo;
 
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.kuwo.vo.LoginUserVo;
import cn.kuwo.vo.UserVo;
 
/**
  * 用長連接,檢查登錄狀態
  * @author zijuntang
  *
  */
public class LongConnectionCheckServlet extends HttpServlet {
     private static final long serialVersionUID = 1L;
     public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         doPost(request, response);
     }
     public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         String uuid = request.getParameter( "uuid" );
         String jsonStr = "" ;
         System.out.println( "in" );
         System.out.println( "uuid:" + uuid);
         long inTime = new Date().getTime();
         Boolean bool = true ;
         while (bool) {
             try {
                 Thread.sleep( 1000 );
             } catch (InterruptedException e) {
                 e.printStackTrace();
             }
             //檢測登錄
             UserVo userVo = LoginUserVo.getLoginUserMap().get(uuid);
             System.out.println( "userVo:" + userVo);
             if (userVo != null ){
                 bool = false ;
                 jsonStr = "{\"uname\":\"" +userVo.getUname()+ "\"}" ;
                 LoginUserVo.getLoginUserMap().remove(uuid);
             } else {
                 if ( new Date().getTime() - inTime > 5000 ){
                     bool = false ;
                 }
             }
         }
         System.out.println( "login ok : " + jsonStr);
         PrintWriter out = response.getWriter();
         out.print(jsonStr);
         out.flush();
         out.close();
     }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package cn.kuwo;
 
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.kuwo.vo.LoginUserVo;
import cn.kuwo.vo.UserVo;
 
/**
  * 二維碼手機端登錄
  * @author zijuntang
  *
  */
public class PhoneLoginServlet extends HttpServlet {
     private static final long serialVersionUID = 1L;
     public PhoneLoginServlet() {
         super ();
         // TODO Auto-generated constructor stub
     }
     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         doPost(request, response);
     }
     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
         String uuid = request.getParameter( "uuid" );
         String uname = request.getParameter( "uname" );
         String upwd = request.getParameter( "upwd" );
         System.out.println(uuid);
         System.out.println(uname);
         System.out.println(upwd);
         //TODO 驗證登錄
         boolean bool = true ;
         if (bool){
             //將登陸信息存入map
             UserVo userVo = LoginUserVo.getLoginUserMap().get(uuid);
             if (userVo == null ){
                 userVo = new UserVo();
                 userVo.setUname(uname);
                 userVo.setUpwd(upwd);
                 LoginUserVo.getLoginUserMap().put(uuid, userVo);
             }
         }
         PrintWriter out = response.getWriter();
         out.print(bool);
         out.flush();
         out.close();
     }
}

cn.kuwo.util包下的生成二維碼的封裝類

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
package cn.kuwo.util; 
   
import java.awt.Color; 
import java.awt.Graphics2D; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import javax.imageio.ImageIO; 
import jp.sourceforge.qrcode.QRCodeDecoder; 
import jp.sourceforge.qrcode.exception.DecodingFailedException; 
import com.swetake.util.Qrcode; 
   
public class TwoDimensionCode { 
       
     /**
      * 生成二維碼(QRCode)圖片
      * @param content 存儲內容
      * @param imgPath 圖片路徑
      */ 
     public void encoderQRCode(String content, String imgPath) { 
         this .encoderQRCode(content, imgPath, "png" , 7 ); 
    
       
     /**
      * 生成二維碼(QRCode)圖片
      * @param content 存儲內容
      * @param output 輸出流
      */ 
     public void encoderQRCode(String content, OutputStream output) { 
         this .encoderQRCode(content, output, "png" , 7 ); 
    
       
     /**
      * 生成二維碼(QRCode)圖片
      * @param content 存儲內容
      * @param imgPath 圖片路徑
      * @param imgType 圖片類型
      */ 
     public void encoderQRCode(String content, String imgPath, String imgType) { 
         this .encoderQRCode(content, imgPath, imgType, 7 ); 
    
       
     /**
      * 生成二維碼(QRCode)圖片
      * @param content 存儲內容
      * @param output 輸出流
      * @param imgType 圖片類型
      */ 
     public void encoderQRCode(String content, OutputStream output, String imgType) { 
         this .encoderQRCode(content, output, imgType, 7 ); 
    
   
     /**
      * 生成二維碼(QRCode)圖片
      * @param content 存儲內容
      * @param imgPath 圖片路徑
      * @param imgType 圖片類型
      * @param size 二維碼尺寸
      */ 
     public void encoderQRCode(String content, String imgPath, String imgType, int size) { 
         try
             BufferedImage bufImg = this .qRCodeCommon(content, imgType, size); 
               
             File imgFile = new File(imgPath);
             if (!imgFile.exists())
             {
                 imgFile.mkdirs();
             }
             // 生成二維碼QRCode圖片 
             ImageIO.write(bufImg, imgType, imgFile); 
         } catch (Exception e) { 
             e.printStackTrace(); 
        
    
   
     /**
      * 生成二維碼(QRCode)圖片
      * @param content 存儲內容
      * @param output 輸出流
      * @param imgType 圖片類型
      * @param size 二維碼尺寸
      */ 
     public void encoderQRCode(String content, OutputStream output, String imgType, int size) { 
         try
             BufferedImage bufImg = this .qRCodeCommon(content, imgType, size); 
             // 生成二維碼QRCode圖片 
             ImageIO.write(bufImg, imgType, output); 
         } catch (Exception e) { 
             e.printStackTrace(); 
        
    
       
     /**
      * 生成二維碼(QRCode)圖片的公共方法
      * @param content 存儲內容
      * @param imgType 圖片類型
      * @param size 二維碼尺寸
      * @return
      */ 
     private BufferedImage qRCodeCommon(String content, String imgType, int size) { 
         BufferedImage bufImg = null
         try
             Qrcode qrcodeHandler = new Qrcode(); 
             // 設置二維碼排錯率,可選L(7%)、M(15%)、Q(25%)、H(30%),排錯率越高可存儲的信息越少,但對二維碼清晰度的要求越小 
             qrcodeHandler.setQrcodeErrorCorrect( 'M' ); 
             qrcodeHandler.setQrcodeEncodeMode( 'B' ); 
             // 設置設置二維碼尺寸,取值范圍1-40,值越大尺寸越大,可存儲的信息越大 
             qrcodeHandler.setQrcodeVersion(size); 
             // 獲得內容的字節數組,設置編碼格式 
             byte [] contentBytes = content.getBytes( "utf-8" ); 
             // 圖片尺寸 
             int imgSize = 67 + 12 * (size - 1 ); 
             bufImg = new BufferedImage(imgSize, imgSize, BufferedImage.TYPE_INT_RGB); 
             Graphics2D gs = bufImg.createGraphics(); 
             // 設置背景顏色 
             gs.setBackground(Color.WHITE); 
             gs.clearRect( 0 , 0 , imgSize, imgSize); 
   
             // 設定圖像顏色> BLACK 
             gs.setColor(Color.BLACK); 
             // 設置偏移量,不設置可能導致解析出錯 
             int pixoff = 2
             // 輸出內容> 二維碼 
             if (contentBytes.length > 0 && contentBytes.length < 800 ) { 
                 boolean [][] codeOut = qrcodeHandler.calQrcode(contentBytes); 
                 for ( int i = 0 ; i < codeOut.length; i++) { 
                     for ( int j = 0 ; j < codeOut.length; j++) { 
                         if (codeOut[j][i]) { 
                             gs.fillRect(j * 3 + pixoff, i * 3 + pixoff, 3 , 3 ); 
                        
                    
                
             } else
                 throw new Exception( "QRCode content bytes length = " + contentBytes.length + " not in [0, 800]." ); 
            
             gs.dispose(); 
             bufImg.flush(); 
         } catch (Exception e) { 
             e.printStackTrace(); 
        
         return bufImg; 
    
       
     /**
      * 解析二維碼(QRCode)
      * @param imgPath 圖片路徑
      * @return
      */ 
     public String decoderQRCode(String imgPath) { 
         // QRCode 二維碼圖片的文件 
         File imageFile = new File(imgPath); 
         BufferedImage bufImg = null
         String content = null
         try
             bufImg = ImageIO.read(imageFile); 
             QRCodeDecoder decoder = new QRCodeDecoder(); 
             content = new String(decoder.decode( new TwoDimensionCodeImage(bufImg)), "utf-8" );  
         } catch (IOException e) { 
             System.out.println( "Error: " + e.getMessage()); 
             e.printStackTrace(); 
         } catch (DecodingFailedException dfe) { 
             System.out.println( "Error: " + dfe.getMessage()); 
             dfe.printStackTrace(); 
        
         return content; 
    
       
     /**
      * 解析二維碼(QRCode)
      * @param input 輸入流
      * @return
      */ 
     public String decoderQRCode(InputStream input) { 
         BufferedImage bufImg = null
         String content = null
         try
             bufImg = ImageIO.read(input); 
             QRCodeDecoder decoder = new QRCodeDecoder(); 
             content = new String(decoder.decode( new TwoDimensionCodeImage(bufImg)), "utf-8" );  
         } catch (IOException e) { 
             System.out.println( "Error: " + e.getMessage()); 
             e.printStackTrace(); 
         } catch (DecodingFailedException dfe) { 
             System.out.println( "Error: " + dfe.getMessage()); 
             dfe.printStackTrace(); 
        
         return content; 
    
   
     public static void main(String[] args) { 
         String imgPath = "D:/aaa/Michael_QRCode.png"
         String encoderContent = "http://60.28.201.37:8380/QrCodeLoginPro/Login.html"
         TwoDimensionCode handler = new TwoDimensionCode(); 
         handler.encoderQRCode(encoderContent, imgPath, "png" );
         
         
         /*
         System.out.println("========encoder success"); 
         String decoderContent = handler.decoderQRCode(imgPath); 
         System.out.println("解析結果如下:"); 
         System.out.println(decoderContent); 
         System.out.println("========decoder success!!!"); 
         */
    
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package cn.kuwo.util;
   
import java.awt.image.BufferedImage; 
import jp.sourceforge.qrcode.data.QRCodeImage; 
   
public class TwoDimensionCodeImage implements QRCodeImage { 
   
     BufferedImage bufImg; 
       
     public TwoDimensionCodeImage(BufferedImage bufImg) { 
         this .bufImg = bufImg; 
    
       
     @Override 
     public int getHeight() { 
         return bufImg.getHeight(); 
    
   
     @Override 
     public int getPixel( int x, int y) { 
         return bufImg.getRGB(x, y); 
    
   
     @Override 
     public int getWidth() { 
         return bufImg.getWidth(); 
    
   
}

cn.kuwo.vo下的2個數據層

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package cn.kuwo.vo;
 
import java.util.HashMap;
 
public class LoginUserVo {
     private static HashMap<String, UserVo> loginUserMap = new HashMap<String, UserVo>();
     private static LoginUserVo loginUserVo;
     public static LoginUserVo getVo(){
         if (loginUserVo == null ){
             loginUserVo = new LoginUserVo();
         }
         return loginUserVo;
     }
     public static HashMap<String, UserVo> getLoginUserMap() {
         return loginUserMap;
     }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package cn.kuwo.vo;
 
public class UserVo {
     private String uname;
     private String upwd;
     public String getUname() {
         return uname;
     }
     public void setUname(String uname) {
         this .uname = uname;
     }
     public String getUpwd() {
         return upwd;
     }
     public void setUpwd(String upwd) {
         this .upwd = upwd;
     }
}

2個網頁

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<!DOCTYPE html>
<html>
<head>
<meta charset= "UTF-8" >
<title>Insert title here</title>
</head>
<script type= "text/javascript" src= "js/jquery-1.11.0.min.js" ></script>
<body>
     <div id= "divCon" >
         <img src= "" id= "QrCodeImg" />
     </div>
</body>
<script type= "text/javascript" >
     $(document).ready(function() {
         var uuid;
         $.get( "/QrCodeLoginPro/GetQrCodeServlet" , function(data, status) {
             var obj = eval( "(" + data + ")" );
             //存儲UUID
             uuid = obj.uuid;
             //顯示二維碼
             $( "#QrCodeImg" ).attr( "src" , obj.qrCodeImg);
             //開始驗證登錄
             validateLogin();
         });
 
         function validateLogin(){
             $.get( "/QrCodeLoginPro/LongConnectionCheckServlet?uuid=" + uuid , function(data, status) {
                 if (data == "" ){
                     validateLogin();
                 } else {
                     var obj = eval( "(" + data + ")" );
                     alert( "登錄成功了:" + obj.uname);
                 }
             });
         }
     });
</script>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<!DOCTYPE html>
<html>
<head>
<meta charset= "UTF-8" >
<title>Insert title here</title>
</head>
<style>
.l_m_l {
     float : left;
     font-size: 14px;
     padding: 5px 0 0 0 ;
     width: 330px;
     color: # 414141 ;
}
 
.l_m_linput {
     height: 31px;
     position: relative;
     width: 300px;
     margin-bottom: 21px;
}
 
.l_m_linput span {
     float : left;
     width: 78px;
     text-align: right;
     line-height: 31px;
}
 
input {
     float : left;
     width: 195px;
     height: 24px;
     line-height: 24px;
     background: #f2f2f2;
     border: 1px solid #c4c4c4;
     padding: 2px 22px 2px 2px;
}
 
.l_mimacon {
     position: absolute;
     top: 6px;
     right: 6px;
     width: 15px;
     height: 17px;
     background: url(img/l_mimacon.png)
         no-repeat;
}
 
.l_peoplecon {
     position: absolute;
     top: 7px;
     right: 6px;
     width: 15px;
     height: 15px;
     background: url(img/l_peoplecon.png)
         no-repeat;
}
 
.l_m_lload a {
     display: block;
     width: 154px;
     height: 40px;
     background:
         url(img/l_loadingbtn.png)
         no-repeat;
     margin: 0 auto;
     line-height: 40px;
     text-align: center;
     font-size: 18px;
     color: #52340c;
     text-decoration: none;
}
</style>
<script type= "text/javascript" src= "js/jquery-1.11.0.min.js" ></script>
<body style= " border-top-right-radius: 0px !important; border-bottom-right-radius: 0px !important; border-bottom-left-radius: 0px !important; background-image: none !important; border: 0px !important; bottom: auto !important; float: none !important; height: auto !important; left: auto !important; line-height: 1.1em !important; margin: 0px !important; outline: 0px !important; overflow: visible !important; padding: 0px !important; position: static !important; right: auto !important; top: auto !important; vertical-align: baseline !important; width: auto !important; box-sizing: content-box !important; font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-size: 1em !important; min-height: inherit !important;">>
     <div style= "margin-left: 100px;" ><img src= "img/logo.png" /></div>
     <div >
         <p class = "l_m_linput" >
             <span><font color= "#fff" >用戶名:</font></span><input type= "text" id= "login_name" value= "zijuntang" ><em
                 class = "l_peoplecon" ></em>
         </p>
         <p class = "l_m_linput" >
             <span><font color= "#fff" >密碼:</font></span><input type= "password" id= "login_psw" value= "tangzijun" ><em
                 class = "l_mimacon" ></em>
         </p>
         <div class = "l_m_linput2" ></div>
         <div class = "l_m_lload" >
             <a href= "javascript:login();" >登錄</a>
         </div>
     </div>
</body>
<script type= "text/javascript" >
     //登錄
     function login(){
         $.post( "/QrCodeLoginPro/PhoneLoginServlet" , {
             uuid : $.getUrlParam( 'uuid' ),
             uname:$( "#login_name" ).val(),
             upwd:$( "#login_psw" ).val()
         }, function(data, status) {
             if (data == "" ){
                 alert( "登錄失敗" );
             } else {
                 alert( "登錄成功" );
             }
         });
     }
     
     //獲取網頁參數
     (function($){
         $.getUrlParam = function(name){
             var reg = new RegExp( "(^|&)" + name + "=([^&]*)(&|$)" );
             var r = window.location.search.substr( 1 ).match(reg);
             if (r!= null ) return unescape(r[ 2 ]); return null ;
         }
         })(jQuery);
</script>
</html>

web.xml配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?xml version= "1.0" encoding= "UTF-8" ?>
     id= "WebApp_ID" version= "2.5" >
     <display-name>QrCodeLoginPro</display-name>
     <welcome-file-list>
         <welcome-file>index.html</welcome-file>
     </welcome-file-list>
     <servlet>
         <description></description>
         <display-name>長連接檢查登錄狀態</display-name>
         <servlet-name>LongConnectionCheckServlet</servlet-name>
         <servlet- class >cn.kuwo.LongConnectionCheckServlet</servlet- class >
     </servlet>
     <servlet-mapping>
         <servlet-name>LongConnectionCheckServlet</servlet-name>
         <url-pattern>/LongConnectionCheckServlet</url-pattern>
     </servlet-mapping>
 
     <servlet>
         <description>獲取二維碼圖片以及uuid</description>
         <display-name>GetQrCodeServlet</display-name>
         <servlet-name>GetQrCodeServlet</servlet-name>
         <servlet- class >cn.kuwo.GetQrCodeServlet</servlet- class >
     </servlet>
     <servlet-mapping>
         <servlet-name>GetQrCodeServlet</servlet-name>
         <url-pattern>/GetQrCodeServlet</url-pattern>
     </servlet-mapping>
 
     <servlet>
         <description>手機掃描二維碼之后進行登錄</description>
         <display-name>PhoneLoginServlet</display-name>
         <servlet-name>PhoneLoginServlet</servlet-name>
         <servlet- class >cn.kuwo.PhoneLoginServlet</servlet- class >
     </servlet>
     <servlet-mapping>
         <servlet-name>PhoneLoginServlet</servlet-name>
         <url-pattern>/PhoneLoginServlet</url-pattern>
     </servlet-mapping>
</web-app>

此外還需要1個二維碼開源包:QRCode.jar

源碼下載:http://files.cnblogs.com/zijun/%E4%BA%8C%E7%BB%B4%E7%A0%81%E7%99%BB%E5%BD%95%E4%BE%8B%E5%AD%90.rar


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM