Springboot与手机的互动
使用手机号码的登录注册案例来简单了解下Springboot与手机的互动
pom.xml
要引入sms相关的依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.3.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.sikiedu</groupId>
<artifactId>ssm-login</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>ssm-login</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--引入腾讯短信SMS的jar包-->
<dependency>
<groupId>com.github.qcloudsms</groupId>
<artifactId>qcloudsms</artifactId>
<version>1.0.6</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
登录与注册页面以及配置文件
application.properties
#Tumeleaf编码
spring.thymeleaf.encoding=UTF-8
#热部署静态文件
spring.thymeleaf.cache=false
#使用HTML5标准
spring.thymeleaf.mode=HTML5
#连接数据库
spring.datasource.url=jdbc:mysql://::1:3306/ssm-login?serverTimezone=UTC&characterEncoding=utf-8&useSSL=true
spring.datasource.username=login
spring.datasource.password=123
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
login.html
<!doctype html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="css/bootstrap.min.css" type="text/css" rel="stylesheet">
<link href="css/font-awesome.min.css" type="text/javascript" rel="stylesheet">
<link href="css/bootsnav.css" type="text/css" rel="stylesheet">
<link href="css/normalize.css" type="text/css" rel="stylesheet">
<link href="css/css.css" rel="stylesheet" type="text/css">
<script src="js/jquery-1.11.0.min.js" type="text/javascript"></script>
<script src="js/bootstrap.min.js" type="text/javascript"></script>
<script src="js/bootsnav.js" type="text/javascript"></script>
<script src="js/jquery.js" type="text/javascript"></script>
<!--[if IE]><script src="js/html5.js"></script><![endif]-->
<title>登录</title>
</head>
<body class="logobg_style">
<div id="large-header" class="large-header login-page">
<canvas id="demo-canvas" width="1590" height="711"></canvas>
<div class="login-form">
<div class="login-content">
<h1 class="title_name">账户登录</h1>
<form th:action="@{~/userlogin}" method="post" role="form" id="form_login" class="login_padding">
<div class="form-group clearfix">
<div class="input-group">
<div class="input-group-addon">
<i class="icon_user"></i>
</div>
<!-- 手机号 -->
<input type="text" class="form-control" name="phone" id="username" placeholder="手机号" autocomplete="off">
</div>
</div>
<div class="form-group clearfix">
<div class="input-group">
<div class="input-group-addon">
<i class="icon_password"></i>
</div>
<!-- 密码 -->
<input type="password" class="form-control" name="password" id="password" placeholder="密码" autocomplete="off">
</div>
</div>
<div class=" textright">
<a href="#" class="forget">忘记密码?</a>
</div>
<div class="tishi"></div>
<div class="form-group">
<a href="javascript:;" type="submit" class="btn btn-danger btn-block btn-login" onClick="cliLogin()">
<i class="fa fa-sign-in"></i>
登录
</a>
</div>
<div class=" textright">
<a href="/register" class="forget">立即注册</a>
</div>
<!-- Implemented in v1.1.4 -->
<div class="form-group"></div>
</form>
</div>
</div>
</div>
<script src="js/TweenLite/TweenLite.min.js"></script>
<script src="js/TweenLite/EasePack.min.js"></script>
<script src="js/TweenLite/rAF.js"></script>
<script src="js/TweenLite/demo-1.js"></script>
<script type="text/javascript">
function cliLogin() {
$("#form_login").submit();
}
</script>
</body>
</html>
register.html(重要)
<!doctype html>
<html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="css/bootstrap.min.css" type="text/css" rel="stylesheet">
<link href="css/font-awesome.min.css" type="text/javascript" rel="stylesheet">
<link href="css/bootsnav.css" type="text/css" rel="stylesheet">
<link href="css/normalize.css" type="text/css" rel="stylesheet">
<link href="css/css.css" rel="stylesheet" type="text/css">
<script src="js/jquery-1.11.0.min.js" type="text/javascript"></script>
<script src="js/jquery.step.js"></script>
<script src="js/bootstrap.min.js" type="text/javascript"></script>
<script src="js/bootsnav.js" type="text/javascript"></script>
<script src="js/jquery.js" type="text/javascript"></script>
<!--[if IE]><script src="js/html5.js"></script><![endif]-->
<title>注册</title>
</head>
<body class="logobg_style">
<div id="large-header" class="large-header login-page">
<canvas id="demo-canvas" width="1590" height="711"></canvas>
<div class="Retrieve_style">
<div class="Retrieve-content step-body" id="myStep">
<h1 class="title_name">用户注册</h1>
<div class="step-header">
<ul>
<li>
<p>输入电话</p>
</li>
<li>
<p>确认密码</p>
</li>
<li>
<p>成功</p>
</li>
</ul>
</div>
<div class="step-content">
<div class="step-list login_padding">
<form role="form" id="form_login" class="">
<div class="form-group clearfix">
<div class="input-group col-lg-8 col-md-8 col-xs-8">
<div class="input-group-addon">
<i class="icon_phone"></i>
</div>
<!-- 手机号 -->
<input type="text" class="form-control text_phone" name="phone" id="phone" placeholder="你的手机号" autocomplete="off">
</div>
<div class="col-lg-4 col-md-4 col-xs-4 fl">
<!-- 发送验证码 -->
<input type="button" id="sms-input" class="btn_mfyzm" value="获取验证码" onclick="SendSMS()" />
</div>
</div>
<div class="form-group clearfix">
<div class="input-group">
<div class="input-group-addon">
<i class="icon_yanzhen"></i>
</div>
<!-- 短信验证码 -->
<input type="text" class="form-control" name="Verification" id="sms-code" placeholder="短信验证码" autocomplete="off">
</div>
</div>
<div class="tishi"></div>
</form>
<div class="form-group">
<!-- 下一步 -->
<button class="btn btn-danger btn-block btn-login" id="applyBtn">下一步</button>
</div>
</div>
<div class="step-list">
<form method="post" role="form" id="" class="login_padding">
<div class="form-group clearfix">
<div class="input-group">
<div class="input-group-addon">
<i class="icon_password"></i>
</div>
<input type="password" class="form-control" name="password" id="password" placeholder="重置密码" autocomplete="off">
</div>
</div>
<div class="form-group clearfix">
<div class="input-group">
<div class="input-group-addon">
<i class="icon_password"></i>
</div>
<input type="password" class="form-control" name="confirmpwd" id="confirmpwd" placeholder="再次密码" autocomplete="off">
</div>
</div>
<div class="tishis"></div>
<div class="form-group">
<a href="javascript:void(0);" type="submit" class="btn btn-danger btn-block btn-login" id="submitBtn">下一步</a>
</div>
</form>
</div>
<div class="step-list">
<div class="ok_style center">
<h2>
<img src="images/ok.png">
</h2>
<h5 class="color2 mtb20">
你已成功注册会员
<b id="sec">5</b>
秒后跳转到首页
</h5>
<a href="JavaScript:ovid()" class="btn btn-danger">首页</a>
<a href="JavaScript:ovid()" class="btn btn-primary">从新注册</a>
</div>
</div>
<form hidden="hidden" th:action="@{~/userRegister}" id="lain_form">
<input id="lain_username" name="phone"/>
<input id="lain_password" name="password"/>
</form>
</div>
</div>
</div>
</div>
<script src="js/TweenLite/TweenLite.min.js"></script>
<script src="js/TweenLite/EasePack.min.js"></script>
<script src="js/TweenLite/rAF.js"></script>
<script src="js/TweenLite/demo-1.js"></script>
<script src="js/layer/layer.js"></script>
<script type="text/javascript">
var time = 6;
var InterValObj;
//页面加载完成时 就调用
window.onload = function(){
document.getElementById("applyBtn").disabled = true;
}
function timer(){
if(time == 0){
//layer.msg("成功");
time = 6;
$('#sms-input').val("获取验证码");
document.getElementById("sms-input").disabled=false;
//删除定时器
window.clearInterval(InterValObj);
}else{
time--;
//layer.msg(time+"秒");
$('#sms-input').val(time+"秒");
}
}
var sms;
function SendSMS(){
//获取手机号
var telephone = $('#phone').val();
if(!(/^1(3|4|5|7|8)\d{9}$/.test(telephone))){
layer.msg("手机号码有误,请重填");
return;
};
//发送ajax请求
$.post(
//发送的url
[[@{~/sms}]],
//数据
{"phone":telephone},
//回调
function(data){
if(data.message){
$('#lain_username').val(telephone);
layer.msg("验证码发送成功请注意查收");
sms = data.sms;
}else{
layer.msg("该手机号已经注册过");
}
},
//数据格式
"json"
)
//设置按钮不再点击
$('#sms-input').attr("disabled","true");
//每隔一千毫秒调用一次
InterValObj = window.setInterval(timer,1000);
};
//验证码的离焦时间
$('#sms-code').blur(function(){
//判断验证码是否正确
var smsCode = $('#sms-code').val();
layer.msg(smsCode);
//拿到真正的验证码
if(smsCode == sms){
layer.msg("成功");
document.getElementById("applyBtn").disabled = false;
}else{
layer.msg("验证码输入有误");
$("#sms-code").focus();
}
});
</script>
</body>
</html>
后端代码逻辑
com.sikiedu.ssmlogin.controller
IndexController.java
package com.sikiedu.ssmlogin.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class IndexController {
//接收并处理index请求
@RequestMapping("/index")
public String index() {
return "index.html";
}
//显示login页面
@RequestMapping("/login")
public String login() {
return "login.html";
}
//显示register页面
@RequestMapping("/register")
public String register() {
return "register.html";
}
}
UserController.java(重要)
package com.sikiedu.ssmlogin.controller;
import java.io.IOException;
import java.util.Random;
import javax.servlet.http.HttpSession;
import org.json.JSONException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.github.qcloudsms.SmsSingleSender;
import com.github.qcloudsms.SmsSingleSenderResult;
import com.github.qcloudsms.httpclient.HTTPException;
import com.sikiedu.ssmlogin.entity.User;
import com.sikiedu.ssmlogin.service.UserService;
@Controller
public class UserController {
@Autowired
private HttpSession session;
@Autowired
private UserService userService;
//用户登录
@RequestMapping("/userlogin")
public String userLogin(User user,Model model) {
System.out.println(user);
boolean success = userService.findUserByPhoneAndPassword(user);
if(success) {
session.setAttribute("user", user);
return "redirect:/index";
}else {
model.addAttribute("error","用户名或者密码错误");
return "login.html";
}
}
//用户注册
@RequestMapping("/userRegister")
public String userRegister(User user) {
System.out.println(user);
userService.save(user);
return "redirect:/login";
}
@RequestMapping("/sms")
@ResponseBody
public String smsCode(String phone) {
System.out.println(phone);
//保护机制 如果用户注册过就不发送短信
/*
* 通过phone查找用户,如果查找到就把过程给掐断
*/
boolean success = userService.findUserByPhone(phone);
//没有对象success为true 有对象success为false
String json = null;
//该用户没有注册
if(success) {
//发送短信
String sms = SMS(phone);
json = "{\"message\":"+true+",\"sms\":\""+sms+"\"}";
}else {
json = "{\"message\":"+false+"}";
}
return json;
}
//发送短信
private String SMS(String phone) {
//手机
String phoneNumber = phone;
//短信的内容 [tLain公众号]该项目的验证码为:1234 如非本人操作请忽略本短信
int templateId = 200461;
//参数
String[] params = new String[1];
//验证码
String code = "";
Random r = new Random();
for (int i = 0; i < 4; i++) {
code += r.nextInt(10);
}
//将Code放入Session中
session.setAttribute("sms", code);
params[0] = code;
//签名
String sign = "tLain公众号";
//拿到发送短信的核心类
SmsSingleSender ssender = new SmsSingleSender(1400142856, "21306d751cfdf61ed433e506da242522");
//发送短信
try {
SmsSingleSenderResult result = ssender.sendWithParam("86", phoneNumber, templateId, params, sign, "", "");
System.out.println(result);
} catch (HTTPException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return code;
}
}
com.sikiedu.ssmlogin.dao
UserMapper.java
package com.sikiedu.ssmlogin.dao;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import com.sikiedu.ssmlogin.entity.User;
@Mapper
public interface UserMapper {
@Insert("insert into user(phone,password) values(#{phone},#{password})")
void save(User user);
@Select("select * from user where phone = #{phone} and password = #{password}")
User findUserByPhoneAndPassword(User user);
@Select("select * from user where phone = #{phone}")
User findUserByPhone(String phone);
}
com.sikiedu.ssmlogin.service
UserService.java
package com.sikiedu.ssmlogin.service;
import com.sikiedu.ssmlogin.entity.User;
public interface UserService {
void save(User user);
boolean findUserByPhoneAndPassword(User user);
boolean findUserByPhone(String phone);
}
com.sikiedu.ssmlogin.service.impl
UserServiceImpl.java
package com.sikiedu.ssmlogin.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.sikiedu.ssmlogin.dao.UserMapper;
import com.sikiedu.ssmlogin.entity.User;
import com.sikiedu.ssmlogin.service.UserService;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
public void save(User user) {
userMapper.save(user);
}
@Override
public boolean findUserByPhoneAndPassword(User user) {
User temp = userMapper.findUserByPhoneAndPassword(user);
return temp==null?false:true;
}
@Override
public boolean findUserByPhone(String phone) {
User temp = userMapper.findUserByPhone(phone);
//查找没有对象则返回true 有对象返回false
return temp==null?true:false;
}
}
com.sikiedu.ssmlogin.filter过滤器
IndexFilter.java
package com.sikiedu.ssmlogin.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class IndexFilter implements Filter {
@Autowired
private HttpServletRequest httpServletRequest;
@Autowired
private HttpSession session;
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("拦截"+httpServletRequest.getServletPath());
if(httpServletRequest.getServletPath().equals("/index")) {
if(session.getAttribute("user") != null) {
chain.doFilter(request, response);
}else {
//如果没有登录就不访问首页
request.getRequestDispatcher("/login").forward(request, response);;
}
}else {
//处理其他请求放行
chain.doFilter(request, response);
}
}
}
com.sikiedu.ssmlogin.entity
User.java
package com.sikiedu.ssmlogin.entity;
public class User {
private Integer id;
private String phone;
private String password;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [id=" + id + ", phone=" + phone + ", password=" + password + "]";
}
}