二、
新建小程序注冊模塊,配置好注冊頁面。
regist.wxml
<view> <view class="login-icon"> <image class="login-img" src="../resource/images/dsp1.jpg"></image> </view> <view class="login-from"> <form bindsubmit='doRegist'> <!--賬號--> <view class="inputView"> <image class="nameImage" src="../resource/images/username.png"></image> <label class="loginLabel">賬號</label> <input name="username" class="inputText" placeholder="請輸入賬號"/> </view> <view class="line"></view> <!--密碼--> <view class="inputView"> <image class="keyImage" src="../resource/images/password.png"></image> <label class="loginLabel">密碼</label> <input name="password" class="inputText" password="true" placeholder="請輸入密碼"/> </view> <!--按鈕--> <view> <button class="loginBtn" type="primary" form-type='submit'>注冊</button> </view> <view> <button class="goLoginBtn" type="warn" bindtap="goLoginPage">返回登錄</button> </view> </form> </view> </view>
regist.wxss
page {
background-color: whitesmoke;
}
.login-img {
width: 750rpx;
}
/*表單內容*/
.inputView {
background-color: white;
line-height: 45px;
}
/*輸入框*/
.nameImage, .keyImage {
margin-left: 22px;
width: 20px;
height: 20px;
}
.loginLabel {
margin: 15px 15px 15px 10px;
color: gray;
font-size: 15px;
}
.inputText {
float: right;
text-align: right;
margin-right: 22px;
margin-top: 11px;
font-size: 15px;
}
.line {
width: 100%;
height: 1px;
background-color: gainsboro;
margin-top: 1px;
}
/*按鈕*/
.loginBtn {
width: 80%;
margin-top: 35px;
}
.goLoginBtn {
width: 80%;
margin-top: 15px;
}
三、開發注冊用戶的接口
新建兩個工具類
package com.imooc.utils; /** * @Description: 自定義響應數據結構 * 這個類是提供給門戶,ios,安卓,微信商城用的 * 門戶接受此類數據后需要使用本類的方法轉換成對於的數據類型格式(類,或者list) * 其他自行處理 * 200:表示成功 * 500:表示錯誤,錯誤信息在msg字段中 * 501:bean驗證錯誤,不管多少個錯誤都以map形式返回 * 502:攔截器攔截到用戶token出錯 * 555:異常拋出信息 */ public class IMoocJSONResult { // 響應業務狀態 private Integer status; // 響應消息 private String msg; // 響應中的數據 private Object data; private String ok; // 不使用 public static IMoocJSONResult build(Integer status, String msg, Object data) { return new IMoocJSONResult(status, msg, data); } public static IMoocJSONResult ok(Object data) { return new IMoocJSONResult(data); } public static IMoocJSONResult ok() { return new IMoocJSONResult(null); } public static IMoocJSONResult errorMsg(String msg) { return new IMoocJSONResult(500, msg, null); } public static IMoocJSONResult errorMap(Object data) { return new IMoocJSONResult(501, "error", data); } public static IMoocJSONResult errorTokenMsg(String msg) { return new IMoocJSONResult(502, msg, null); } public static IMoocJSONResult errorException(String msg) { return new IMoocJSONResult(555, msg, null); } public IMoocJSONResult() { } public IMoocJSONResult(Integer status, String msg, Object data) { this.status = status; this.msg = msg; this.data = data; } public IMoocJSONResult(Object data) { this.status = 200; this.msg = "OK"; this.data = data; } public Boolean isOK() { return this.status == 200; } public Integer getStatus() { return status; } public void setStatus(Integer status) { this.status = status; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } public String getOk() { return ok; } public void setOk(String ok) { this.ok = ok; } }
package com.imooc.utils; import java.security.MessageDigest; import org.apache.commons.codec.binary.Base64; public class MD5Utils { /** * @Description: 對字符串進行md5加密 */ public static String getMD5Str(String strValue) throws Exception { MessageDigest md5 = MessageDigest.getInstance("MD5"); String newstr = Base64.encodeBase64String(md5.digest(strValue.getBytes())); return newstr; } public static void main(String[] args) { try { String md5 = getMD5Str("imooc"); System.out.println(md5); } catch (Exception e) { e.printStackTrace(); } } }
四、開發注冊用戶的接口
在com.imooc.controller包中新建RegistLoginController類,然后新建相應的Service類,主要是檢查用戶是否存在以及新增用戶。
UserService.class
package com.imooc.service; import com.imooc.pojo.Users; public interface UserService { /** * 判斷用戶名是否存在 * @param username * @return */ public boolean queryUsernameIsExist(String username); /** * 保存用戶(用戶注冊) * @param user */ public void saveUser(Users user); }
UserServiceImpl.class
package com.imooc.service; import org.n3r.idworker.Sid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.imooc.mapper.UsersMapper; import com.imooc.pojo.Users; public class UserServiceImpl implements UserService { @Autowired private UsersMapper userMapper; //導入工具包,使用戶生成的id是唯一的id @Autowired private Sid sid; @Transactional(propagation = Propagation.SUPPORTS) @Override public boolean queryUsernameIsExist(String username) { // TODO Auto-generated method stub Users user = new Users(); user.setUsername(username); Users result = userMapper.selectOne(user); return result == null ? false : true; } @Transactional(propagation = Propagation.REQUIRED) @Override public void saveUser(Users user) { // TODO Auto-generated method stub String userId = sid.nextShort(); user.setId(userId); userMapper.insert(user); } }
然后在RegistLoginController類中注入Service用於調用方法。
package com.imooc.controller; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.imooc.pojo.Users; import com.imooc.service.UserService; import com.imooc.utils.IMoocJSONResult; import com.imooc.utils.MD5Utils; @RestController public class RegistLoginController { @Autowired private UserService userService; @PostMapping("/regist") public IMoocJSONResult regist(@RequestBody Users user) throws Exception { //1、判斷用戶名和密碼必須不為空 if(StringUtils.isBlank(user.getUsername()) || StringUtils.isBlank(user.getPassword())) { return IMoocJSONResult.errorMsg("用戶名和密碼不能為空"); } //2、判斷用戶名是否存在 boolean usernameIsExist = userService.queryUsernameIsExist(user.getUsername()); //3、保存用戶,注冊信息 if(!usernameIsExist) { user.setNickname(user.getUsername()); user.setPassword(MD5Utils.getMD5Str(user.getPassword())); user.setFansCounts(0); user.setReceiveLikeCounts(0); user.setFollowCounts(0); userService.saveUser(user); }else { return IMoocJSONResult.errorMsg("用戶名已經存在,請換一個試試"); } return IMoocJSONResult.ok(); } }
此時,關於注冊的類開發完了,接下來使用swagger2構建restful接口測試,關於swagger2的好處有以下幾點:
接下來,在項目里導入swagger2,在common模塊中的pom文件上注入以下配置
在api模塊的com.imooc包中新建Swagger2類
package com.imooc; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.service.Contact; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration @EnableSwagger2 public class Swagger2 { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select() .apis(RequestHandlerSelectors.basePackage("com.imooc.controller")) .paths(PathSelectors.any()).build(); } private ApiInfo apiInfo() { // TODO Auto-generated method stub return new ApiInfoBuilder() // 設置頁面標題 .title("使用swagger2構建短視頻后端api接口文檔") // 設置聯系人 .contact(new Contact("imooc-zhaoBe", "http://www.imooc.com", "imooc@163.com")) // 描述 .description("歡迎訪問短視頻接口文檔,這里是描述信息") // 定義版本號 .version("1.0").build(); } }
接着 ,在各個類中分別配置導入swagger2
首先是RegistLoginController類的類名前和對應的方法名前
接着是作為返回值的Users類,特別是作為參數的username以及password
以下是正確配置完swagger2之后的界面。
五、小程序注冊與后端聯調
首先在app.js上配置全局變量(如果測試時是在手機上的話,需要填http內網穿透)
接着寫regist.js,用來完成聯調
const app = getApp() Page({ data: { }, doRegist: function(e){ var formObject = e.detail.value; var username = formObject.username; var password = formObject.password; //簡單驗證 if(username.length == 0 || password.length == 0){ wx.showToast({ title: '用戶名或密碼不能為空', icon: 'none', duration: 3000 }) }else{ var serverUrl = app.serverUrl; wx.showLoading({ title: '請等待...', }); wx.request({ url: serverUrl + '/regist', method: "POST", data: { username: username, password: password }, header: { 'content-type': 'application/json' // 默認值 }, success: function(res) { console.log(res.data); wx.hideLoading(); var status = res.data.status; if(status == 200){ wx.showToast({ title: '用戶注冊成功~!!!', icon: 'none', duration: 3000 }), app.userInfo = res.data.data; }else if(status == 500){ wx.showToast({ title: res.data.msg, icon: 'none', duration: 3000 }) } } }) } }, goLoginPage: function () { wx.navigateTo({ url: '../userLogin/login', }) } })
測試時,需要在app.json上加上"debug": true的配置,在上線時再刪除
六、用戶登錄
1、界面
login.wxml
<view> <view class="login-icon"> <image class="login-img" src="../resource/images/dsp1.jpg"></image> </view> <view class="login-from"> <form bindsubmit='doLogin'> <!--賬號--> <view class="inputView"> <image class="nameImage" src="../resource/images/username.png"></image> <label class="loginLabel">賬號</label> <input name="username" value='imooc' class="inputText" placeholder="請輸入賬號" /> </view> <view class="line"></view> <!--密碼--> <view class="inputView"> <image class="keyImage" src="../resource/images/password.png"></image> <label class="loginLabel">密碼</label> <input name="password" value='imooc' class="inputText" password="true" placeholder="請輸入密碼" /> </view> <!--按鈕--> <view> <button class="loginBtn" type="primary" form-type='submit'>登錄</button> </view> <view> <button class="goRegistBtn" type="warn" bindtap="goRegistPage">沒有賬號?點擊注冊</button> </view> </form> </view> </view>
login.wxss
page { background-color: whitesmoke; } .login-img { width: 750rpx; } /*表單內容*/ .inputView { background-color: white; line-height: 45px; } /*輸入框*/ .nameImage, .keyImage { margin-left: 22px; width: 20px; height: 20px; } .loginLabel { margin: 15px 15px 15px 10px; color: gray; font-size: 15px; } .inputText { float: right; text-align: right; margin-right: 22px; margin-top: 11px; font-size: 15px; } .line { width: 100%; height: 1px; background-color: gainsboro; margin-top: 1px; } /*按鈕*/ .loginBtn { width: 80%; margin-top: 35px; } .goRegistBtn { width: 80%; margin-top: 15px; }
2、編寫后端springboot接口
RegistLoginController.class
package com.imooc.controller; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.imooc.pojo.Users; import com.imooc.service.UserService; import com.imooc.utils.IMoocJSONResult; import com.imooc.utils.MD5Utils; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @RestController @Api(value = "用戶注冊登錄的接口",tags = {"注冊登錄的controller"}) public class RegistLoginController { @Autowired private UserService userService; @ApiOperation(value = "用戶注冊", notes = "用戶注冊的接口") @PostMapping("/regist") public IMoocJSONResult regist(@RequestBody Users user) throws Exception { //1、判斷用戶名和密碼必須不為空 if(StringUtils.isBlank(user.getUsername()) || StringUtils.isBlank(user.getPassword())) { return IMoocJSONResult.errorMsg("用戶名和密碼不能為空"); } //2、判斷用戶名是否存在 boolean usernameIsExist = userService.queryUsernameIsExist(user.getUsername()); //3、保存用戶,注冊信息 if(!usernameIsExist) { user.setNickname(user.getUsername()); user.setPassword(MD5Utils.getMD5Str(user.getPassword())); user.setFansCounts(0); user.setReceiveLikeCounts(0); user.setFollowCounts(0); userService.saveUser(user); }else { return IMoocJSONResult.errorMsg("用戶名已經存在,請換一個試試"); } user.setPassword(""); return IMoocJSONResult.ok(user); } @ApiOperation(value="用戶登錄", notes="用戶登錄的接口") @PostMapping("/login") public IMoocJSONResult login(@RequestBody Users user) throws Exception { String username = user.getUsername(); String password = user.getPassword(); // Thread.sleep(3000); // 1. 判斷用戶名和密碼必須不為空 if (StringUtils.isBlank(username) || StringUtils.isBlank(password)) { return IMoocJSONResult.ok("用戶名或密碼不能為空..."); } // 2. 判斷用戶是否存在 Users userResult = userService.queryUserForLogin(username, MD5Utils.getMD5Str(user.getPassword())); // 3. 返回 if (userResult != null) { userResult.setPassword(""); // UsersVO userVO = setUserRedisSessionToken(userResult); return IMoocJSONResult.ok(userResult); } else { return IMoocJSONResult.errorMsg("用戶名或密碼不正確, 請重試..."); } } }
UserServiceImpl.class
package com.imooc.service; import org.n3r.idworker.Sid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.imooc.mapper.UsersMapper; import com.imooc.pojo.Users; import tk.mybatis.mapper.entity.Example; import tk.mybatis.mapper.entity.Example.Criteria; @Service public class UserServiceImpl implements UserService { @Autowired private UsersMapper userMapper; //導入工具包,使用戶生成的id是唯一的id @Autowired private Sid sid; @Transactional(propagation = Propagation.SUPPORTS) @Override public boolean queryUsernameIsExist(String username) { // TODO Auto-generated method stub Users user = new Users(); user.setUsername(username); Users result = userMapper.selectOne(user); return result == null ? false : true; } @Transactional(propagation = Propagation.REQUIRED) @Override public void saveUser(Users user) { // TODO Auto-generated method stub String userId = sid.nextShort(); user.setId(userId); userMapper.insert(user); } @Transactional(propagation = Propagation.SUPPORTS) @Override public Users queryUserForLogin(String username, String password) { Example userExample = new Example(Users.class); Criteria criteria = userExample.createCriteria(); criteria.andEqualTo("username", username); criteria.andEqualTo("password", password); Users result = userMapper.selectOneByExample(userExample); return result; } }
3、小程序登錄與后端聯調
login.js
const app = getApp() Page({ data: { }, // onLoad: function (params) { // var me = this; // var redirectUrl = params.redirectUrl; // // debugger; // if (redirectUrl != null && redirectUrl != undefined && redirectUrl != '') { // redirectUrl = redirectUrl.replace(/#/g, "?"); // redirectUrl = redirectUrl.replace(/@/g, "="); // me.redirectUrl = redirectUrl; // } // }, // 登錄 doLogin: function (e) { // var me = this; var formObject = e.detail.value; var username = formObject.username; var password = formObject.password; // 簡單驗證 if (username.length == 0 || password.length == 0) { wx.showToast({ title: '用戶名或密碼不能為空', icon: 'none', duration: 3000 }) } else { var serverUrl = app.serverUrl; wx.showLoading({ title: '請等待...', }); // 調用后端 wx.request({ url: serverUrl + '/login', method: "POST", data: { username: username, password: password }, header: { 'content-type': 'application/json' // 默認值 }, success: function (res) { console.log(res.data); wx.hideLoading(); if (res.data.status == 200) { // 登錄成功跳轉 wx.showToast({ title: '登錄成功', icon: 'success', duration: 2000 }); app.userInfo = res.data.data; // // fixme 修改原有的全局對象為本地緩存 // app.setGlobalUserInfo(res.data.data); // 頁面跳轉 // var redirectUrl = me.redirectUrl; // if (redirectUrl != null && redirectUrl != undefined && redirectUrl != '') { // wx.redirectTo({ // url: redirectUrl, // }) // } else { // wx.redirectTo({ // url: '../mine/mine', // }) // } } else if (res.data.status == 500) { // 失敗彈出框 wx.showToast({ title: res.data.msg, icon: 'none', duration: 3000 }) } } }) } }, goRegistPage:function() { wx.navigateTo({ url: '../userRegist/regist', }) } })
注:在兩個頁面的js文件上都配置了跳轉到彼此的js函數。