> 文章列表 > 外卖小程序05

外卖小程序05

外卖小程序05

目录

  • HttpClient
    • 作用
    • 发送http请求步骤
    • 测试使用HttpClient发送Http请求
      • 测试类
  • 微信小程序用户登录
    • 登录流程
    • 相关配置
    • 代码实现
      • 用户登录实体类UserLoginDTO
      • 返回数据实体类UserLoginVO
      • Controller层
      • Service层
      • Mapper层
      • 拦截器JwtTokenUserInterceptor
      • 注册拦截器

HttpClient

作用

发送http请求

接收响应数据

发送http请求步骤

1.创建HttpClient对象

2.创建Http请求对象

3.调用HttpClient对象的execute方法,传入请求对象

测试使用HttpClient发送Http请求

测试类

/*** HttpClient:可以用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议* Maven坐标:* <dependency>* <groupId>org.apache.httpcomponents</groupId>* <artifactId>httpclient</artifactId>* <version>4.5.13</version>* </dependency>* HttpClient的核心API:* - HttpClient:Http客户端对象类型,使用该类型对象可发起Http请求。* - HttpClients:可认为是构建器,可创建HttpClient对象。* - CloseableHttpClient:实现类,实现了HttpClient接口。* - HttpGet:Get方式请求类型。* - HttpPost:Post方式请求类型。*/
@SpringBootTest
public class HttpClientTest {/*** 测试通过HttpClient发送GET请求*/@Testpublic void testGET() throws IOException {//创建HttpClient对象CloseableHttpClient httpClient = HttpClients.createDefault();//创建请求对象HttpGet httpGet = new HttpGet("http://localhost:8080/user/shop/status");//发送请求,接收响应数据CloseableHttpResponse response = httpClient.execute(httpGet);//获取响应状态码int statusCode = response.getStatusLine().getStatusCode();System.out.println("服务端响应的响应状态码:" + statusCode);//服务端返回的响应状态码:200//获取响应数据HttpEntity entity = response.getEntity();String body = EntityUtils.toString(entity);System.out.println("服务端响应的数据:" + body);  //服务端返回的数据:{"code":1,"msg":null,"data":1}//关闭资源response.close();httpClient.close();}/*** 通过HttpClient测试POST请求*/@Testpublic void testPOST() throws Exception {//创建HttpClient对象CloseableHttpClient httpClient = HttpClients.createDefault();//创建请求对象HttpPost httpPost = new HttpPost("http://localhost:8080/admin/employee/login");//创建json对象JSONObject jsonObject = new JSONObject();jsonObject.put("username", "admin");jsonObject.put("password", "123456");StringEntity entity = new StringEntity(jsonObject.toString());//指定请求编码方式entity.setContentEncoding("utf-8");//数据格式entity.setContentType("application/json");httpPost.setEntity(entity);//发送请求,接收响应数据CloseableHttpResponse response = httpClient.execute(httpPost);//获取响应状态码int statusCode = response.getStatusLine().getStatusCode();System.out.println("服务端响应的响应状态码:" + statusCode);//服务端响应的响应状态码:200//获取响应数据HttpEntity responseEntity = response.getEntity();String body = EntityUtils.toString(responseEntity);System.out.println("服务端响应的数据:" + body);  //服务端响应的数据:{"code":1,"msg":null,"data":{"id":1,"userName":"admin","name":"管理员","token":"jwt令牌"}}//关闭资源response.close();httpClient.close();}
}

微信小程序用户登录

登录流程

​ >由小程序端获取用户微信登录的授权码,并将授权码通过请求发送到服务端,服务端接收到授权码后,向微信接口发送请求,获取用户唯一标识openid,并向用户返回openid和token等

相关配置

