正式推出:百度搜索引擎细雨算法2.0正式上线

优采云 发布时间: 2022-11-17 04:47

  正式推出:百度搜索引擎细雨算法2.0正式上线

  百度算法小雨算法2.0上线

  2019.11.7 百度更新Drizzle Algorithm 2.0,本次更新主要针对B2B领域的网站。B2B领域主要包括:供求黄页、加盟代理、生产贴牌、批发交易等。

  该算法涵盖PC站点、H5站点、智能小程序内容。对于算法覆盖的站点,小程序会根据违规的严重程度限制搜索结果的展示。

  毛毛雨算法2.0算法详情:

  1.暴力内容

  1. 文章不良内容采集

  

  如:拼接内容、纯采集内容、跨域采集内容等。

  2.发布软文信息误导用户

  示例:利用小程序页面发布软件,如标题“垃圾车厂家哪家好?”,内容为品牌软文,对用户产生误导信息。

  3.空白页

  

  发布一个不符合用户需求的空白页面,对用户来说是完全没有价值的。

  4.产品信息不正确

  示例:商品详情、价格等与实践情况不符。

  5、功能不完善,无法使用

  解决方案:用户微服务用户注册功能实现

  文章目录

  用户在注册前需要向注册的手机号码发送验证码,我们将验证码存储在Redis中。

  发送时,我们先将验证码存储在Redis中,然后在用户发起注册时取出验证码。

  发送验证码

  Redis配置如下:

  package com.zjq.users.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;

import com.fasterxml.jackson.annotation.PropertyAccessor;

import com.fasterxml.jackson.databind.ObjectMapper;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.data.redis.connection.RedisConnectionFactory;

import org.springframework.data.redis.core.RedisTemplate;

import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import org.springframework.data.redis.serializer.StringRedisSerializer;

/**

* redis配置类

* @author zjq

*/

@Configuration

public class RedisTemplateConfiguration {

/**

* redisTemplate 序列化使用的jdkSerializeable, 存储二进制字节码, 所以自定义序列化类

* @param redisConnectionFactory

* @return

*/

@Bean

public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {

RedisTemplate redisTemplate = new RedisTemplate();

redisTemplate.setConnectionFactory(redisConnectionFactory);

// 使用Jackson2JsonRedisSerialize 替换默认序列化

Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

ObjectMapper objectMapper = new ObjectMapper();

objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);

jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

// 设置key和value的序列化规则

redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);

redisTemplate.setKeySerializer(new StringRedisSerializer());

redisTemplate.setHashKeySerializer(new StringRedisSerializer());

redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);

redisTemplate.afterPropertiesSet();

return redisTemplate;

}

}

  新建服务实现发送验证码功能:

  查询是否已根据手机号生成验证码。如果已经生成则直接返回,如果没有生成则生成一个6位验证码。调用短信服务发送短信。消息发送成功,代码保存到Redis。过期时间为60s。

  代码实现如下:

  /**

* 发送验证码业务逻辑层

* @author zjq

*/

@Service

public class SendVerifyCodeService {

@Resource

private RedisTemplate redisTemplate;

/**

* 发送验证码

*

* @param phone

*/

public void send(String phone) {

// 检查非空

AssertUtil.isNotEmpty(phone, "手机号不能为空");

// 根据手机号查询是否已生成验证码,已生成直接返回

if (!checkCodeIsExpired(phone)) {

return;

}

// 生成 6 位验证码

String code = RandomUtil.randomNumbers(6);

// 调用短信服务发送短信

// 发送成功,将 code 保存至 Redis,失效时间 60s

String key = RedisKeyConstant.verify_code.getKey() + phone;

redisTemplate.opsForValue().set(key, code, 60, TimeUnit.SECONDS);

}

/**

* 根据手机号查询是否已生成验证码

*

* @param phone

* @return

*/

private boolean checkCodeIsExpired(String phone) {

String key = RedisKeyConstant.verify_code.getKey() + phone;

String code = redisTemplate.opsForValue().get(key);

return StrUtil.isBlank(code) ? true : false;

}

/**

* 根据手机号获取验证码

*

* @param phone

* @return

*/

public String getCodeByPhone(String phone) {

String key = RedisKeyConstant.verify_code.getKey() + phone;

return redisTemplate.opsForValue().get(key);

}

}

  使用的枚举类RedisKeyConstant:

  @Getter

public enum RedisKeyConstant {

verify_code("verify_code:", "验证码");

private String key;

private String desc;

RedisKeyConstant(String key, String desc) {

this.key = key;

this.desc = desc;

}

<p>

}

</p>

  发送验证码的控制层代码如下:

  /**

* 发送验证码控制层

* @author zjq

*/

@RestController

public class SendVerifyCodeController {

@Resource

private SendVerifyCodeService sendVerifyCodeService;

@Resource

private HttpServletRequest request;

/**

* 发送验证码

*

* @param phone

* @return

*/

@GetMapping("send")

public ResultInfo send(String phone) {

sendVerifyCodeService.send(phone);

return ResultInfoUtil.buildSuccess("发送成功", request.getServletPath());

}

}

  发送验证码接口,需要配置网关释放发送验证码接口/users/send,配置如下:

  secure:

ignore:

urls: # 配置白名单路径

- /actuator/**

- /auth/oauth/**

- /users/signin

- /users/send

  验证发送:

  也可以在Redis中查看手机号发送的验证码信息:

  接下来,继续用户注册过程......

  用户注册检查手机号是否已注册

  在mapper中新建一个通过手机号查询用户的方法:

   /**

* 根据手机号查询用户信息

* @param phone

* @return

*/

@Select("select id, username, phone, email, is_valid " +

" from t_users where phone = #{phone}")

