Android平台下利用zxing实现二维码开发

  现在走在大街小巷都能看到二维码,而且最近由于项目需要,所以研究了下二维码开发的东西,开源的二维码扫描库主要有zxing和zbar,zbar在iPos平台上应用比较成熟,而在Android平台上主流还是用zxing库,因此这里主要讲述如何利用zxing进行二维码开发。

1.如何将zxing的Android源码导入工程。

  在导入zxing的android源码之前,先去官方下载zxing的源码:http://code.google.com/p/zxing/downloads/list

  我这里下载的是1.6版本的,我试验了几个版本,发现2.0以后的版本实际用起来没有1.6和1.7版本的好用,最后选择了1.6版本。

  zxing 1.6源码结构如下:

  其中android文件夹就是android平台下的官方例子。

  在导入之前先要对core文件下的源码进行编译,得到核心包core.jar。

  编译方法请参照:http://blog.163.com/yimigao@126/blog/static/671560502011611111116747/

  然后就可以导入android平台下的例子了,导入方法如下:

  1)打开Eclipse,新建android项目:(注意不要直接把android文件夹拷到workspace下导入,那样会无法导入)

  

  2)导入核心包core.jar。

  3)修改strings.xml文件。在导入core.jar之后工程还是会有错误:

  

  出现这种错误可能是由于字符错误导致的,只需要把所有的%s 和%f改成 %1$s和%1$f   即可。

  修改完之后重新清理项目,此时已经没有错误了:

  

  4)运行效果:

  

2.代码简化

  上面代码中,很多功能我们在自己的项目中都用不到,因此需要对其进行简化,至于如何简化这里就不赘述了,网上有很多教程。下面只给出简化后的结果:

  

  如果只进行二维码识别和二维码生成的话,只需要上面包中的文件。其中CaptureActivity.java是拍照取景的类,camera包下面的类主要与照相机相关的类,decoding和encoding是解码和编码相关的类,view是取景框相关的类。

