青檬数码
项目数据接口开源地址
gitee:https://gitee.com/big-cao-xiaosheng/b2c_shoping
- 项目演示视频
b2c
(一)
1.核心功能代码块
import java.io.IOException;
import java.util.Random;
import java.util.Scanner;
import java.util.UUID;
import com.github.qcloudsms.SmsSingleSender;
import com.github.qcloudsms.SmsSingleSenderResult;
import org.json.JSONException;
import com.github.qcloudsms.httpclient.HTTPException;
/**
* 短信工具类
* @author Administrator
*
*/
public class MessageUtil {
public static String sendMessage(String phone) {
String message="";
// 短信应用SDK AppID
int appid =;// 1400开头
// 短信应用SDK AppKey
String appkey = "";
// 需要发送短信的手机号码
String[] phoneNumbers = {phone};
// 短信模板ID,需要在短信应用中申请
int templateId =; // 模板ID需要在短信控制台中申请
// 签名
String smsSign = ""; // 签名需要在短信控制台中申请,另外签名参数使用的是`签名内容`,而不是`签名ID`
try {
/*int x=new Random().nextInt(100);
x=(x+1)*100;
Integer x1=new Integer(x);
message=x1.toString();*/
//随机生成四位验证码
int x = UUID.randomUUID().toString().hashCode();
if (x < 0) {
x = -x;
}
String orerdcode=String.format("%09d", x);
message=orerdcode.substring(0,6);
String[] params = {message,"2"};
SmsSingleSender ssender = new SmsSingleSender(appid, appkey);
SmsSingleSenderResult result = ssender.sendWithParam("86", phoneNumbers[0], templateId, params, smsSign, "", ""); // 签名不能为空串
System.out.println(result);
} catch (HTTPException e) {
// HTTP响应码错误
e.printStackTrace();
} catch (JSONException e) {
// json解析错误
e.printStackTrace();
} catch (IOException e) {
// 网络IO错误
e.printStackTrace();
}
return message;
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入手机号:");
String phone=sc.nextLine();
String message=sendMessage(phone);
System.out.println(message);
System.out.println("请输入验证码:");
String yanzhengma=sc.nextLine();
if(yanzhengma.equals(message)) {
System.out.println("验证成功");
}else {
System.out.println("验证失败");
}
}
}
2.使用注解的方式实现aop的启动只读事务,避免数据库的脏读
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="query*" read-only="true"/>
<tx:method name="search*" read-only="true"/>
<tx:method name="select*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="*" isolation="DEFAULT" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* com.feisi.service.*.*.*(..))" id="cut"/>
<aop:advisor advice-ref="txManager" pointcut-ref="cut"/>
</aop:config>
3.token令牌的生成
import com.nimbusds.jose.JOSEException;
import com.nimbusds.jose.JWSAlgorithm;
import com.nimbusds.jose.JWSHeader;
import com.nimbusds.jose.crypto.MACSigner;
import com.nimbusds.jose.crypto.MACVerifier;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
import com.feisi.pojo.Users;
import java.text.ParseException;
import java.util.Date;
public class JwtUtil {
public static long expire=6000000L; // 令牌的过时时间 60秒
public static String secret = "hahhahahahahhahaaheheheheheheheheyhehyheyhehy";
/**
* 生成token
* subject代表token所有者,用userId作为subject
* @return
*/
public static String genToken(String subject,String password) throws JOSEException {
// 生成jwt的header 算法时HS256
JWSHeader header = new JWSHeader(JWSAlgorithm.HS256);
//生产payload部分
/*
{
sub:"employee表的id",
iss:"服务器的域名",
exp:"2020 10-20",// 超时时间
username:"" // 公共属性
}
加密生成payload
*/
JWTClaimsSet claimsSet = new JWTClaimsSet.Builder()
.subject(subject) //设置标准字段sub
.issuer("www.demo")
.expirationTime(new Date(System.currentTimeMillis()+expire)) //设置超时时间
.claim("password",password) //设置payload中的公共属性
.build();
//3. 生成签名
MACSigner macSigner = new MACSigner(secret);
SignedJWT signedJWT = new SignedJWT(header, claimsSet);
signedJWT.sign(macSigner);
//获取字符串形式的token
return signedJWT.serialize();
}
/**
* 验证token
* @param token
* @return
*/
public static Users validToken(String token) throws ParseException, JOSEException, JwtException {
if(token==null){
throw new JwtException("没有token");
}
//得到只有第三部分的jwt对象
SignedJWT jwt = SignedJWT.parse(token);
//获取盐的解密形式
MACVerifier macVerifier = new MACVerifier(secret);
//校验token是否能被正确解密
if(!jwt.verify(macVerifier)){
throw new JwtException("token不合法");
}
//验证是否超时
if(new Date().after(jwt.getJWTClaimsSet().getExpirationTime())){
throw new JwtException("token超时");
}
//拿到代表subject的userid
JWTClaimsSet payload = jwt.getJWTClaimsSet();
String u_name = payload.getSubject();
//拿公共属性 username
String password = (String) payload.getClaim("password");
Users user = new Users();
user.setU_name(u_name);
user.setU_password(password);
return user;
}
}
4.拦截器的设置解决前后端跨域问题
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/*前后端分离跨域请求问题*/
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
httpServletResponse.setHeader("Access-Control-Allow-Origin", "*");
httpServletResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
httpServletResponse.setHeader("Access-Control-Max-Age", "3600");
httpServletResponse.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
httpServletResponse.setHeader("Content-Type","application/json;charset=UTF-8");
httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
5.拦截器验证token
import com.feisi.pojo.Users;
import com.feisi.util.JwtException;
import com.feisi.util.JwtUtil;
import com.nimbusds.jose.shaded.json.parser.ParseException;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class TokenInterceptors implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//1. 先获取token,从请求头中获取token
String token = request.getHeader("access-token");
//2. 对token进行合法性验证
try {
//如果验证成功,返回一个代表当前登录用户的employee对象
Users user = JwtUtil.validToken(token);
//更新当前的token,更新expire time 超时时间
String newToken = JwtUtil.genToken(user.getU_name(), user.getU_password());
//将新token存入到响应头当中;
response.setHeader("access-token", newToken);
//验证权限成功后,放行给controller处理具体请求
return true;
} catch (JwtException e) {
//如果验证不合法,直接返回状态码401,返回失败信息
response.setStatus(401);
response.getWriter().write("{\"message\":\"forbidden\"}");
return false;
}
}
}
后续将陆续推出pc端前端代码实现,后台管理模块,及接口的实现