springboot项目通过自定义注解及拦截器Interceptor校验前端传参
在我们的项目中前后端联调过程中传参是很重要的节点,我们可以通过自定义注解及配置相关的拦截器Interceptor来实现对前端参数是否传过来,在某些应用场景中是频繁使用的,比如:身份证的校验,手机号的校验,相关字段是否传输等等。
1.自定义注解的创建:
该注解的使用直接添加到相应的方法上即可。
import org.springframework.stereotype.Component;
import java.lang.annotation.*;
@Documented
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Component
public @interface CheckParam
{
String value() ;
}
2.拦截器Interceptor的创建:
该拦截器逻辑:通过判断进入到拦截器中是否含有相应自定义的注解, 获取自定义注解中的参数并通过“,”分割得到相应的参数进行相信的处理。
import com.ylkz.util.RegexUtil;
import com.ylkz.util.StringUtils;
import com.ylkz.annotation.CheckParam;
import net.sf.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
public class CheckParamInterceptor extends HandlerInterceptorAdapter {
protected static Logger LOGGER = LoggerFactory.getLogger("CheckParamInterceptor");
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof HandlerMethod) {
CheckParam annotation = ((HandlerMethod) handler).getMethodAnnotation(CheckParam.class);
// 没有添加注解
if (annotation == null) {
return true;
}
// 1.获取注解中的所有参数名
String params = annotation.value();
if (params != null && params.trim().length() > 0) {
String[] paramArr = params.split(",");
if (paramArr != null && paramArr.length > 0) {
List<String> badKeys = new ArrayList<String>();
for (String param : paramArr) {
String value = request.getParameter(param);
if (value == null) { // 参数值如果为null,添加到记录
badKeys.add(param);
continue;
}
if ("mobile".equals(param)) { // 如果参数带有手机号
if(!RegexUtil.isMobile_11num(value.toString())){ // 规则验证失败
LOGGER.info("mobile不符合");
badKeys.add(param);
continue;
}
} else if ("idCard".equals(param)) { // 如果参数带有身份证号码
if(!RegexUtil.isIDCard(value.toString())){ // 规则验证失败
badKeys.add(param);
continue;
}
if (value.toString().trim().length() == 18) {
String idCard17 = value.toString().substring(0, 17);
String lastNumCheck = StringUtils.getLastNum(idCard17);
String lastNum = value.toString().substring(17, 18);
if (!lastNum.toLowerCase().equals(lastNumCheck)) {
LOGGER.info("身份证号码最后一位验证失败,用户录入最后一位 " + lastNum + ", 校验值为 " + lastNumCheck);
badKeys.add(param);
continue;
}
}
}
}
if (badKeys.size() > 0) {
LOGGER.info("必要的参数不能为空:" + badKeys);
ResultMessage resultMessage = new ResultMessage(false, "001", "接口调用参数异常", badKeys);
JSONObject responseJSONObject = JSONObject.fromObject(resultMessage);
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json; charset=utf-8");
PrintWriter out = null;
try {
out = response.getWriter();
out.append(responseJSONObject.toString());
LOGGER.debug(responseJSONObject.toString());
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close();
}
}
return false;
}
}
}
}
return true;
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
super.afterCompletion(request, response, handler, ex);
}
}
举例说明:
比如通过校验相应的参数是否为null。如果为null的话则会返回给前端页面相关调用接口失败缺少相关参数。
/**
* 获取一个职位的,多个状态的订单统计数据
* @param demandId
* @param status
* @return
*/
@CheckParam("demandId,status")
private Map<String,Integer> getApplyCountByDemandIdAndApplyStatus(Long demandId, List<ApplyStatusEnum> status) {
final Map<String,Integer> result = new HashMap<>();
result.put("demandId",demandId.intValue());
status.forEach(applyEnum -> result.put(applyEnum.getDesc(),getApplyCountByDemandIdAndApplyState(demandId,applyEnum)));
return result;
}
@ResponseBody
@RequestMapping(value = "/lookResume", method = RequestMethod.POST)
@CheckParam("resumeId")
public ResultMessage lookResume(@RequestParam(value = "userId") Integer userId,
@RequestParam(value = "resumeId") Integer resumeId) {
try {
//验证简历是否存在
Boolean exists = redisUtil.hasKey(RedisKey_ResumeConstants.BASE_RESUME_INFO + resumeId);
if (!exists) {
logger.error(RedisKey_ResumeConstants.BASE_RESUME_INFO + resumeId + "\t\t\t简历不存在");
return new ResultMessage(ResponseCode.DATA_NOT_FOUND.getCode(), "简历不存在", "");
}
/**增加简历浏览量*/
double hincr = redisUtil.hincr(RedisKey_StatisticsConstants.STATISTICS_RESUME_LOOKED, resumeId.toString(), 1);
return new ResultMessage(ResponseCode.SUCCESS.getCode(), "操作成功", hincr);
} catch (Exception e) {
e.printStackTrace();
return new ResultMessage(ResponseCode.SYSTEM_INNER_ERROR.getCode(), "操作异常", "");
}
}
手机号校验,身份证校验相关的工具类:
import java.util.regex.Pattern;
/**
* 账户相关属性验证工具
*
*/
public class RegexUtil {
/**
* 正则表达式:验证手机号
*/
public static final String REGEX_MOBILE = "^1([358][0-9]|4[579]|66|7[0135678]|9[89])[0-9]{8}$";
/**
* 正则表达式:验证手机号_11位数字
*/
public static final String REGEX_MOBILE_11NUM = "(^\\d{11}$)";
/**
* 正则表达式:验证手机号_11位数字
*/
public static final String IS_NUM = "^[0-9]*$";
/**
* 正则表达式:验证邮箱
*/
public static final String REGEX_EMAIL = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$";
/**
* 正则表达式:验证汉字
*/
public static final String REGEX_CHINESE = "^[\u4e00-\u9fa5],{0,}$";
/**
* 正则表达式:验证身份证
*/
public static final String REGEX_ID_CARD = "(^[1-9]\\d{5}(18|19|([23]\\d))\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$)|(^[1-9]\\d{5}\\d{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)\\d{2}$)";
/**
* 正则表达式:验证URL
*/
public static final String REGEX_URL = "http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?";
/**
* 正则表达式:验证IP地址
*/
public static final String REGEX_IP_ADDR = "(25[0-5]|2[0-4]\\d|[0-1]\\d{2}|[1-9]?\\d)";
/**
* 校验手机号
*
* @param mobile
* @return 校验通过返回true,否则返回false
*/
public static boolean isMobile(String mobile) {
if (mobile == null) return false;
return Pattern.matches(REGEX_MOBILE, mobile);
}
/**
* 校验手机号位数
*
* @param mobile
* @return 校验通过返回true,否则返回false
*/
public static boolean isMobile_11num(String mobile) {
if (mobile == null) return false;
return Pattern.matches(REGEX_MOBILE_11NUM, mobile);
}
/**
* 校验纯数字
*
* @param num
* @return 校验通过返回true,否则返回false
*/
public static boolean isNum(String num) {
if (num == null) return false;
return Pattern.matches(IS_NUM, num);
}
/**
* 校验身份证位数
*
* @return 校验通过返回true,否则返回false
*/
public static boolean isIden_num(String iden) {
if (iden == null) return false;
int length = iden.trim().length();
if (length == 15 || length == 18) return true;
return false;
}
/**
* 校验邮箱
*
* @param email
* @return 校验通过返回true,否则返回false
*/
public static boolean isEmail(String email) {
return Pattern.matches(REGEX_EMAIL, email);
}
/**
* 校验汉字
*
* @param chinese
* @return 校验通过返回true,否则返回false
*/
public static boolean isChinese(String chinese) {
return Pattern.matches(REGEX_CHINESE, chinese);
}
/**
* 校验身份证
*
* @param idCard
* @return 校验通过返回true,否则返回false
*/
public static boolean isIDCard(String idCard) {
return Pattern.matches(REGEX_ID_CARD, idCard);
}
/**
* 校验URL
*
* @param url
* @return 校验通过返回true,否则返回false
*/
public static boolean isUrl(String url) {
return Pattern.matches(REGEX_URL, url);
}
/**
* 校验IP地址
*
* @param ipAddr
* @return
*/
public static boolean isIPAddr(String ipAddr) {
return Pattern.matches(REGEX_IP_ADDR, ipAddr);
}
}
按照代码直接配置就可进行相关校验,谢谢。。。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/80404.html