3.将简化的zxing代码嵌入自己的工程。

  在自己的工程中嵌入简化的zxing代码即可实现二维码生成和识别功能。

  嵌入方法:

  1)将上述简化的代码拖到自己工程目录下;

  2)将values文件夹和raw文件夹复制自己工程目录下;

  3)建立CaptureActivity.java的布局文件capture.xml。

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent" >
  5.  
  6. <SurfaceView
  7. android:id="@+id/preview_view"
  8. android:layout_width="wrap_content"
  9. android:layout_height="wrap_content"
  10. android:layout_gravity="center" />
  11.  
  12. <com.zxing.view.ViewfinderView
  13. android:id="@+id/viewfinder_view"
  14. android:layout_width="wrap_content"
  15. android:layout_height="wrap_content" />
  16.  
  17. <RelativeLayout
  18. android:layout_width="fill_parent"
  19. android:layout_height="fill_parent"
  20. android:layout_gravity="center"
  21. android:orientation="vertical" >
  22.  
  23. <TextView
  24. android:layout_width="fill_parent"
  25. android:layout_height="wrap_content"
  26. android:layout_alignParentTop="true"
  27. android:layout_centerInParent="true"
  28. android:gravity="center"
  29. android:paddingBottom="10dp"
  30. android:paddingTop="10dp"
  31. android:text="Scan Barcode"
  32. android:textColor="@android:color/white"
  33. android:textSize="18sp"
  34. android:textStyle="bold" />
  35.  
  36. <Button
  37. android:id="@+id/btn_cancel_scan"
  38. android:layout_width="230dp"
  39. android:layout_height="40dp"
  40. android:layout_alignParentBottom="true"
  41. android:layout_centerInParent="true"
  42. android:layout_marginBottom="75dp"
  43. android:text="Cancel"
  44. android:textSize="15sp"
  45. android:textStyle="bold" />
  46.  
  47. </RelativeLayout>
  48.  
  49. </FrameLayout>

  3)导入core.jar包

  4)修改AndrodMainfest.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="com.qrcode"
  4. android:versionCode="1"
  5. android:versionName="1.0">
  6. <uses-sdk android:minSdkVersion="7" />
  7.  
  8. <uses-permission android:name="android.permission.VIBRATE" /> <!-- 震动权限 -->
  9. <uses-permission android:name="android.permission.CAMERA" />
  10. <uses-feature android:name="android.hardware.camera" /> <!-- 使用照相机权限 -->
  11. <uses-feature android:name="android.hardware.camera.autofocus" /> <!-- 自动聚焦权限 -->
  12.  
  13. <application android:icon="@drawable/icon" android:label="@string/app_name">
  14. <activity android:name=".MainActivity"
  15. android:label="@string/app_name">
  16. <intent-filter>
  17. <action android:name="android.intent.action.MAIN" />
  18. <category android:name="android.intent.category.LAUNCHER" />
  19. </intent-filter>
  20. </activity>
  21.  
  22. <!-- 隐藏键盘 --><!-- 全屏 -->
  23. <activity
  24. android:configChanges="orientation|keyboardHidden"
  25. android:name="com.zxing.activity.CaptureActivity"
  26. android:screenOrientation="portrait"
  27. android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
  28. android:windowSoftInputMode="stateAlwaysHidden" >
  29. </activity>
  30.  
  31. </application>
  32. </manifest>

  5)运行效果:

   

  在这里识别二维码之后是把结果返回到上一个activity显示,所以在MainActivity中调用方法是:

  1. Intent openCameraIntent = new Intent(MainActivity.this,CaptureActivity.class);
  2. startActivityForResult(openCameraIntent, 0);

  然后获取结果在onActivityResult中进行:

  1. @Override
  2. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  3. super.onActivityResult(requestCode, resultCode, data);
  4.  
  5. if (resultCode == RESULT_OK) {
  6. Bundle bundle = data.getExtras();
  7. String scanResult = bundle.getString("result");
  8. resultTextView.setText(scanResult);
  9. }
  10. }

  如果要直接在CaptureActivity中弹出识别结果,可以更改CaptureActivity.java的handleDecode方法:

  1. public void handleDecode(Result result, Bitmap barcode) {
  2. inactivityTimer.onActivity();
  3. playBeepSoundAndVibrate();
  4. String resultString = result.getText();
  5. //FIXME
  6. if (resultString.equals("")) {
  7. Toast.makeText(CaptureActivity.this, "Scan failed!", Toast.LENGTH_SHORT).show();
  8. }else {
  9. // System.out.println("Result:"+resultString);
  10. Intent resultIntent = new Intent();
  11. Bundle bundle = new Bundle();
  12. bundle.putString("result", resultString);
  13. resultIntent.putExtras(bundle);
  14. this.setResult(RESULT_OK, resultIntent);
  15. }
  16. CaptureActivity.this.finish();
  17. }

  上述代码是得到结果之后传给之前调用CaptureActivity的activity,所以如果要改的话只需要把else语句块下面的语句和最后一句finish注释掉,补上自己的代码就可以了。比如可以改成:

  1. public void handleDecode(Result result, Bitmap barcode) {
  2. inactivityTimer.onActivity();
  3. playBeepSoundAndVibrate();
  4. final String resultString = result.getText();
  5. //FIXME
  6. if (resultString.equals("")) {
  7. Toast.makeText(CaptureActivity.this, "Scan failed!", Toast.LENGTH_SHORT).show();
  8. }else {
  9. // System.out.println("Result:"+resultString);
  10. /*Intent resultIntent = new Intent();
  11. Bundle bundle = new Bundle();
  12. bundle.putString("result", resultString);
  13. resultIntent.putExtras(bundle);
  14. this.setResult(RESULT_OK, resultIntent);*/
  15.  
  16. AlertDialog resutlDialog = new AlertDialog.Builder(CaptureActivity.this).create();
  17. resutlDialog.setTitle("扫描结果");
  18. resutlDialog.setMessage(resultString);
  19. resutlDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener()
  20. {
  21. @Override
  22. public void onClick(DialogInterface dialog, int which)
  23. {
  24. dialog.dismiss();
  25. }
  26. });
  27. resutlDialog.show();
  28. }
  29. //CaptureActivity.this.finish();
  30. }

  我的工程源码下载:http://files.cnblogs.com/dolphin0520/QRCode.rar

