【学习笔记】seckill-秒杀项目--(2)登录功能及完善

一、逆向工程

首先通过CodeGenerator基于数据库表生产对应的POJI、Mapper、Service、ServiceImpl、Controller等需要的类。
逆向工程使用了MybatisPlus提供的AutoGenerator,代码可去官网查看。
代码生成器里面包括一些全局配置,可以设置作者、日期等;

// 代码生成器
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");
//作者
gc.setAuthor("roro");
//打开输出目录
gc.setOpen(false);
//xml开启 BaseResultMap
gc.setBaseResultMap(true);
//xml 开启BaseColumnList
gc.setBaseColumnList(true);
//日期格式,采用Date
gc.setDateType(DateType.ONLY_DATE);
mpg.setGlobalConfig(gc);

数据源配置,包括数据源url,驱动、用户名、密码;

// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://localhost:3306/seckill?
useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia" +
"/Shanghai");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("root");
mpg.setDataSource(dsc);

包配置,要将那些类放在什么包下

// 包配置
PackageConfig pc = new PackageConfig();
pc.setParent("com.example.seckill")
.setEntity("pojo")
.setMapper("mapper")
.setService("service")
.setServiceImpl("service.impl")
.setController("controller");
mpg.setPackageInfo(pc);

自定义配置

// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
Map<String,Object> map = new HashMap<>();
map.put("date1","1.0.0");
this.setMap(map);
}
};
// 如果模板引擎是 freemarker
String templatePath = "/templates/mapper.xml.ftl";
// 自定义输出配置
List<FileOutConfig> focList = new ArrayList<>();
// 自定义配置会被优先输出
focList.add(new FileOutConfig(templatePath) {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化
return projectPath + "/src/main/resources/mapper/" +
tableInfo.getEntityName() + "Mapper"
+ StringPool.DOT_XML;
}
});
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
// 配置模板
TemplateConfig templateConfig = new TemplateConfig()
.setEntity("templates/entity.java")
.setMapper("templates/mapper.java")
.setService("templates/service.java")
.setServiceImpl("templates/serviceImpl.java")
.setController("templates/controller.java");
templateConfig.setXml(null);
mpg.setTemplate(templateConfig);
// 策略配置
StrategyConfig strategy = new StrategyConfig();
//数据库表映射到实体的命名策略,驼峰命名法
strategy.setNaming(NamingStrategy.underline_to_camel);
//数据库表字段映射到实体的命名策略
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
//lombok模型
strategy.setEntityLombokModel(true);
//生成 @RestController 控制器
// strategy.setRestControllerStyle(true);
strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
strategy.setControllerMappingHyphenStyle(true);
//表前缀
strategy.setTablePrefix("t_");
mpg.setStrategy(strategy);
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
mpg.execute();

二、登录功能

1. 准备login界面

url输入:localhost:8080/login/toLogin进入登录页面;
表单输入用户名、密码,点击登录后调用doLogin(),跳转至/login/doLogin进行用户名及密码校验,校验通过则跳转至/goods/toList,校验失败则提示失败信息。

<script>
    function login() {
        $("#loginForm").validate({
            submitHandler: function (form) {
                doLogin();
            }
        });
    }
    function doLogin() {
        g_showLoading();
        var inputPass = $("#password").val();
        var salt = g_passsword_salt;
        var str = "" + salt.charAt(0) + salt.charAt(2) + inputPass +
            salt.charAt(5) + salt.charAt(4);
        var password = md5(str);
        $.ajax({
            url: "/login/doLogin",
            type: "POST",
            data: {
                mobile: $("#mobile").val(),
                password: password
            },
            success: function (data) {
                layer.closeAll();
                if (data.code == 200) {
                    layer.msg("成功");
                    window.location.href="/goods/toList";
                } else {
                    layer.msg(data.message);
                }
            },
            error: function () {
                layer.closeAll();
            }
        });
    }
</script>

2. 页面跳转功能实现

@Controller
@RequestMapping("/login")
@Slf4j
public class LoginController {

    @Autowired
    private IUserService userService;

    /**
     * 跳转登录页面
     * @author 47roro
     * @date 2022/4/3
     * @param
     * @return java.lang.String
     **/
    @RequestMapping("/toLogin")
    public String toLogin(){
        return "login";
    }