Users selectByPhone(@Param("phone") String phone);

  服务中创建和验证手机号相关方法:

   /**

* 校验手机号是否已注册

*/

public void checkPhoneIsRegistered(String phone) {

AssertUtil.isNotEmpty(phone, "手机号不能为空");

Users diners = usersMapper.selectByPhone(phone);

AssertUtil.isTrue(diners == null, "该手机号未注册");

AssertUtil.isTrue(diners.getIsValid() == 0, "该用户已锁定,请先解锁");

}

  控制层创建相关接口并提供验证:

   /**

* 校验手机号是否已注册

*

* @param phone

* @return

*/

@GetMapping("checkPhone")

public ResultInfo checkPhone(String phone) {

userService.checkPhoneIsRegistered(phone);

return ResultInfoUtil.buildSuccess(request.getServletPath());

}

  网关也需要配置为允许接口:

  secure:

ignore:

urls: # 配置白名单路径

- /actuator/**

- /auth/oauth/**

- /users/signin

- /users/send

- /users/checkPhone

  此时数据库信息如下:

  测试验证:

  现有电话号码:

  不存在的手机号码:

  这个异常显然不够友好。接下来我们定义全局异常配置。

  全局异常配置

  添加全局异常处理类,代码如下:

  /**

* 全局异常处理类

* @author zjq

*/

@RestControllerAdvice

@Slf4j

public class GlobalExceptionHandler {

@Resource

private HttpServletRequest request;

@ExceptionHandler(ParameterException.class)

public ResultInfo handlerParameterException(ParameterException ex) {

String path = request.getRequestURI();

ResultInfo resultInfo =

ResultInfoUtil.buildError(ex.getErrorCode(), ex.getMessage(), path);

return resultInfo;

}

@ExceptionHandler(Exception.class)

public ResultInfo handlerException(Exception ex) {

log.info("未知异常:{}", ex);

String path = request.getRequestURI();

ResultInfo resultInfo =

ResultInfoUtil.buildError(path);

return resultInfo;

<p>

}

}

</p>

  请求一个不存在的手机号,或者一个已经被锁定的手机号,返回如下:

  检查用户名是否已经注册

  在mapper中添加根据用户名查询用户:

   /**

* 根据用户名查询用户信息

* @param username

* @return

*/

@Select("select id, username, phone, email, is_valid " +

" from t_users where username = #{username}")

Users selectByUsername(@Param("username") String username);

  用户注册验证通过后,需要将新用户添加到数据库中,将新用户信息添加到mapper中:

   /**

* 新增用户信息

* @param userDTO

* @return

*/

@Insert("insert into " +

" t_users (username, password, phone, roles, is_valid, create_date, update_date) " +

" values (#{username}, #{password}, #{phone}, \"ROLE_USER\", 1, now(), now())")

int saveUser(UserDTO userDTO);

  UserDTO的内容如下:

  package com.imooc.commons.model.dto;

import io.swagger.annotations.ApiModel;

import io.swagger.annotations.ApiModelProperty;

import lombok.Getter;

import lombok.Setter;

import java.io.Serializable;

@Getter

@Setter

@ApiModel(description = "注册用户信息")

public class DinersDTO implements Serializable {

@ApiModelProperty("用户名")

private String username;

@ApiModelProperty("密码")

private String password;

@ApiModelProperty("手机号")

private String phone;

@ApiModelProperty("验证码")

private String verifyCode;

}

  用户注册逻辑实现

  用户注册步骤如下:

  参数非空验证验证码一致性验证验证用户名是否注册注册密码加密自动登录

  代码实现如下:

   /**

* 用户注册

*

* @param userDTO

* @param path

* @return

*/

public ResultInfo register(UserDTO userDTO, String path) {

// 参数非空校验

String username = userDTO.getUsername();

AssertUtil.isNotEmpty(username, "请输入用户名");

String password = userDTO.getPassword();

AssertUtil.isNotEmpty(password, "请输入密码");

String phone = userDTO.getPhone();

AssertUtil.isNotEmpty(phone, "请输入手机号");

String verifyCode = userDTO.getVerifyCode();

AssertUtil.isNotEmpty(verifyCode, "请输入验证码");

// 获取验证码

String code = sendVerifyCodeService.getCodeByPhone(phone);

// 验证是否过期

AssertUtil.isNotEmpty(code, "验证码已过期,请重新发送");

// 验证码一致性校验

AssertUtil.isTrue(!userDTO.getVerifyCode().equals(code), "验证码不一致,请重新输入");

// 验证用户名是否已注册

Users users = usersMapper.selectByUsername(username.trim());

AssertUtil.isTrue(users != null, "用户名已存在,请重新输入");

// 注册

// 密码加密

userDTO.setPassword(DigestUtil.md5Hex(password.trim()));

usersMapper.saveUser(userDTO);

// 自动登录

return signIn(username.trim(), password.trim(), path);

}

  控制层代码如下:

   /**

* 注册

*

* @param userDTO

* @return

*/

@PostMapping("register")

public ResultInfo register(@RequestBody UserDTO userDTO) {

return userService.register(userDTO, request.getServletPath());

}

  核实

  新用户发起注册。

  检查电话号码是否已注册:

  发送验证码:

  执行注册操作:

  可以看到验证码是807596:

  第一次故意等验证码过期再执行,返回如下:

  然后重新发送验证码:

  再次输入错误的验证码,返回如下:

  如果输入正确,返回自动登录的token信息:

  本篇内容到此结束,

  有什么收获请点赞采集关注✔️,您的鼓励就是我最大的动力。

  如有错误和问题,请指出。

  首页:喝一杯小吴的博文摘要‍

  保持爱,去下山下海。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线