3.关于zxing源码的若干问题。

  在实际使用过程中发现zxing源码存在一些问题,下面逐一来说一下:

  1)竖屏问题。

  zxing给出的官方例子是横屏的,但是对于手机实际上竖屏操作更加方便一点,如果要改成竖屏,需要修改以下几个文件:

  首先将AndrodMainfest.xml下CaptureActivity的配置改为竖屏:

  1. android:screenOrientation="portrait"

  然后需要修改CameraConfigurationManager.java下的setDesiredCameraParameters方法,该方法直接使用

  1. camera.setDisplayOrientation(90);

  来让屏幕旋转90度,这个办法在android 2.2版本以后是可行的,但是2.2之前的版本并没有提供这个接口,因此需要对sdk版本进行判断:

  1. if (Integer.parseInt(Build.VERSION.SDK) >=8)
  2. setDisplayOrientation(camera, 90);
  3. else
  4. {
  5. if (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
  6. {
  7. parameters.set("orientation", "portrait");
  8. parameters.set("rotation", 90);
  9. }
  10. if (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
  11. {
  12. parameters.set("orientation", "landscape");
  13. parameters.set("rotation", 90);
  14. }
  15. }

  在修改为竖屏之后发现取景框会发生拉伸,需要进行以下几点修改:

  在CameraManager.java中将:

  1. rect.left = rect.left * cameraResolution.x / screenResolution.x;
  2. rect.right = rect.right * cameraResolution.x / screenResolution.x;
  3. rect.top = rect.top * cameraResolution.y / screenResolution.y;
  4. rect.bottom = rect.bottom * cameraResolution.y / screenResolution.y;

  修改为:

  1. rect.left = rect.left * cameraResolution.y / screenResolution.x;
  2. rect.right = rect.right * cameraResolution.y / screenResolution.x;
  3. rect.top = rect.top * cameraResolution.x / screenResolution.y;
  4. rect.bottom = rect.bottom * cameraResolution.x / screenResolution.y;

  然后将DecodeHandler类中的方法decode改为:

  1. private void decode(byte[] data, int width, int height) {
  2. long start = System.currentTimeMillis();
  3. Result rawResult = null;
  4.  
  5. //modify here
  6. byte[] rotatedData = new byte[data.length];
  7. for (int y = 0; y < height; y++) {
  8. for (int x = 0; x < width; x++)
  9. rotatedData[x * height + height - y - 1] = data[x + y * width];
  10. }
  11. int tmp = width; // Here we are swapping, that's the difference to #11
  12. width = height;
  13. height = tmp;
  14.  
  15. PlanarYUVLuminanceSource source = CameraManager.get().buildLuminanceSource(rotatedData, width, height);
  16. BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
  17. try {
  18. rawResult = multiFormatReader.decodeWithState(bitmap);
  19. } catch (ReaderException re) {
  20. // continue
  21. } finally {
  22. multiFormatReader.reset();
  23. }
  24.  
  25. if (rawResult != null) {
  26. long end = System.currentTimeMillis();
  27. Log.d(TAG, "Found barcode (" + (end - start) + " ms):\n" + rawResult.toString());
  28. Message message = Message.obtain(activity.getHandler(), R.id.decode_succeeded, rawResult);
  29. Bundle bundle = new Bundle();
  30. bundle.putParcelable(DecodeThread.BARCODE_BITMAP, source.renderCroppedGreyscaleBitmap());
  31. message.setData(bundle);
  32. //Log.d(TAG, "Sending decode succeeded message...");
  33. message.sendToTarget();
  34. } else {
  35. Message message = Message.obtain(activity.getHandler(), R.id.decode_failed);
  36. message.sendToTarget();
  37. }
  38. }

  再将CameraConfigurationManager类中的方法initFromCameraParameters修改为:

  1. void initFromCameraParameters(Camera camera) {
  2. Camera.Parameters parameters = camera.getParameters();
  3. previewFormat = parameters.getPreviewFormat();
  4. previewFormatString = parameters.get("preview-format");
  5. Log.d(TAG, "Default preview format: " + previewFormat + '/' + previewFormatString);
  6. WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
  7. Display display = manager.getDefaultDisplay();
  8. screenResolution = new Point(display.getWidth(), display.getHeight());
  9. Log.d(TAG, "Screen resolution: " + screenResolution);
  10.  
  11. Point screenResolutionForCamera = new Point();
  12. screenResolutionForCamera.x = screenResolution.x;
  13. screenResolutionForCamera.y = screenResolution.y;
  14. // preview size is always something like 480*320, other 320*480
  15. if (screenResolution.x < screenResolution.y) {
  16. screenResolutionForCamera.x = screenResolution.y;
  17. screenResolutionForCamera.y = screenResolution.x;
  18. }
  19.  
  20. cameraResolution = getCameraResolution(parameters, screenResolutionForCamera);
  21.  
  22. //cameraResolution = getCameraResolution(parameters, screenResolution);
  23. Log.d(TAG, "Camera resolution: " + screenResolution);
  24. }

  最后将PlanarYUVLuminanceSource.java中的renderCroppedGreyscaleBitmap方法改为:

  1. public Bitmap renderCroppedGreyscaleBitmap() {
  2. int width = getWidth();
  3. int height = getHeight();
  4. int[] pixels = new int[width * height];
  5. byte[] yuv = yuvData;
  6. int inputOffset = top * dataHeight + left;
  7.  
  8. for (int y = 0; y < height; y++) {
  9. int outputOffset = y * width;
  10. for (int x = 0; x < width; x++) {
  11. int grey = yuv[inputOffset + x] & 0xff;
  12. pixels[outputOffset + x] = 0xFF000000 | (grey * 0x00010101);
  13. }
  14. inputOffset += dataHeight;
  15. }
  16.  
  17. Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
  18. bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
  19. return bitmap;
  20. }

  3)取景框的绘制

  取景框的绘制可以参照这篇博文:http://www.cnblogs.com/forrestsun/archive/2012/11/06/2757005.html

  4)闪光灯的开启和关闭

  如果需要开启和关闭闪光灯,在CameraManager.java中添加2个方法:

  1.   public void openLight() //打开闪光灯
  2. {
  3. if(camera!=null)
  4. {
  5. Parameters parameter=camera.getParameters();
  6. parameter.setFlashMode(Parameters.FLASH_MODE_TORCH);
  7. camera.setParameters(parameter);
  8. }
  9. }
  10.  
  11. public void closeLight() //关闭闪光灯
  12. {
  13. if(camera!=null)
  14. {
  15. Parameters parameter=camera.getParameters();
  16. parameter.setFlashMode(Parameters.FLASH_MODE_OFF);
  17. camera.setParameters(parameter);
  18. }
  19. }

  然后在CaptureActivity中的initCamera方法中打开闪光灯:

  1. CameraManager.get().openDriver(surfaceHolder);
  2. CameraManager.get().openLight(); //开闪光灯

  在需要的地方关闭闪光灯即可。

  5)连续扫描问题

  如果在识别二维码成功之后,需要连续多次扫描二维码,只需在扫描完成之后添加代码(在CaptureActivity的dandleDecode方法中添加):

  1. if(handler!=null) //实现连续扫描
  2. handler.restartPreviewAndDecode();

  比如:

  1. public void handleDecode(Result result, Bitmap barcode) {
  2. inactivityTimer.onActivity();
  3. playBeepSoundAndVibrate();
  4. final String resultString = result.getText();
  5. //FIXME
  6. if (resultString.equals("")) {
  7. Toast.makeText(CaptureActivity.this, "Scan failed!", Toast.LENGTH_SHORT).show();
  8. }else {
  9. // System.out.println("Result:"+resultString);
  10. /*Intent resultIntent = new Intent();
  11. Bundle bundle = new Bundle();
  12. bundle.putString("result", resultString);
  13. resultIntent.putExtras(bundle);
  14. this.setResult(RESULT_OK, resultIntent);*/
  15.  
  16. AlertDialog resutlDialog = new AlertDialog.Builder(CaptureActivity.this).create();
  17. resutlDialog.setTitle("扫描结果");
  18. resutlDialog.setMessage(resultString);
  19. resutlDialog.setButton(AlertDialog.BUTTON_POSITIVE, "打开链接", new DialogInterface.OnClickListener()
  20. {
  21. @Override
  22. public void onClick(DialogInterface dialog, int which)
  23. {
  24. dialog.dismiss();
  25. if(!isLegalUrl(resultString)) //如果url不合法
  26. {
  27. Toast.makeText(getApplicationContext(), "该链接不是合法的URL", Toast.LENGTH_SHORT).show();
  28. if(handler!=null) //实现连续扫描
  29. handler.restartPreviewAndDecode();
  30. return;
  31. }
  32. Intent intent = new Intent(); //打开链接
  33. intent.setAction("android.intent.action.VIEW");
  34. Uri content_url = Uri.parse(resultString);
  35. intent.setData(content_url);
  36. startActivity(intent);
  37. }
  38. });
  39.  
  40. resutlDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "取消", new DialogInterface.OnClickListener()
  41. {
  42. @Override
  43. public void onClick(DialogInterface dialog, int which)
  44. {
  45. dialog.dismiss();
  46. if(handler!=null) //实现连续扫描
  47. handler.restartPreviewAndDecode();
  48. }
  49. });
  50. resutlDialog.show();
  51. }
  52. //CaptureActivity.this.finish();
  53. }

  6)识别完成之后的震动。

  如果需要取消二维码识别之后的震动,只需要在CaptureActivity类的onResume方法中将vibrate 设置为false即可。

  7)修改取景框距屏幕顶部位置

  如果需要修改取景框距屏幕顶部位置,只需要修改CameraManager.java的getFramingRect方法,在getFramingRect方法中,

  1. int topOffset = (screenResolution.y - height) / 2

  这句是控制取景框到屏幕顶部的距离,若需要减小距屏幕顶部的距离,只需要将分母变大即可。

  8)取景框下方提示文字的绘制。

  在ViewfinderView.java的 Collection<ResultPoint> currentPossible = possibleResultPoints前面加入以下代码:

  

  1. TextPaint textPaint = new TextPaint();
    textPaint.setARGB(0xFF, 0xFF, 0xFF,0xFF); //字体颜色
  2. textPaint.setTextSize(TEXT_SIZE * density);
  3. textPaint.setAntiAlias(true); //设置抗锯齿,否则字迹会很模糊
    StaticLayout layout = new StaticLayout(getResources().getString(R.string.scan_text),textPaint,
  4. frame.right-frame.left,Alignment.ALIGN_NORMAL,1.0F,0.0F,true);
  5. canvas.translate(frame.left, (float) (frame.bottom + (float)TEXT_PADDING_TOP *density)); //绘制起始位置
  6. layout.draw(canvas);

  这里解释一下,textPaint.setAntiAlias(true); 是设置为抗锯齿,否则字体会很模糊。StaticLayout的第一个参数就是要绘制的字符串,第二个是画笔,第三个参数是设置每一行的宽度,即超过该宽度就换行,第四个是对齐方式。

  canvas.translate(frame.left, (float) (frame.bottom + (float)TEXT_PADDING_TOP *density))的参数是绘制字符串的起始位置。

  9)乱码问题

  在扫描一部分二维码时会出现乱码的情况,是由于编码的问题,可以参照这篇文章:

  http://www.2cto.com/kf/201209/152900.html

  如果不想编译core包,我的工程源码中的core包是已经改好了的,可以识别GBK二维码,需要的朋友可以直接拿去用。

  关于zxing 二维码识别的问题暂时就讨论这么多,有兴趣的朋友可以读源码深入研究一下。

