外卖小程序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");}
}