官网:阿里短信验证码购买
说明:自行注册账号购买,在只说明如何使用。
视图层:
首页:index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="root" value="${pageContext.request.contextPath}"></c:set>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>首页</title>
</head>
<body>
<div id="divcontent">
<div id="divtop">
<c:if test="${empty sessionScope.user}">
<a href="${root}/user?op=loginUser">[用户登录]</a>
</c:if>
<c:if test="${not empty sessionScope.user}">
<img class="imgshow" alt="" src="/upload/${sessionScope.user.uid}" />
${sessionScope.user.maskname}
<a href="${root}/user?op=logoutUser">[安全退出]</a>
</c:if>
<a href="${root}/user?op=registUser">[会员注册]</a>
</div>
</div>
</body>
</html>
注册页面:regist.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="root" value="${pageContext.request.contextPath}"></c:set>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>用户注册</title>
<style type="text/css">
#tbluser{
width: 600px;
margin: 100px auto;
border-collapse: collapse;
font-size: 15px;
}
.tdtitle{
text-align: right;
color: blue;
}
.info{
color: red;
}
</style>
<script type="text/javascript" src="${root}/static/js/jquery-1.12.4.js"></script>
<script type="text/javascript">
$(function(){
var second = 30;
//发送短信验证码给客户
function sendagain(){
second--;
if(second==0){
$("#send").val("发送验证码");
$("#send").prop("disabled",false);
second=30;
return;
}
$("#send").val(second+"秒后重新发送");
setTimeout(sendagain,1000);
}
$("#send").click(function(){
var phone = $("#phone").val();
var phoneReg = /^1[3-9]\d{9}$/;
if(!phoneReg.test(phone)){
alert("请确认手机号码的正确");
return;
}
$.ajax({
async:false,
type:"GET",
url:"${root}/user",
data:{"op":"existPhone","phone":phone},
dataType:"json",
success:function(res){
//认证手机号是否已经被注册过,没有被注册才继续下一步认证
if(res.code==200){
//客户端产生短信验证码四位数字
var code = (Math.random()+'').substr(2,4);
$("#sendcode").html(code);
$("#send").prop("disabled",true);
sendagain();
//真实发送手机短信验证码到用户手机,需要使用可以把注释去掉
/* $.ajax({
async:false,
type:"GET",
url:"${root}/user",
data:{"op":"sendCode","phone":phone,"code":code},
success:function(res){
alert(res);
},
error:function(){
alert("网络延时");
}
}); */
}else{
//手机号已经被注册
alert(res.message);
}
},
error:function(){
alert("网络延时");
}
});
});
//认证通过后实现注册
$("input[type='submit']").click(function(){
var phone = $("#phone").val();
var phoneReg = /^1[3-9]\d{9}$/;
if(!phoneReg.test(phone)){
alert("请确认手机号码的正确");
return false;
}
$.ajax({
async:false,
type:"GET",
url:"${root}/user",
data:{"op":"existPhone","phone":phone},
dataType:"json",
success:function(res){
if(res.code!=200){
alert(res.message);
return false;
}
},
error:function(){
alert("网络延时");
}
});
var code = $("#code").val();
if(code.length==0){
alert("短信验证码不能为空");
return false;
}
var sendcode = $("#sendcode").html();
if(code!=sendcode){
alert("短信验证码输入错误");
return false;
}
var pwd = $("#pwd").val();
if(pwd.length<6){
alert("密码长度不能少于六位");
return false;
}
var apwd = $("#apwd").val();
if(pwd!=apwd){
alert("两次密码输入不一致");
return false;
}
return true;
});
});
</script>
</head>
<body>
<form id="formuser" action="${root}/user" method="post">
<table border="1" id="tbluser">
<tr>
<td class="tdtitle">手机号码:</td>
<td>
<input type="text" id="phone" name="phone" maxlength="11" placeholder="请输入手机号码" />
<input type="button" id="send" value="发送验证码" />
</td>
<td>
<span id="spanphone" class="info">手机号码必须是十一位数字</span>
</td>
</tr>
<tr>
<td class="tdtitle">验证码:</td>
<td>
<input type="text" maxlength="4" id="code" placeholder="请输入手机短信验证码" />
<span id="sendcode" class="info"></span>
</td>
<td>
<span id="spancode" class="info">短信验证码切忌告知他人</span>
</td>
</tr>
<tr>
<td class="tdtitle">密码:</td>
<td>
<input type="password" maxlength="20" id="pwd" name="pwd" placeholder="请输入用户密码" />
</td>
<td>
<span id="spanpwd" class="info">请确保密码复杂度</span>
</td>
</tr>
<tr>
<td class="tdtitle">密码确认:</td>
<td>
<input type="password" maxlength="20" id="apwd" placeholder="请再次输入密码" />
</td>
<td>
<span id="spanapwd" class="info">两次密码输入保持一致</span>
</td>
</tr>
<tr>
<td class="tdtitle"> </td>
<td>
<input type="hidden" name="op" value="registUser" />
<input type="submit" value="注册" />
<input type="reset" value="重置" />
</td>
<td>
<span id="spanresult" class="info"></span>
</td>
</tr>
</table>
</form>
</body>
</html>
控制层
UserServlet.java
package com.uplooking.controller;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.http.HttpResponse;
import org.apache.http.util.EntityUtils;
import com.alibaba.fastjson.JSONObject;
import com.uplooking.constant.ConfigConsts;
import com.uplooking.constant.MenuConsts;
import com.uplooking.constant.UserConsts;
import com.uplooking.service.MenuService;
import com.uplooking.service.UserService;
import com.uplooking.service.impl.MenuServiceImpl;
import com.uplooking.service.impl.UserServiceImpl;
import com.uplooking.util.HttpUtils;
import com.uplooking.util.IOUtils;
/**
* Servlet implementation class UserServlet
*/
@WebServlet("/user")
public class UserServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private UserService userService = null;
private MenuService menuService = null;
/**
* @see HttpServlet#HttpServlet()
*/
public UserServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see Servlet#init(ServletConfig)
*/
public void init(ServletConfig config) throws ServletException {
// TODO Auto-generated method stub
userService =new UserServiceImpl();
menuService = new MenuServiceImpl();
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding(ConfigConsts.ENCODING);
response.setCharacterEncoding(ConfigConsts.ENCODING);
response.setContentType(ConfigConsts.CONTENT);
PrintWriter out = response.getWriter();
try {
switch (request.getParameter(ConfigConsts.OP)) {
//点注册跳转到注册页面
case UserConsts.REGISTUSER:
request.getRequestDispatcher("/WEB-INF/user/regist.jsp").forward(request, response);
return;
//手机号是否被注册
case UserConsts.EXISTPHONE:
String phone = request.getParameter("phone");
out.write(JSONObject.toJSONString(userService.existPhone(phone)));
return;
//短信验证码发送
case UserConsts.SENDCODE:
phone = request.getParameter("phone");
String code = request.getParameter("code");
String host = "http://yzxyx.market.alicloudapi.com";
String path = "/yzx/marketSms";
String method = "POST";
String appcode = "e583f0932d9f4e0db852fc74e1c04574";
Map<String, String> headers = new HashMap<String, String>();
headers.put("Authorization", "APPCODE " + appcode);
Map<String, String> querys = new HashMap<String, String>();
querys.put("phone", phone);
querys.put("templateId", "TP1803086");
querys.put("variable", "code:"+code);
Map<String, String> bodys = new HashMap<String, String>();
HttpResponse res = HttpUtils.doPost(host, path, method, headers, querys, bodys);
out.write(EntityUtils.toString(res.getEntity()));
return;
//点击登录页面跳转到登录页面
case UserConsts.LOGINUSER:
request.getRequestDispatcher("/WEB-INF/user/login.jsp").forward(request, response);
return;
//注销
case UserConsts.LOGOUTUSER:
//会话清除
request.getSession().invalidate();
response.sendRedirect(request.getContextPath()+"/index.jsp");
return;
case MenuConsts.LISTMENUNEXT:
int fid = Integer.parseInt(request.getParameter("fid"));
out.write(JSONObject.toJSONString(menuService.listMenu(fid)));
return;
default:
break;
}
} catch (Exception e) {
e.printStackTrace();
}finally{
out.flush();
out.close();
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding(ConfigConsts.ENCODING);
response.setCharacterEncoding(ConfigConsts.ENCODING);
response.setContentType(ConfigConsts.CONTENT);
switch (request.getParameter(ConfigConsts.OP)) {
case UserConsts.REGISTUSER:
String phone =request.getParameter("phone");
String pwd =request.getParameter("pwd");
//上传文件物理路径 避免项目重启初始化文件信息
String path = IOUtils.parentPath(request.getServletContext().getRealPath(""))+
File.separatorChar+ConfigConsts.UPLOADPATH+File.separatorChar;
request.setAttribute(ConfigConsts.RESULT, userService.registUser(phone, pwd,path));
request.getRequestDispatcher("/WEB-INF/user/result.jsp").forward(request, response);
return;
case UserConsts.LOGINUSER:
String name =request.getParameter("name");
pwd =request.getParameter("pwd");
Map<String, Object> result = userService.loginUser(name, pwd);
if(ConfigConsts.SUCCESSCODE == Integer.parseInt(result.get(ConfigConsts.CODE).toString())){
//登录成功 重定向
request.getSession().setAttribute(ConfigConsts.USER, result.get(ConfigConsts.USER));
response.sendRedirect(request.getContextPath()+"/index.jsp");
}else{
request.setAttribute(ConfigConsts.RESULT, result);
request.getRequestDispatcher("/WEB-INF/user/login.jsp").forward(request, response);
}
return;
default:
break;
}
}
}
业务层
验证手机号是否被注册及添加注册用户信息
UserServiceImpl.java
package com.uplooking.service.impl;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;
import org.apache.ibatis.session.SqlSession;
import org.springframework.util.DigestUtils;
import com.uplooking.constant.ConfigConsts;
import com.uplooking.constant.UserConsts;
import com.uplooking.dao.UserMapper;
import com.uplooking.pojo.UserVO;
import com.uplooking.service.UserService;
import com.uplooking.util.IOUtils;
import com.uplooking.util.MybaitsUtils;
import com.uplooking.util.RandomUtils;
public class UserServiceImpl implements UserService {
@Override
public Map<String, Object> registUser(String phone, String pwd,String path) {
Map<String, Object> map = new HashMap<String, Object>();
SqlSession sqlSession = null;
try {
sqlSession = MybaitsUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
if(userMapper.findByPhone(phone)==null){
//系统产生 用户名 盐值
String name = RandomUtils.getNumUpperString(UserConsts.NAMEUPPERLENGTH)+phone;
String salt = RandomUtils.getNumUpperLowerString(UserConsts.SALTLENGTH);
//配合盐值 MD5加密
pwd = DigestUtils.md5DigestAsHex((pwd+salt).getBytes());
UserVO userVO = new UserVO(null, null, name, pwd, salt, phone, null);
if(userMapper.insert(userVO)==1){
//将默认图片复制 新的图片为自增列的编号
byte[] data = IOUtils.readFile(path+File.separatorChar+UserConsts.USERDEFAULT);
IOUtils.writeFile(path+File.separatorChar+userVO.getUid(), data);
sqlSession.commit();
map.put(ConfigConsts.CODE,ConfigConsts.SUCCESSCODE);
map.put(ConfigConsts.MESSAGE,UserConsts.REGISTUSERSUCCESS);
}else{
map.put(ConfigConsts.CODE,UserConsts.REGISTUSERFAILCODE);
map.put(ConfigConsts.MESSAGE,UserConsts.REGISTUSERFAIL);
}
}else{
map.put(ConfigConsts.CODE,UserConsts.PHONEEXISTCODE);
map.put(ConfigConsts.MESSAGE,UserConsts.PHONEEXISTMESSAGE);
}
} catch (Exception e) {
sqlSession.rollback();
map.put(ConfigConsts.CODE,ConfigConsts.EXCEPTCODE);
map.put(ConfigConsts.MESSAGE,ConfigConsts.EXCEPTMESSAGE);
e.printStackTrace();
}finally{
MybaitsUtils.closeSqlSession(sqlSession);
}
return map;
}
@Override
public Map<String, Object> existPhone(String phone) {
Map<String, Object> map = new HashMap<String, Object>();
SqlSession sqlSession = null;
try {
sqlSession = MybaitsUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
if(userMapper.findByPhone(phone)==null){
map.put(ConfigConsts.CODE,ConfigConsts.SUCCESSCODE);
map.put(ConfigConsts.MESSAGE,UserConsts.PHONENOTEXISTMESSAGE);
}else{
map.put(ConfigConsts.CODE,UserConsts.PHONEEXISTCODE);
map.put(ConfigConsts.MESSAGE,UserConsts.PHONEEXISTMESSAGE);
}
} catch (Exception e) {
map.put(ConfigConsts.CODE,ConfigConsts.EXCEPTCODE);
map.put(ConfigConsts.MESSAGE,ConfigConsts.EXCEPTMESSAGE);
e.printStackTrace();
}finally{
MybaitsUtils.closeSqlSession(sqlSession);
}
return map;
}
}
常量
ConfigConsts.java
package com.uplooking.constant;
public interface ConfigConsts {
String ENCODING = "utf-8";
String CONTENT = "text/html";
String OP = "op";
String INDEX = "index";
String SIZE = "size";
String STEP = "step";
String UPLOADPATH = "upload";
String CODE = "code";
String MESSAGE = "message";
String RESULT = "result";
String USER = "user";
int SUCCESSCODE = 200;
int EXCEPTCODE = 500;
String EXCEPTMESSAGE = "系统异常";
String TIMESTAMPTIME = " 0:00:00";
String[] ALLOWROUTES = {"index.jsp","user","auth"};
}
UserConsts.java
package com.uplooking.constant;
import java.io.File;
public interface UserConsts {
char MASKCHAR = '*';
int MASKNAMESTART = 4;
int MASKPWDSTART = 0;
int MASKSALTSTART = 0;
int MASKPHONESTART = 3;
int MASKPHONELENGTH = 6;
int NAMEUPPERLENGTH = 4;
int SALTLENGTH = 20;
int PHONEEXISTCODE = 401;
String PHONEEXISTMESSAGE = "电话号码已被注册";
String PHONENOTEXISTMESSAGE = "电话号码可以使用";
String PHONEPATTERN = "1[3-9][0-9]{9}";
String REGISTUSERSUCCESS = "用户注册成功";
String REGISTUSERFAIL = "用户注册失败";
int REGISTUSERFAILCODE = 402;
String NAMENOTEXISTMESSAGE = "用户名不存在";
int NAMENOTEXISTCODE = 403;
String PASSWORDERRORMESSAGE = "密码错误";
int PASSWORDERRORCODE = 404;
String LOGINUSERSUCCESS = "用户登录成功";
String REGISTUSER = "registUser";
String SENDCODE = "sendCode";
String EXISTPHONE = "existPhone";
String LOGINUSER = "loginUser";
String LOGOUTUSER = "logoutUser";
String USERDEFAULT = "0";
}
AuthConsts.java
package com.uplooking.constant;
public interface AuthConsts {
int AUTHCODELENGTH = 4;
String AUTHCODE = "authCode";
int AUTHEXPIRY = 300;
String AUTHSUCCESSMESSAGE ="验证码输入正确";
String AUTHFAILMESSAGE ="验证码输入错误";
int AUTHFAILCODE = 601;
}