Android平台下利用zxing实现二维码开发的更多相关文章

  1. (转载)Android平台下利用zxing实现二维码开发

    Android平台下利用zxing实现二维码开发 现在走在大街小巷都能看到二维码,而且最近由于项目需要,所以研究了下二维码开发的东西,开源的二维码扫描库主要有zxing和zbar,zbar在iPos平 ...

  2. 【转】Android平台下利用zxing实现二维码开发

    http://www.cnblogs.com/dolphin0520/p/3355728.html 现在走在大街小巷都能看到二维码,而且最近由于项目需要,所以研究了下二维码开发的东西,开源的二维码扫描 ...

  3. Android利用zxing生成二维码

    感谢大佬:https://blog.csdn.net/mountain_hua/article/details/80646089 **gayhub上的zxing可用于生成二维码,识别二维码 gayhu ...

  4. android 使用开源库zxing生成二维码,扫描二维码【转】

    转自:http://blog.csdn.net/qq_16064871/article/details/52422723 zxing是一个开放源码的,用Java实现的多种格式的1D/2D条码图像处理库 ...

  5. Java利用Zxing生成二维码

    Zxing是Google提供的关于条码(一维码.二维码)的解析工具,提供了二维码的生成与解析的方法,现在我简单介绍一下使用Java利用Zxing生成与解析二维码 1.二维码的生成 1.1 将Zxing ...

  6. 利用zxing生成二维码

    使用zxing类库可以很容易生成二维码QRCode,主要代码如下: private Bitmap createQRCode(String str,int width,int height) { Bit ...

  7. Android笔记之使用ZXing扫描二维码

    ZXing发布版下载地址:https://github.com/zxing/zxing/releases 为了能让官方Demo跑起来,先把ZXing核心部分core复制到自己的工程里 还要把andro ...

  8. (转载)Android项目实战(二十八):使用Zxing实现二维码及优化实例

    Android项目实战(二十八):使用Zxing实现二维码及优化实例 作者:听着music睡 字体:[增加 减小] 类型:转载 时间:2016-11-21我要评论 这篇文章主要介绍了Android项目 ...

  9. [置顶] xamarin android使用zxing扫描二维码

    好久没写了,这片文章篇幅不长,概述一下在xamarin android中用 ZXing.Net.Mobile库扫描二维码读取url的示例.扫码支付,扫码登录,App上各种各样的扫码,好像没个扫码的就有 ...

随机推荐

  1. vlookup函数基本使用--如何将两个Excel表中的数据匹配;excel表中vlookup函数使用方法将一表引到另一表

    vlookup函数基本使用--如何将两个Excel表中的数据匹配:excel表中vlookup函数使用方法将一表引到另一表 一.将几个学生的籍贯匹配出来‘ 二.使用查找与引用函数 vlookup 三. ...

  2. Java核心技术及面试指南 集合部分总的面试题归纳以及答案

    3.6.1ArrayList和LinkedList有什么差别?在哪种场景里应当用ArrayList(或LinkedList)? 大家如果学过数据结构,这个问题不难回答:前者是基于数组,数组比较擅长索引 ...

  3. ZooKeeper系列(4):ZooKeeper的配置文件详解

    ZooKeeper系列文章:https://www.cnblogs.com/f-ck-need-u/p/7576137.html#zk zkServer.sh读取的默认配置文件是$ZOOKEEPER_ ...

  4. linux添加字体

    执行命令发现输入命令查看字体列表是提示命令无效: 如上图可以看出,不仅没有中文字体,连字体库都没有,那么接下来就记录一下在Linux CentOS 7中如何安装字体库以及中文字体. 安装字体库 在Ce ...

  5. C#基础知识总结(三)

    摘要 关系表达式.逻辑表达式.分支结构的总结:if-else.if-else if-else.switch-case一.关系运算符 >,==,<… 关系表达式的结果是bool类型,true ...

  6. .NET 中的序列化 & 反序列化

    序列化:将对象的状态信息及类型信息,转换为一种易于传输或存储形式(流,即字节序列)的过程. 下图为序列化过程图示,图片来自微软官方文档: 反序列化:与序列化相反,将流转换为对象的过程. 常用的有二进制 ...

  7. 【Java每日一题】20170215

    20170214问题解析请点击今日问题下方的“[Java每日一题]20170215”查看(问题解析在公众号首发,公众号ID:weknow619) package Feb2017; public cla ...

  8. devtools进行热部署

    热部署的形式这里只介绍一种devtools devtools可以实现页面热部署(即页面修改后会立即生效,这个可以直接在application.properties文件中配置spring.thymele ...

  9. mybatis笔记01

    目录 1. Mybatis的介绍 2. 使用JDBC编码的分析 2.1 准备 2.3 程序代码 2.4 JDBC问题 3. Mybatis架构 4. Mybatis入门程序 4.1 mybatis下载 ...

  10. 腾讯云下的CentOS7 安装最新版Python3.7.0

    第一步下载Python3.7.0 刚开始我是在windows上下载之后 传到FTP服务器上的 后来发现使用以下命令可以更快捷地下载到服务器 *  wget https://www.python.org ...