基于mob短信验证的账号注册demo
来源:互联网 发布:起诉淘宝店无中文标签 编辑:程序博客网 时间:2024/05/16 23:58
////////////////////2016/05/14////////////////////////
/////////////////////by xbw//////////////////////////////
/////////////////eclipse api 21/////////////////////
快期末考试了,把之前做的项目整理一下,分享点demo,基于mob短信验证的账号注册demo,那个mob的key的注册直接去mob官网注册就好了,不多说了,先看一下效果图。
首先在mob官网下载短信验证sdk,咱这有demo,一会贴出来,直接复制demo里的sdk就好了,
首先在res文件中新建raw文件夹,把libs文件复制进去,再把smssdk_errors.xml文件复制到values文件夹中,
复制这几个文件到lib文件夹下,好了,开始敲代码,首先去AndroidManifest.xml文件下注册权限,
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.xbw.login" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.READ_SMS" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.GET_TASKS" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.BROADCAST_STICKY" /> <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.GET_TASKS" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.FLASHLIGHT" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.RESTART_PACKAGES" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.BROADCAST_STICKY" /> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" /> <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" /> <uses-permission android:name="android.permission.READ_LOGS" /> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BATTERY_STATS" /> <uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.USE_CREDENTIALS" /> <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" /> <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" /> <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" /> <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" /> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@android:style/Theme.Light.NoTitleBar" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="com.mob.tools.MobUIShell" android:configChanges="keyboardHidden|orientation|screenSize" android:theme="@android:style/Theme.Translucent.NoTitleBar" android:windowSoftInputMode="stateHidden|adjustResize" /> </application></manifest>
写注册页面布局activity_register.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/mainLayout" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#373447" > <ImageView android:id="@+id/user_logo" android:layout_width="100dp" android:layout_height="100dp" android:layout_centerHorizontal="true" android:layout_marginTop="10dp" android:contentDescription="@string/app_name" android:src="@drawable/ic_launcher" /> <TextView android:id="@+id/userNameTxt" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/user_logo" android:layout_centerHorizontal="true" android:layout_marginTop="5dp" android:text="XBW" android:textColor="#CEC9E7" android:textSize="16sp" /> <LinearLayout android:id="@+id/accountLayout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/userNameTxt" android:layout_centerHorizontal="true" android:layout_marginTop="30dp" android:gravity="center_vertical" android:orientation="horizontal" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/login_user" /> <EditText android:id="@+id/chat_register_username" android:layout_width="240dp" android:layout_height="wrap_content" android:background="@null" android:hint="手机号" android:padding="10dp" android:singleLine="true" android:textColor="#CEC9E7" android:textSize="16sp" /> </LinearLayout> <View android:id="@+id/line3" android:layout_width="240dp" android:layout_height="1dp" android:layout_below="@id/accountLayout" android:layout_centerHorizontal="true" android:background="#CEC9E7" /> <LinearLayout android:id="@+id/accountLayout2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/line3" android:layout_centerHorizontal="true" android:layout_marginTop="35dp" android:gravity="center_vertical" android:orientation="horizontal" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/login_user" /> <EditText android:id="@+id/chat_register_code" android:layout_width="240dp" android:layout_height="wrap_content" android:background="@null" android:hint="短信验证码" android:padding="10dp" android:singleLine="true" android:textColor="#CEC9E7" android:textSize="16sp" /> </LinearLayout> <View android:id="@+id/line1" android:layout_width="240dp" android:layout_height="1dp" android:layout_below="@id/accountLayout2" android:layout_centerHorizontal="true" android:background="#CEC9E7" /> <LinearLayout android:id="@+id/pwdLayout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/line1" android:layout_centerHorizontal="true" android:layout_marginTop="10dp" android:gravity="center_vertical" android:orientation="horizontal" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/login_pwd" /> <EditText android:id="@+id/chat_register_password" android:layout_width="204dp" android:layout_height="wrap_content" android:background="@null" android:hint="密码(最少6位)" android:inputType="textPassword" android:padding="10dp" android:singleLine="true" android:textColor="#CEC9E7" android:textSize="16sp" /> <CheckBox android:id="@+id/chat_register_password_checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginRight="5dp" android:button="@drawable/password_checkbox" /> </LinearLayout> <View android:id="@+id/line2" android:layout_width="240dp" android:layout_height="1dp" android:layout_below="@id/pwdLayout" android:layout_centerHorizontal="true" android:background="#CEC9E7" /> <LinearLayout android:id="@+id/pwdLayoutre" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@id/line2" android:layout_centerHorizontal="true" android:layout_marginTop="10dp" android:gravity="center_vertical" android:orientation="horizontal" > <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/login_pwd" /> <EditText android:id="@+id/chat_register_password2" android:layout_width="204dp" android:layout_height="wrap_content" android:background="@null" android:hint="确认密码" android:inputType="textPassword" android:padding="10dp" android:singleLine="true" android:textColor="#CEC9E7" android:textSize="16sp" /> <CheckBox android:id="@+id/chat_register_password_checkbox2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_marginRight="5dp" android:button="@drawable/password_checkbox" /> </LinearLayout> <View android:id="@+id/line4" android:layout_width="240dp" android:layout_height="1dp" android:layout_below="@id/pwdLayoutre" android:layout_centerHorizontal="true" android:background="#CEC9E7" /> <Button android:id="@+id/chat_register_signup_btn" android:layout_width="240dp" android:layout_height="wrap_content" android:layout_alignLeft="@+id/line2" android:layout_alignParentBottom="true" android:layout_marginBottom="26dp" android:background="#312E3F" android:padding="10dp" android:text="注册" android:textColor="#CEC9E7" android:textSize="20dp" android:textStyle="bold" /> <Button android:id="@+id/chat_register_sendmsg_btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignLeft="@+id/line3" android:layout_alignRight="@+id/line3" android:layout_below="@+id/line3" android:layout_marginTop="7dp" android:background="@drawable/btn_long_red" android:text="发送短信验证码" /></RelativeLayout>
素材等都在我的demo里了,需要的拿去。
短信验证我们用到了自动填充短信验证码,还有发送验证码后60秒短信倒计时;
我们需要写两个类
SmsContent.java 自动填充短信验证码
package com.xbw.login;import java.util.ArrayList;import java.util.regex.Matcher;import java.util.regex.Pattern;import android.app.Activity;import android.database.ContentObserver;import android.database.Cursor;import android.net.Uri;import android.os.Handler;import android.widget.EditText;public class SmsContent extends ContentObserver {public static final String SMS_URI_INBOX = "content://sms/inbox";private Activity activity = null;private String smsContent = "";private EditText verifyText = null;public SmsContent(Activity activity, Handler handler, EditText verifyText) {super(handler);this.activity = activity;this.verifyText = verifyText;}@SuppressWarnings("deprecation")@Overridepublic void onChange(boolean selfChange) {super.onChange(selfChange);Cursor cursor = null;// 光标// 读取收件箱中指定号码的短信cursor = activity.managedQuery(Uri.parse(SMS_URI_INBOX), new String[] {"_id", "address", "body", "read" }, "address=? and read=?",new String[] { "106571207117008", "0" }, "date desc");//mob短信验证号码if (cursor != null) {// 如果短信为未读模式cursor.moveToFirst();if (cursor.moveToFirst()) {String smsbody = cursor.getString(cursor.getColumnIndex("body"));System.out.println("smsbody=======================" + smsbody);String pattern = "[1-9]\\d*";Pattern p = Pattern.compile(pattern);Matcher m = p.matcher(smsbody.toString());ArrayList al =new ArrayList();while(m.find()){al.add(m.group(0));}if(!al.isEmpty())verifyText.setText(al.get(0).toString());}}}}
TimeCountUtil.java倒计时
package com.xbw.login;import android.annotation.SuppressLint;import android.app.Activity;import android.graphics.Color;import android.os.CountDownTimer;import android.text.Spannable;import android.text.SpannableString;import android.text.style.ForegroundColorSpan;import android.widget.Button;public class TimeCountUtil extends CountDownTimer { private Activity mActivity; private Button btn;//按钮// 在这个构造方法里需要传入三个参数,一个是Activity,一个是总的时间millisInFuture,一个是countDownInterval,然后就是你在哪个按钮上做这个是,就把这个按钮传过来就可以了 public TimeCountUtil( Activity mActivity,long millisInFuture, long countDownInterval,Button btn) { super(millisInFuture, countDownInterval); this.mActivity = mActivity; this.btn =btn; } @SuppressLint("NewApi") @Override public void onTick(long millisUntilFinished) { btn.setClickable(false);//设置不能点击 btn.setText(millisUntilFinished / 1000 + "秒后可重新发送");//设置倒计时时间//设置按钮为灰色,这时是不能点击的 btn.setBackground(mActivity.getResources().getDrawable(R.drawable.btn_long_white)); Spannable span = new SpannableString(btn.getText().toString());//获取按钮的文字 span.setSpan(new ForegroundColorSpan(Color.RED), 0, 2, Spannable.SPAN_INCLUSIVE_EXCLUSIVE);//讲倒计时时间显示为红色 btn.setText(span); } @SuppressLint("NewApi") @Override public void onFinish() { btn.setText("重新获取验证码"); btn.setClickable(true);//重新获得点击 btn.setBackground(mActivity.getResources().getDrawable(R.drawable.btn_long_red));//还原背景色 } }
package com.xbw.login;import java.util.regex.Matcher;import java.util.regex.Pattern;import android.annotation.SuppressLint;import android.app.Activity;import android.app.Dialog;import android.net.Uri;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.text.Editable;import android.text.TextUtils;import android.text.TextWatcher;import android.text.method.HideReturnsTransformationMethod;import android.text.method.PasswordTransformationMethod;import android.util.Log;import android.view.View;import android.view.View.OnClickListener;import android.view.WindowManager;import android.widget.Button;import android.widget.CheckBox;import android.widget.CompoundButton;import android.widget.CompoundButton.OnCheckedChangeListener;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;import cn.smssdk.EventHandler;import cn.smssdk.SMSSDK;public class MainActivity extends Activity {private EditText mUsernameET;private EditText mPasswordET;private EditText mCodeET;private EditText mPasswordET2;private Button mSendmsgBtn;private Button mSignupBtn;private CheckBox mPasswordCB;private CheckBox mPasswordCB2;private String phone_number = "";private boolean success = false;Dialog dialog;SmsContent content;// private SmsReceiver smsReceiver;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);// 沉浸式状态栏getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);// 沉浸式状态栏setContentView(R.layout.activity_register);initView();SMSSDK.initSDK(this, mob_APPKEY, mob_APPSECRET);//mob的keyEventHandler eh = new EventHandler() {@Overridepublic void afterEvent(int event, int result, Object data) {Message msg = new Message();msg.arg1 = event;msg.arg2 = result;msg.obj = data;handlersms.sendMessage(msg);}};SMSSDK.registerEventHandler(eh);}@SuppressLint("NewApi")private void initView() {mUsernameET = (EditText) findViewById(R.id.chat_register_username);mPasswordET = (EditText) findViewById(R.id.chat_register_password);mPasswordET2 = (EditText) findViewById(R.id.chat_register_password2);mCodeET = (EditText) findViewById(R.id.chat_register_code);mSendmsgBtn = (Button) findViewById(R.id.chat_register_sendmsg_btn);mSignupBtn = (Button) findViewById(R.id.chat_register_signup_btn);mPasswordCB = (CheckBox) findViewById(R.id.chat_register_password_checkbox);mPasswordCB2 = (CheckBox) findViewById(R.id.chat_register_password_checkbox2);mUsernameET.addTextChangedListener(myWatchers);mCodeET.addTextChangedListener(myWatcher);mPasswordCB.setOnCheckedChangeListener(new OnCheckedChangeListener() {@Overridepublic void onCheckedChanged(CompoundButton arg0, boolean arg1) {// TODO Auto-generated method stubif (arg1) {mPasswordCB.setChecked(true);mPasswordET.setTransformationMethod(HideReturnsTransformationMethod.getInstance());} else {mPasswordCB.setChecked(false);mPasswordET.setTransformationMethod(PasswordTransformationMethod.getInstance());}}});mPasswordCB2.setOnCheckedChangeListener(new OnCheckedChangeListener() {@Overridepublic void onCheckedChanged(CompoundButton arg0, boolean arg1) {// TODO Auto-generated method stubif (arg1) {mPasswordCB2.setChecked(true);mPasswordET2.setTransformationMethod(HideReturnsTransformationMethod.getInstance());} else {mPasswordCB2.setChecked(false);mPasswordET2.setTransformationMethod(PasswordTransformationMethod.getInstance());}}});mSendmsgBtn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO 自动生成的方法存根if (TextUtils.isEmpty(mUsernameET.getText().toString())) {Toast.makeText(getApplicationContext(), "手机号码不能为空", 1).show();} else if (!judgephone(mUsernameET.getText().toString())) {Toast.makeText(getApplicationContext(), "请输入正确的手机号码", 1).show();} else {new Thread() {public void run() {try {SMSSDK.getVerificationCode("86", mUsernameET.getText().toString());success = true;} catch (Exception e) {e.printStackTrace();} finally {}}}.start();// //////////////////////////////////////////////////////////////////////////////////}}});mSignupBtn.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View arg0) {// TODO Auto-generated method stubfinal String userName = mUsernameET.getText().toString().trim();final String password = mPasswordET.getText().toString().trim();final String password2 = mPasswordET2.getText().toString().trim();final String code = mCodeET.getText().toString().trim();if (TextUtils.isEmpty(userName)) {Toast.makeText(getApplicationContext(), "请输入手机号",Toast.LENGTH_SHORT).show();} else if (!judgephone(userName)) {Toast.makeText(getApplicationContext(), "请输入正确的手机号",Toast.LENGTH_SHORT).show();} else if (TextUtils.isEmpty(password)) {Toast.makeText(getApplicationContext(), "请输入密码",Toast.LENGTH_SHORT).show();} else if (password.length() < 6) {Toast.makeText(getApplicationContext(), "密码长度不小于6位",Toast.LENGTH_SHORT).show();} else if (TextUtils.isEmpty(password2)) {Toast.makeText(getApplicationContext(), "请确认输入密码",Toast.LENGTH_SHORT).show();} else if (!password.equals(password2)) {Toast.makeText(getApplicationContext(), "两次密码输入不一致",Toast.LENGTH_SHORT).show();} else {// 插入数据库}}});mSignupBtn.setClickable(false);mSignupBtn.setBackground(MainActivity.this.getResources().getDrawable(R.color.sign_up_btn_normal));mSendmsgBtn.setText("发送验证码");mSendmsgBtn.setClickable(false);mSendmsgBtn.setBackground(this.getResources().getDrawable(R.drawable.btn_long_white));}Handler handlersms = new Handler() {@SuppressLint("NewApi")@SuppressWarnings("deprecation")@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);int event = msg.arg1;int result = msg.arg2;Object data = msg.obj;Log.e("event", "event=" + event);if (result == SMSSDK.RESULT_COMPLETE) {if (event == SMSSDK.EVENT_SUBMIT_VERIFICATION_CODE) {if (result == SMSSDK.RESULT_COMPLETE) {Toast.makeText(getApplicationContext(), "短信验证成功",Toast.LENGTH_SHORT).show();mSignupBtn.setBackground(MainActivity.this.getResources().getDrawable(R.color.sign_up_btn_press));mSignupBtn.setClickable(true);}} else if (event == SMSSDK.EVENT_GET_VERIFICATION_CODE) {Toast.makeText(getApplicationContext(), "验证码已经发送",Toast.LENGTH_SHORT).show();TimeCountUtil timeCountUtil = new TimeCountUtil(MainActivity.this, 60000, 1000, mSendmsgBtn);timeCountUtil.start();// smsReceiver = new SmsReceiver();// registerBroadcastReceiver();content = new SmsContent(MainActivity.this, new Handler(),mCodeET);// 注册短信变化监听getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, content);// dialog.dismiss();} else if (event == SMSSDK.RESULT_ERROR) {Toast.makeText(getApplicationContext(), "------", 1000).show();}} else {((Throwable) data).printStackTrace();Toast.makeText(getApplicationContext(), "错误" + data, 10000).show();}dialog.dismiss();}};TextWatcher myWatcher = new TextWatcher() {@Overridepublic void afterTextChanged(Editable s) {if (mCodeET.getText().length() == 4&& judgephone(mUsernameET.getText().toString()) && success) {new Thread() {public void run() {try {SMSSDK.submitVerificationCode("86", mUsernameET.getText().toString(), mCodeET.getText().toString());} catch (Exception e) {e.printStackTrace();} finally {}}}.start();}// //////////////////////////////////////////////////////////////////////////////////}@Overridepublic void beforeTextChanged(CharSequence s, int start, int count,int after) {// TODO 自动生成的方法存根}@Overridepublic void onTextChanged(CharSequence s, int start, int before,int count) {// TODO 自动生成的方法存根}};TextWatcher myWatchers = new TextWatcher() {@SuppressLint("NewApi")@Overridepublic void afterTextChanged(Editable s) {if (mUsernameET.getText().length() == 11) {if (judgephone(mUsernameET.getText().toString())) {// 从数据库判断此账号是否存在}} else {success = false;mSignupBtn.setClickable(false);mSignupBtn.setBackground(MainActivity.this.getResources().getDrawable(R.color.sign_up_btn_normal));}// //////////////////////////////////////////////////////////////////////////////////}@Overridepublic void beforeTextChanged(CharSequence s, int start, int count,int after) {// TODO 自动生成的方法存根}@Overridepublic void onTextChanged(CharSequence s, int start, int before,int count) {// TODO 自动生成的方法存根}};public boolean judgephone(String phone) {String str = "";str = phone;String pattern = "(13\\d|14[57]|15[^4,\\D]|17[678]|18\\d)\\d{8}|170[059]\\d{7}";Pattern r = Pattern.compile(pattern);Matcher m = r.matcher(str);return m.matches();}public void back(View view) {finish();}@Overrideprotected void onDestroy() {super.onDestroy();SMSSDK.unregisterAllEventHandler();if (content != null)this.getContentResolver().unregisterContentObserver(content);// stopBroadcastReceiver();}}最后的正则表达式匹配手机号多余了,mob的自带了,数据库还需要自己搭建,这就不贴了;
demo传送门
0 1
- 基于mob短信验证的账号注册demo
- 集成mob的SMSSDK获取短信验证码的Demo
- 【demo记录】mob短信验证(GUI和无GUI)
- MOB无GUI短信验证DEMO(记录帖)
- mob短信验证码SMSSDK的使用
- Mob实现短信验证-免费的哦
- mob短信验证码SMSSDK的错误代码
- 使用MOB免费短信验证码进行登录(注册)
- 自定义MOB短信短信注册
- Mob- 短信验证使用
- Mob短信验证
- Mob短信验证
- mob短信验证
- Mob短信验证
- 短信验证(mob)
- Mob短信验证
- MOB短信验证
- Mob短信验证
- 从PAXOS到Zookeeper分布式一致性原理与实践
- 第十、十一周项目
- 学习SpringMVC(三)之RequestParam
- 初识软件工程-软件工程的基本概念
- 新版本 Linux Deploy 部署 Debian 提示 E:the selected extractor cannot be found:ar 问题
- 基于mob短信验证的账号注册demo
- 四点起床
- mybatis 使用oracle char 字段查询返回结果总是null
- 第十二周项目1.1实现复数类中的运算符重载(成员函数)
- Vi 编辑器的三种模式
- Linux文件远程拷贝命令scp的使用
- Hadoop安装教程_单机/伪分布式配置_Hadoop2.6.0/Ubuntu14.04
- Java PathFinder(一) Java PathFinder基于Eclipse的安装配置及使用
- 一种为使用Log4j的分布式应用提供云端日志服务的方法