【SpringSecurity+OAuth2+JWT入门到实战】10.改造优化获取图形验证码和短信验证码

编程

项目文件结构

验证码处理器代码结构

虚线是调用

  • ValidateCodeController # 服务入口
  • ValidateCodeProcessor # 验证码处理接口
  • AbstractValidateCodeProcessor # 验证码处理 公共功能,使用模版方法模式聚合公共逻辑
  • ImageCodeProcessor # 图片验证码处理:响应
  • SmsCodeProcessor # 短信验证码处理:发送
  • ValidateCodeGenerator # 生成接口
  • ImageCodeGenerate # 图形验证码生成
  • SmsCodeGenerator # 短信验证码生成

ValidateCodeProcessor

com.spring.security.validate.code路径创建ValidateCodeProcessor类,生成验证码入口

package com.spring.security.validate.code;

import org.springframework.web.context.request.ServletWebRequest;

/**

* 校验码处理器,封装不同校验码的处理逻辑

*

*/

public interface ValidateCodeProcessor {

/**

* 验证码放入session时的前缀

*/

String SESSION_KEY_PREFIX = "SESSION_KEY_FOR_CODE_";

/**

* 创建校验码

*

* @param request

* @throws Exception

*/

void createCode(ServletWebRequest request) throws Exception;

}

 

AbstractValidateCodeProcessor

验证码处理 公共功能,使用模版方法模式聚合公共逻辑

com.spring.security.validate.code.impl路径创建AbstractValidateCodeProcessor类

package com.spring.security.validate.code.impl;

import java.util.Map;

import com.spring.security.validate.code.ValidateCodeException;

import org.apache.commons.lang.StringUtils;

import com.spring.security.validate.code.ValidateCode;

import com.spring.security.validate.code.ValidateCodeGenerator;

import com.spring.security.validate.code.ValidateCodeProcessor;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.social.connect.web.HttpSessionSessionStrategy;

import org.springframework.social.connect.web.SessionStrategy;

import org.springframework.web.context.request.ServletWebRequest;

public abstract class AbstractValidateCodeProcessor<C extends ValidateCode> implements ValidateCodeProcessor {

/**

* 操作session的工具类

*/

private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();

/**

* 收集系统中所有的 {@link ValidateCodeGenerator} 接口的实现。

*/

@Autowired

private Map<String, ValidateCodeGenerator> validateCodeGenerators;

/**

* ValidateCodeProcessor

*/

@Override

public void createCode(ServletWebRequest request) throws Exception {

C validateCode = generate(request);

save(request, validateCode);

send(request, validateCode);

}

/**

* 生成校验码

*

* @param request

* @return

*/

@SuppressWarnings("unchecked")

private C generate(ServletWebRequest request) {

String type = getProcessorType(request);

ValidateCodeGenerator validateCodeGenerator = validateCodeGenerators.get(type + "CodeGenerator");

if (validateCodeGenerator == null) {

throw new ValidateCodeException("验证码生成器" + type + "CodeGenerator不存在");

}

return (C) validateCodeGenerator.createCode(request);

}

/**

* 保存校验码

*

* @param request

* @param validateCode

*/

private void save(ServletWebRequest request, C validateCode) {

sessionStrategy.setAttribute(request, SESSION_KEY_PREFIX + getProcessorType(request).toUpperCase(), validateCode);

}

/**

* 发送校验码,由子类实现

*

* @param request

* @param validateCode

* @throws Exception

*/

protected abstract void send(ServletWebRequest request, C validateCode) throws Exception;

/**

* 根据请求的url获取校验码的类型

*

* @param request

* @return

*/

private String getProcessorType(ServletWebRequest request) {

return StringUtils.substringAfter(request.getRequest().getRequestURI(), "/code/");

}

}

 

ImageCodeProcessor

com.spring.security.validate.code.image路径创建ImageCodeProcessor图片验证码处理:响应

/**

*

*/

package com.spring.security.validate.code.image;

import javax.imageio.ImageIO;

import com.spring.security.validate.code.impl.AbstractValidateCodeProcessor;

import org.springframework.stereotype.Component;

import org.springframework.web.context.request.ServletWebRequest;

/**

* 图片验证码处理器

*

*/

@Component("imageCodeProcessor")

public class ImageCodeProcessor extends AbstractValidateCodeProcessor<ImageCode> {

/**

* 发送图形验证码,将其写到响应中

*/

@Override

protected void send(ServletWebRequest request, ImageCode imageCode) throws Exception {

ImageIO.write(imageCode.getImage(), "JPEG", request.getResponse().getOutputStream());

}

}

 

SmsCodeProcessor

com.spring.security.validate.code.sms路径创建SmsCodeProcessor短信验证码处理:发送

/**

*

*/

package com.spring.security.validate.code.sms;

import com.spring.security.validate.code.ValidateCode;

import com.spring.security.validate.code.impl.AbstractValidateCodeProcessor;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Component;

import org.springframework.web.bind.ServletRequestUtils;

import org.springframework.web.context.request.ServletWebRequest;

/**

* 短信验证码处理器

*

*/

@Component("smsCodeProcessor")

public class SmsCodeProcessor extends AbstractValidateCodeProcessor<ValidateCode> {

/**

* 短信验证码发送器

*/

@Autowired

private SmsCodeSender smsCodeSender;

@Override

protected void send(ServletWebRequest request, ValidateCode validateCode) throws Exception {

//获取手机号

String mobile = ServletRequestUtils.getRequiredStringParameter(request.getRequest(), "mobile");

//发送短信

smsCodeSender.send(mobile, validateCode.getCode());

}

}

 

修改控制器

改造ValidateController类统一访问路径

package com.spring.security.validate.code;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RestController;

import org.springframework.web.context.request.ServletWebRequest;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.util.Map;

/**

* 获取验证码控制器

*/

@RestController

public class ValidateController {

@Autowired

private Map<String, ValidateCodeProcessor> validateCodeProcessor;

/**

* 创建验证码,根据验证码类型不同,调用不同的 {@link ValidateCodeProcessor}接口实现

*

* @param request

* @param response

* @param type

* @throws Exception

*/

@GetMapping("/code/{type}")

public void createCode(HttpServletRequest request, HttpServletResponse response, @PathVariable String type)

throws Exception {

validateCodeProcessor.get(type + "CodeProcessor").createCode(new ServletWebRequest(request, response));

}

}

 

修改图形验证码拦截器

修改ValidateCodeFilter类的validateCode方法:

ImageCode codeInSession = (ImageCode) sessionStrategy.getAttribute(servletWebRequest, "SESSION_KEY_FOR_CODE_IMAGE");

session值我们先写死,等做到短信验证码拦截器一起优化掉。

 

测试

启动项目访问:http://127.0.0.1:8080/signIn.html

获取图形验证码没问题,输入正确验证码账号登录:

 

重启项目测试获取短信验证:

以上是 【SpringSecurity+OAuth2+JWT入门到实战】10.改造优化获取图形验证码和短信验证码 的全部内容, 来源链接: utcz.com/z/514083.html

回到顶部