  wechat:appid: ***********secret: ****************jwt:user-secret-key: itheimauser-ttl: 7200000user-token-name: authentication

代码实现

用户登录实体类UserLoginDTO

/*** C端用户登录*/
@Data
public class UserLoginDTO implements Serializable {private String code;//授权码}

返回数据实体类UserLoginVO

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserLoginVO implements Serializable {private Long id;//用户idprivate String openid;//微信用户唯一标识openidprivate String token;//jwt令牌}

Controller层

@RestController
@RequestMapping("user/user")
@Slf4j
@Api(tags = "用户相关接口")
public class UserController {@Autowiredprivate UserService userService;@Autowiredprivate JwtProperties jwtProperties;@PostMapping("login")@ApiOperation("微信登录")public Result<UserLoginVO> userLogin(@RequestBody UserLoginDTO userLoginDTO) {log.info("微信用户登录:{}", userLoginDTO.getCode());//微信登录User user = userService.WXLogin(userLoginDTO);//为微信用户生成jwt令牌Map<String, Object> claims = new HashMap<>();claims.put(JwtClaimsConstant.USER_ID, user.getId());String token = JwtUtil.createJWT(jwtProperties.getUserSecretKey(), jwtProperties.getUserTtl(), claims);UserLoginVO userLoginVO = UserLoginVO.builder().token(token).id(user.getId()).openid(user.getOpenid()).build();return Result.success(userLoginVO);}
}

Service层

@Service
public class UserServiceImpl implements UserService {private static final String WX_LOGIN = "https://api.weixin.qq.com/sns/jscode2session";@Autowiredprivate UserMapper userMapper;@Autowiredprivate WeChatProperties weChatProperties;@Overridepublic User WXLogin(UserLoginDTO userLoginDTO) {//调用微信接口服务,获取当前用户的openidString openid = getOpenid(userLoginDTO.getCode());//判断openid是否为空,为空表示登陆失败,抛出业务异常if (openid == null) {throw new LoginFailedException(MessageConstant.LOGIN_FAILED);}//判断当前用户是否为新用户User user = userMapper.getByOpenid(openid);//如果是新用户,自动完成注册if (user == null) {user = User.builder().openid(openid).createTime(LocalDateTime.now()).build();userMapper.insert(user);}//返回用户对象return user;}private String getOpenid(String code) {Map<String, String> paramMap = new HashMap<>();paramMap.put("appid", weChatProperties.getAppid());paramMap.put("secret", weChatProperties.getSecret());paramMap.put("js_code", code);paramMap.put("grant_type", "authorization_code");String json = HttpClientUtil.doGet(WX_LOGIN, paramMap);JSONObject jsonObject = JSON.parseObject(json);String openid = jsonObject.getString("openid");return openid;}
}

Mapper层

@Mapper
public interface UserMapper {@Select("select * from user where openid = #{openid}")User getByOpenid(String openid);void insert(User user);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sky.mapper.UserMapper"><insert id="insert" keyProperty="id" useGeneratedKeys="true">insert into user(id, openid, name, phone, sex, id_number, avatar, create_time)values (#{id}, #{openid}, #{name}, #{phone}, #{sex}, #{idNumber}, #{avatar}, #{createTime});</insert></mapper>

拦截器JwtTokenUserInterceptor

/*** jwt令牌校验的拦截器*/
@Component
@Slf4j
public class JwtTokenUserInterceptor implements HandlerInterceptor {@Autowiredprivate JwtProperties jwtProperties;/*** 校验jwt** @param request* @param response* @param handler* @return* @throws Exception*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {//判断当前拦截到的是Controller的方法还是其他资源if (!(handler instanceof HandlerMethod)) {//当前拦截到的不是动态方法,直接放行return true;}//1、从请求头中获取令牌String token = request.getHeader(jwtProperties.getUserTokenName());//2、校验令牌try {log.info("jwt校验:{}", token);Claims claims = JwtUtil.parseJWT(jwtProperties.getUserSecretKey(), token);Long userId = Long.valueOf(claims.get(JwtClaimsConstant.USER_ID).toString());log.info("当前用户id:", userId);//将用户id存入ThreadLocal中BaseContext.setCurrentId(userId);//3、通过,放行return true;} catch (Exception ex) {//4、不通过,响应401状态码response.setStatus(401);return false;}}
}

注册拦截器

/*** 配置类,注册web层相关组件*/
@Configuration
@Slf4j
public class WebMvcConfiguration extends WebMvcConfigurationSupport {@Autowiredprivate JwtTokenUserInterceptor jwtTokenUserInterceptor;/*** 注册自定义拦截器** @param registry*/@Overrideprotected void addInterceptors(InterceptorRegistry registry) {log.info("开始注册自定义拦截器...");registry.addInterceptor(jwtTokenUserInterceptor).addPathPatterns("/user/**").excludePathPatterns("/user/user/login").excludePathPatterns("/user/shop/status");}
}