    @RequestMapping("/doLogin")
    @ResponseBody
    public RespBean doLogin(@Valid LoginVo loginVo, HttpServletRequest request, HttpServletResponse response){
        //log.info(loginVo.toString());
        return userService.doLogin(loginVo, request, response);
    }
}

@Controller
@RequestMapping("/goods")
public class GoodsController {

    /**
     * 跳转到商品列表页面
     * @author 47roro
     * @date 2022/4/3
     * @param session
     * @param model
     * @param cookie
     * @return java.lang.String
     **/
    @RequestMapping("/toList")
    public String toList(HttpSession session, Model model, @CookieValue("userCookie") String cookie){
        if(StringUtils.isEmpty(cookie)){
            return "login";
        }
        User user = (User) session.getAttribute(cookie);
        if(null == user){
            return "login";
        }
        model.addAttribute("user", user);
        return "goodsList";
    }
}

3. 登录服务

/**
 *  服务实现类
 * @author 47roro
 * @since 2022-04-03
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private UserMapper userMapper;

    /**
     * 登录
     * @author 47roro
     * @date 2022/4/3
     * @param loginVo
     * @return com.example.seckill.vo.RespBean
     **/
    @Override
    public RespBean doLogin(LoginVo loginVo, HttpServletRequest request, HttpServletResponse response) {
        String mobile = loginVo.getMobile();
        String password = loginVo.getPassword();
        
        User user = userMapper.selectById(mobile);
        // 如果用户名不存在,抛出登录失败信息。
        if(null == user){
            throw new GlobalException(RespBeanEnum.LOGIN_ERROR);
        }
        // 如果用户密码错误,抛出登录失败信息。(获取到前端加密后的密码和数据库内保存的加密密码对比)
        if(!MD5Util.frompassToDBPass(password, user.getSalt()).equals(user.getPassword())){
            throw new GlobalException(RespBeanEnum.LOGIN_ERROR);
        }
        // 生成cookie
        String cookie = UUIDUtil.uuid();
        request.getSession().setAttribute(cookie, user);
        CookieUtil.setCookie(request, response, "userCookie", cookie);
        // 登录成功
        return RespBean.success();
    }
}

4. 用户名校验

/**
 * @author 47roro
 * @create 2022/4/3
 * @description: 手机号码校验
 */
public class ValidatorUtil {
    private static final Pattern mobile_pattern = Pattern.compile("[1]([3-9])[0-9]{9}$");

    public static boolean isMobile(String mobile){
        if(!StringUtils.hasLength(mobile)){
            return false;
        }
        Matcher matcher = mobile_pattern.matcher(mobile);
        return matcher.matches();
    }
}

5. 其他

自定义注解,校验手机号:

/**
 * @author 47roro
 * @create 2022/4/3
 * @description: 自定义注解校验手机号
 */
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.TYPE_USE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(
        validatedBy = {IsMobileValidator.class}
)
public @interface IsMobile {
    boolean required() default true;

    String message() default "手机号码格式错误";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};
}

全局异常:

/**
 * @author 47roro
 * @create 2022/4/3
 * @description: 全局异常处理类
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

	@ExceptionHandler(Exception.class)
	public RespBean ExceptionHandler(Exception e) {
		if (e instanceof GlobalException) {
			GlobalException ex = (GlobalException) e;
			return RespBean.error(ex.getRespBeanEnum());
		} else if (e instanceof BindException) {
			BindException ex = (BindException) e;
			RespBean respBean = RespBean.error(RespBeanEnum.BIND_ERROR);
			respBean.setMessage("参数校验异常:" + ex.getBindingResult().getAllErrors().get(0).getDefaultMessage());
			return respBean;
		}
		return RespBean.error(RespBeanEnum.ERROR);
	}
}

请求枚举类:

/**
 * @author 47roro
 * @create 2022/4/3
 * @description: 请求枚举类
 */
@Getter
@ToString
@AllArgsConstructor
public enum RespBeanEnum {
    //通用
    SUCCESS(200, "SUCCESS"),
    ERROR(500, "服务端异常"),
    //登录模块
    LOGIN_ERROR(500210, "用户名或密码错误"),
    MOBILE_ERROR(500211, "手机号码不正确"),
    BIND_ERROR(500212, "参数校验异常");

    private final Integer code;
    private final String message;
}

三、视频参考

优极限-秒杀项目

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值