项目开发之量化交易QuantTrade(二)
前后端业务:用户登录
业务实现
MemberController
/**
* 登录用户
* @param member
* @return
*/
@ApiOperation("登录接口")
@PostMapping("/login")
public @ResponseBody RestObject login(@RequestBody Member member, @ApiIgnore HttpSession httpSession){
RestObject restObject = memberService.login(member,httpSession);
return restObject;
}
MemberService
import com.quanttrade.member.javabean.Member;
import com.quanttrade.member.mapper.MemberMapper;
import com.quanttrade.utils.javabean.RestObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import javax.servlet.http.HttpSession;
@Service
public class MemberService {
@Autowired
private MemberMapper memberMapper;
/**
* 注册用户信息
* @param param 用户名、密码、确认密码
* @return 注册结果
*/
public RestObject register(Member param) {
//1、合法性校验
String serviceMsg = "注册";
RestObject serviceMsg1 = legitimacyVerification(param, serviceMsg);
if (serviceMsg1 != null) return serviceMsg1;
//1.3、确认密码必须存在
if(param.getRepeat()==null || "".equals(param.getRepeat().trim())){
return RestObject.ERROR(serviceMsg+"失败,请先填写确认密码!");
}
//1.4、密码和确认密码必须保持一致
if(!param.getAuthstring().equals(param.getRepeat())){
return RestObject.ERROR(serviceMsg+"失败,密码和确认密码必须保持一致!");
}
//2、先对密码进行MD5加密,替换未加密密码
param.setAuthstring(
DigestUtils.md5DigestAsHex(
param.getAuthstring().getBytes()
)
);
//3、调用mapper层保存数据
int rows = 0;
try {
rows = memberMapper.saveMemberInfo(param);
} catch (Exception e) {
String errorMsg = e.getMessage();
System.out.println(errorMsg);
if(errorMsg.contains("Duplicate entry")&& errorMsg.contains("tb_member.account")){
//判断如果是用户名重复了,抛出用户名重复的问题
return RestObject.ERROR("注册失败,该用户名已注册,请更换一个新的用户名!");
}
return RestObject.ERROR("注册失败,请联系管理员");
}
//4、返回业务结果
if(rows>0){
return RestObject.OK("注册成功!");
}else{
return RestObject.ERROR("注册失败,请联系管理员");
}
}
/**
* 用户名和密码的合法性校验
* @param param
* @param serviceMsg
* @return
*/
private static RestObject legitimacyVerification(Member param, String serviceMsg) {
//1.0、防止空指针异常
if(param == null){
return RestObject.ERROR(serviceMsg + "失败,请联系管理员");
}
//1.1、用户名必须存在
if(param.getAccount()==null || "".equals(param.getAccount().trim())){
return RestObject.ERROR(serviceMsg + "失败,请先填写用户名!");
}
//1.2、密码必须存在
if(param.getAuthstring()==null || "".equals(param.getAuthstring().trim())){
return RestObject.ERROR(serviceMsg + "失败,请先填写密码!");
}
return null;
}
/**
* 用户登录业务
* @param param 用户名、密码
* @param session session对象
* @return 业务结果
*/
public RestObject login(Member param, HttpSession session) {
//1、合法性校验
String serviceMsg = "登录";
RestObject serviceMsg1 = legitimacyVerification(param, serviceMsg);
if (serviceMsg1 != null) return serviceMsg1;
//2、对密码进行一次MD5加密
param.setAuthstring(
DigestUtils.md5DigestAsHex(
param.getAuthstring().getBytes()
)
);
//3、根据用户名和密码对用户信息进行查询
Member member = null;
try {
member = memberMapper.searchAccountByUserNameAndPassWord(param);
} catch (Exception e) {
System.out.println(e.getMessage());
return RestObject.ERROR("登录失败,请联系管理员!");
}
//4、登录业务判断
if(member!=null && member.getAccount()!=null && !"".equals(member.getAccount())){
//登录成功
session.setAttribute("member",member); //session中保存了用户信息,登录成功的标志
return RestObject.OK("登录成功");
}else{
//登录失败
return RestObject.ERROR("登录失败,用户名或密码错误!");
}
}
}
MemberMapper
/**
* 根据用户名和密码查询用户信息
* @param param
* @return
*/
Member searchAccountByUserNameAndPassWord(@Param("member") Member param);
MemberMapper.xml
<select id="searchAccountByUserNameAndPassWord" resultType="com.quanttrade.member.javabean.Member">
SELECT ACCOUNT FROM tb_member WHERE ACCOUNT=#{member.account} AND authstring=#{member.authstring}
</select>
测试:
前端整合
后端业务:登录权限校验(自定义注解定制化过程)
需求说明
自定义一个注解,要求哪个方法加入@RequireLogin注解,该方法只有登录用户才能执行,非登录用户执行会报错
业务实现
构建自定义注解:
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface RequireLogin {
boolean value() default true;
}
编写拦截器:
import com.alibaba.fastjson.JSON;
import com.quanttrade.utils.annotation.RequireLogin;
import com.quanttrade.utils.javabean.RestObject;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
@Component
public class LoginInterceptor implements HandlerInterceptor {
/**
* 在请求指定的 控制器业务方法之前,进行拦截,判断是否有登录权限。
* 有权限,放行
* 没有权限,拦截
* @param request
* @param response
* @param handler
* @return true 放行 false 拦截
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if(handler instanceof HandlerMethod){
//1、判断当前执行的业务方法 是否被注解修饰了
//1.1、对Handler进行强转
HandlerMethod handlerMethod = (HandlerMethod) handler;
//1.2、判断当前方法是否被注解修饰
RequireLogin requireLogin = handlerMethod.getMethodAnnotation(RequireLogin.class);
//2、判断当前方法是否需要进行权限校验
if(requireLogin!=null && requireLogin.value()){
//3、如果需要进行校验,判断是否有权限,有权限就放行,没有权限就拦截
//3.1、获取session中的member对象
Object member = request.getSession().getAttribute("member");
//3.2、判断member对象是否存在
if(member==null){
//3.3、如果Member不存在,说明没有登录权限,拦截,返回错误信息
//处理中文
response.setContentType("application/json;charset=utf-8");
//向前写出信息
PrintWriter writer = response.getWriter();
writer.write(JSON.toJSONString(RestObject.ERROR("请先登录!")));
//拦截
return false;
}
//3.4、如果member存在,说明有登录权限直接放行
}
//4、如果不需要权限校验,直接放行即可
}
//如果不是要拦截的业务方法系列,直接放行
return true;
}
}
注册拦截器:
import com.quanttrade.utils.interceptor.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MVCConfig implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
/**
* 注册拦截器,为拦截器配置拦截路径
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
//注册拦截器,并为该拦截器添加拦截路径
registry.addInterceptor(loginInterceptor).addPathPatterns("/member/**");
}
}
编写一个测试用的控制器方法:
MemberController:
/**
* 测试登录权限校验的接口
* @return
*/
@ApiOperation("测试登录权限校验的接口")
@PostMapping("/testRequireLogin")
@RequireLogin
public @ResponseBody RestObject testRequireLogin(){
return RestObject.OK("测试成功!您已登录");
}
分别测试未登录 和 登录状态即可!!!
至此前后端业务实现成功,接下来将数据数据获取阶段