外卖小程序05

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请求
     */
    @Test
    public 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请求
     */
    @Test
    public 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: itheima
    user-ttl: 7200000
    user-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;//用户id
    private String openid;//微信用户唯一标识openid
    private String token;//jwt令牌

}

Controller层

@RestController
@RequestMapping("user/user")
@Slf4j
@Api(tags = "用户相关接口")
public class UserController {

    @Autowired
    private UserService userService;
    @Autowired
    private 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";
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private WeChatProperties weChatProperties;

    @Override
    public User WXLogin(UserLoginDTO userLoginDTO) {
        //调用微信接口服务,获取当前用户的openid
        String 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 {

    @Autowired
    private JwtProperties jwtProperties;

    /**
     * 校验jwt
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public 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 {

    @Autowired
    private JwtTokenUserInterceptor jwtTokenUserInterceptor;

    /**
     * 注册自定义拦截器
     *
     * @param registry
     */
    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        log.info("开始注册自定义拦截器...");
        registry.addInterceptor(jwtTokenUserInterceptor)
                .addPathPatterns("/user/**")
                .excludePathPatterns("/user/user/login")
                .excludePathPatterns("/user/shop/status");
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Laravel小程序源码是一个使用Laravel框架开发的小程序的源代码。Laravel是一种流行的PHP框架,拥有简洁的语法和强大的功能,可以有效地帮助开发人员构建高质量的Web应用程序。 这个小程序源码包含了一个完整的系统的基本功能,包括用户注册登录、浏览商家菜单、下单、支付、订单管理等。它提供了一个友好的用户界面,用户可以方便地浏览不同商家的菜单和信息,并下单购买食物。 使用Laravel框架的好处是它的灵活性和可扩展性。开发人员可以根据自己的需求进行自定义和扩展,添加新的功能或修改现有功能,以满足特定的业务需求。此,Laravel还提供了很多强大的工具和功能,如数据库迁移、数据验证、缓存管理等,帮助开发人员提高开发效率和代码质量。 使用这个小程序源码,开发人员可以快速搭建一个系统并进行二次开发,根据自己的需求进行定制。它可以帮助开发人员省去从头开始构建一个系统的时间和精力,提高开发效率和项目质量。 总之,Laravel小程序源码是一个用来构建小程序的基础代码,它提供了一个完整的系统的功能,用户可以根据自己的需求进行二次开发和定制。无论是初学者还是有经验的开发人员,使用这个源码都可以快速地构建一个高质量的小程序

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值