java实现手机扫描二维码进行登录-程序员宅基地

技术标签: ViewUI  java  后端  javascript  

转自: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

转载于:https://www.cnblogs.com/nearpengju123/p/5185784.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_30624825/article/details/99535120

智能推荐

计算机的外围设备简介_计算机外围固定-程序员宅基地

文章浏览阅读6.1k次,点赞3次,收藏5次。外围设备介绍计算机的外围设备(简称外设)虽然很多,但按功能分大类只有四类:输入、输出、存储、网络通讯。有些专业计算机需要的外围设备也不尽相同,并不都需要这四类外围设备。外围设备可以按需要组装,有些专业计算机甚至可以将存储设备和主芯片集成到一片芯片上,从而不再需要外加存储设备。最早的计算机(那时还只能称为计算器,只能做简单运算,如ABC机和ENIAC机)输入只是一些拨码开关,只能输入数字(还得是二进_计算机外围固定

java 图片中加文字_java怎么在图片上加文字-程序员宅基地

文章浏览阅读1.5k次。java 图片中加文字_java怎么在图片上加文字

GBase8cGDCA认证模拟题题库(三)_如果需要打开delete语句的审计功能,需要开启下面哪个参数-程序员宅基地

文章浏览阅读720次,点赞20次,收藏6次。B 选项,在创建模式时,可以不指定模式名。C 选项,兼容模式可选值为 AB、C、PG.安装GBase 8c分布式集群时所需的配置文件gbase.yml,在解压GBase8cV5 S3.0.0BXX CentOS x86 64.tar.bz2压缩包生成的目录中得到。真值的有效文本值是: TRUE、t、"true'、y、yes'、"1'TRUE'、true、整数范围内1~2^63-1、整数范围内-1~-2^63。GBase 8c 使用create table 创建表时,不指定参数,默认是astore,行存表。_如果需要打开delete语句的审计功能,需要开启下面哪个参数

xml文件中几个名词_xml文件里面的名词-程序员宅基地

文章浏览阅读334次。1 xmlns是XML Namespaces的缩写,中文名称是XML(标准通用标记语言的子集)命名空间。 web-app是web.xml的根节点标签名称 version是版本的意思 xmlns是web.xml文件用到的命名空间 xmlns:xsi是指web.xml遵守xml规范 xsi:schemaLocation是指具体用到的schema资源_xml文件里面的名词

【OpenGL】中点圆、椭圆生成算法_用setpixel函数中点画圆算法代码c++-程序员宅基地

文章浏览阅读1.6w次,点赞12次,收藏69次。OpenGL 中点圆、椭圆生成算法_用setpixel函数中点画圆算法代码c++

HTML-CSS实现背景图片出现不同的位置_css背景图高度占据一半另一半有别的背景色-程序员宅基地

文章浏览阅读2.1k次。首先在HTML中写入div,命名为img,在这个div中加入一个span标签并命名为img-bg和img50(5星为50).<div class="img"> <span class="img-bg img50"></span> <span class="img-bg img45"></span> <span class="img-bg img40"></span> </div> 在css代码._css背景图高度占据一半另一半有别的背景色

随便推点

Android MPAndroidChart:动态添加统计数据线【8】_android 动态统计-程序员宅基地

文章浏览阅读3.9k次。Android MPAndroidChart:动态添加统计数据线【8】本文在附录相关文章6的基础上,动态的依次增加若干条统计折线(相当于批量增加数据点)。布局文件:

vmware中的linux虚拟机如何增加磁盘容量_linux虚拟机磁盘空间不足-程序员宅基地

文章浏览阅读6.3k次。vmware中 centos的磁盘大小 20G->30G现象:fdisk -l可以看到增大后的磁盘总量,但是需要增加分区并格式化然后挂载才能使用.一、vmware中的设置先关闭虚拟机vm->settings->hard disk->utilities->expand->输入大小(增加后的大小)二、启动虚拟机,进入命令行1、 fdisk /dev/sda进入命令行Comman_linux虚拟机磁盘空间不足

Hadoop2.7.3下Mysql8.0下Hive2.3.8的安装_hive2.3.8安装-程序员宅基地

文章浏览阅读927次。hive安装前提:1.基于hadoop2.7的完全分布式集群搭建完成hadoop2.7集群搭建2.MySQL8.0安装完成 安装centos7上MySQL8.0Hive2.3.8的安装下载链接:https://mirrors.tuna.tsinghua.edu.cn/apache/下滑找到hive点击进去点击hive2.3.9(hive2.3.9和hive2.3.8差别不大)下载画红线的也就是bin.tar.gz后缀的hive解压安装下载完成后通过xftp传到虚拟机上(基操不在赘述)_hive2.3.8安装

The‘grub-efi-amd64-signed‘ package failed to install into /target/. Without the GRUB boot loader,_the grub-efiamd64-signed' package failed to instal-程序员宅基地

文章浏览阅读430次,点赞8次,收藏4次。在进行安装的时候有一个是否联网的选择,选择链接网络,则在安装的时候,可以看到在安装过程中,它会主动下载grub-efi-amd64-signed' package,确确实实,我在安装详情里看到了它有这个的download过程以及update过程。_the grub-efiamd64-signed' package failed to install intotarget without the g

从零开始用 Python 构建一个简单的神经网络_从零开始搭建神经网络-程序员宅基地

文章浏览阅读451次。n_learn_data = int ( n_samples * 0.8 ) # 80% 的可用数据点 learn_data , test_data = samples [: n_learn_data ], samples [ - n_learn_data :] learn_labels , test_labels = labels [: n_learn_data ], labels [ - n_learn_data :]_从零开始搭建神经网络

PAT乙级-题解(Java)_找工作pat乙级-程序员宅基地

文章浏览阅读1.4k次。我的题解放在github仓库了(喜欢的话,记得star哈)下面是汇总导航,如果你只想看其中某个题的话,点击题解直达。乙级的题目每个题都是一个有趣的故事,引导你去思考解决问题的能力,不是单纯的刷题。然后只涉及数组,循环,判断,字符串等基础编程语言语法的知识,不会设计复杂的算法与数据结构。一开始可能会有点吃力,正常,但是如果你全部刷完,leetcode上部分简单题对你来说是小case了。甲级主要是算法与数据结构,乙级刷完了,也可刷甲级, 甲级的题目特别好,测试用例丰富如果是急需找工作,面试的话刷lee_找工作pat乙级