第二章
发送邮件
public class MailClient { private static final Logger loger = LoggerFactory.getLogger(MailClient.class); @Autowired private JavaMailSender mailSender; @Value("${spring.mail.username}") private String from; public void sendMail(String to, String subject, String content){ try { MimeMessage message = mailSender.createMimeMessage(); MimeMessageHelper helper = new MimeMessageHelper(message); helper.setFrom(from); helper.setTo(to); helper.setSubject(subject); helper.setText(content, true); } catch (MessagingException e) { loger.error("发送邮件失败:" + e.getMessage()); } } }
开发注册功能
-
访问注册页面
-
创建注册页面和方法
-
-
提交注册数据
-
先判断前端数据不能为空
-
验证账号和邮箱是否已存在
-
-
激活注册账号
-
给指定邮箱发激活邮件,进行账号的状态激活
-
跳转到登录页面
-
会话管理
@CookieValue()能获取客户端的cookie. cookie存储在客服端,是明文,不安全 session存储在服务端,但会照成服务端内存压力的问题
生成验证码
编写Kaptcha配置类、生成随机字符生成图片
@Configuration public class KaptchaConfig { @Bean public Producer kaptchaProducer(){ Properties properties = new Properties(); properties.setProperty("kaptcha.image.width", "100"); properties.setProperty("kaptcha.image.height", "40"); properties.setProperty("kaptcha.textproducer.font.size", "32"); properties.setProperty("kaptcha.textproducer.font.color", "0,0,0"); properties.setProperty("kaptcha.textproducer.char.string","0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"); properties.setProperty("kaptcha.textproducer.char.length","4"); properties.setProperty("kaptcha.noise.impl","com.google.code.kaptcha.impl.NoNoise"); DefaultKaptcha kaptcha = new DefaultKaptcha(); Config config = new Config(properties); kaptcha.setConfig(config); return kaptcha; } }
生成验证码的方法
@RequestMapping(path = "/kaptcha",method = RequestMethod.GET) public void getkaptcha(HttpServletResponse response, HttpSession session){ //生成验证码 String text = kaptchaProducer.createText(); BufferedImage image = kaptchaProducer.createImage(text); //验证码存入session session.setAttribute("kaptcha", text); //图片输出给浏览器 response.setContentType("image/png"); try { OutputStream os = response.getOutputStream(); ImageIO.write(image, "png", os); } catch (IOException e) { logger.error("响应验证码失败"); } }
登录、退出
每次登录生成登录凭证
//登录 public Map<String,Object> login(String username, String password, int expiredSeconds){ Map<String,Object> map = new HashMap<>(); //空值处理 xxx User user = userMapper.selectByName(username); //验证账号状态 //验证密码 password = CommunityUtil.md5(password + user.getSalt()); if (!user.getPassword().equals(password)){ map.put("passwordMsg", "密码不正确"); return map; } //生成登录凭证 LoginTicket loginTicket = new LoginTicket(); loginTicket.setUserId(user.getId()); loginTicket.setTicket(CommunityUtil.generateUUID()); loginTicket.setStatus(0); loginTicket.setExpired(new Date(System.currentTimeMillis() + expiredSeconds * 1000)); loginTicketMapper.inserLoginTicket(loginTicket); map.put("ticket", loginTicket.getTicket()); return map; }
退出:改变登录状态
显示登录信息
拦截器:定义拦截器,配置拦截器
应用:请求开始时查询用户、模板上显示用户数据、请求结束时清理用户数据
preHandle:Controller方法处理之前
postHandle:preHandle返回true,Controller方法处理完之后,DispatcherServlet进行视图的渲染之前,也就是说在这个方法中你可以对ModelAndView进行操作
afterCompletion:preHandle返回true,DispatcherServlet进行视图的渲染之后,多用于清理资源
检查登录状态
使用拦截器:方法前标注自定义注解,拦截所有请求,只处理有改注解的
自定义注解:元注解-@Target、@Retention
在方法上新增自定义注解@LoginRequired
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface LoginRequired { }
public class LoginRequiredInterceptor implements HandlerInterceptor { @Autowired private HostHolder hostHolder; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (handler instanceof HandlerMethod){ HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); LoginRequired loginRequired = method.getAnnotation(LoginRequired.class); if (loginRequired != null && hostHolder.getUser() == null){ response.sendRedirect(request.getContextPath() + "/login"); return false; } } return true; }