美文网首页
SpringBoot实战—HttpClient

SpringBoot实战—HttpClient

作者: 遇见编程 | 来源:发表于2024-07-11 08:27 被阅读0次
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.13</version>
    </dependency>
    

    实现步骤:

    1. 创建HttpClient对象
    2. 创建请求对象
    3. 发送请求,接受响应结果
    4. 解析结果
    5. 关闭资源
    import org.apache.http.HttpEntity;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.util.EntityUtils;
    import org.junit.jupiter.api.Test;
    import org.springframework.boot.test.context.SpringBootTest;
    
    @SpringBootTest
    public class HttpClientTest {
    
        /**
         * 测试通过httpclient发送GET方式的请求
         */
        @Test
        public void testGET() throws Exception{
            //创建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);
    
            HttpEntity entity = response.getEntity();
            String body = EntityUtils.toString(entity);
            System.out.println("服务端返回的数据为:" + body);
    
            //关闭资源
            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");
    
            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);
    
            HttpEntity entity1 = response.getEntity();
            String body = EntityUtils.toString(entity1);
            System.out.println("响应数据为:" + body);
    
            //关闭资源
            response.close();
            httpClient.close();
        }
    }
    
    

    微信登录案例
    配置微信登录所需配置项:

    application-dev.yml

    sky:
      wechat:
        appid: xxxxxx
        secret: xxxxxxxx
    

    application.yml

    sky:
      wechat:
        appid: ${sky.wechat.appid}
        secret: ${sky.wechat.secret}
    

    配置为微信用户生成jwt令牌时使用的配置项:

    application.yml

    sky:
      jwt:
        # 设置jwt签名加密时使用的秘钥
        admin-secret-key: itcast
        # 设置jwt过期时间
        admin-ttl: 7200000
        # 设置前端传递过来的令牌名称
        admin-token-name: token
        user-secret-key: itheima
        user-ttl: 7200000
        user-token-name: authentication
    
    import lombok.Data;
    import java.io.Serializable;
    /**
     * C端用户登录
     */
    @Data
    public class UserLoginDTO implements Serializable {
    
        private String code;
    
    }
    
    import lombok.AllArgsConstructor;
    import lombok.Builder;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    import java.io.Serializable;
    
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public class UserLoginVO implements Serializable {
        private Long id;
        private String openid;
        private String token;
    }
    
    import com.sky.constant.JwtClaimsConstant;
    import com.sky.dto.UserLoginDTO;
    import com.sky.entity.User;
    import com.sky.properties.JwtProperties;
    import com.sky.result.Result;
    import com.sky.service.UserService;
    import com.sky.utils.JwtUtil;
    import com.sky.vo.UserLoginVO;
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import java.util.HashMap;
    import java.util.Map;
    
    @RestController
    @RequestMapping("/user/user")
    @Api(tags = "C端用户相关接口")
    @Slf4j
    public class UserController {
    
        @Autowired
        private UserService userService;
        @Autowired
        private JwtProperties jwtProperties;
    
        /**
         * 微信登录
         * @param userLoginDTO
         * @return
         */
        @PostMapping("/login")
        @ApiOperation("微信登录")
        public Result<UserLoginVO> login(@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()
                    .id(user.getId())
                    .openid(user.getOpenid())
                    .token(token)
                    .build();
            return Result.success(userLoginVO);
        }
    }
    
    package com.sky.service;
    
    import com.sky.dto.UserLoginDTO;
    import com.sky.entity.User;
    
    public interface UserService {
    
        /**
         * 微信登录
         * @param userLoginDTO
         * @return
         */
        User wxLogin(UserLoginDTO userLoginDTO);
    }
    
    package com.sky.service.impl;
    
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONObject;
    import com.sky.constant.MessageConstant;
    import com.sky.dto.UserLoginDTO;
    import com.sky.entity.User;
    import com.sky.exception.LoginFailedException;
    import com.sky.mapper.UserMapper;
    import com.sky.properties.WeChatProperties;
    import com.sky.service.UserService;
    import com.sky.utils.HttpClientUtil;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import java.time.LocalDateTime;
    import java.util.HashMap;
    import java.util.Map;
    
    @Service
    @Slf4j
    public class UserServiceImpl implements UserService {
    
        //微信服务接口地址
        public static final String WX_LOGIN = "https://api.weixin.qq.com/sns/jscode2session";
    
        @Autowired
        private WeChatProperties weChatProperties;
        @Autowired
        private UserMapper userMapper;
    
        /**
         * 微信登录
         * @param userLoginDTO
         * @return
         */
        public User wxLogin(UserLoginDTO userLoginDTO) {
            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;
        }
    
        /**
         * 调用微信接口服务,获取微信用户的openid
         * @param code
         * @return
         */
        private String getOpenid(String code){
            //调用微信接口服务,获得当前微信用户的openid
            Map<String, String> map = new HashMap<>();
            map.put("appid",weChatProperties.getAppid());
            map.put("secret",weChatProperties.getSecret());
            map.put("js_code",code);
            map.put("grant_type","authorization_code");
            String json = HttpClientUtil.doGet(WX_LOGIN, map);
    
            JSONObject jsonObject = JSON.parseObject(json);
            String openid = jsonObject.getString("openid");
            return openid;
        }
    }
    
    package com.sky.mapper;
    
    import com.sky.entity.User;
    import org.apache.ibatis.annotations.Mapper;
    import org.apache.ibatis.annotations.Select;
    
    @Mapper
    public interface UserMapper {
    
        /**
         * 根据openid查询用户
         * @param openid
         * @return
         */
        @Select("select * from user where openid = #{openid}")
        User getByOpenid(String openid);
    
        /**
         * 插入数据
         * @param user
         */
        void insert(User user);
    }
    

    创建UserMapper.xml映射文件:

    <?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" useGeneratedKeys="true" keyProperty="id">
            insert into user (openid, name, phone, sex, id_number, avatar, create_time)
            values (#{openid}, #{name}, #{phone}, #{sex}, #{idNumber}, #{avatar}, #{createTime})
        </insert>
    
    </mapper>
    

    3.4.8 编写拦截器

    编写拦截器JwtTokenUserInterceptor:统一拦截用户端发送的请求并进行jwt校验

    package com.sky.interceptor;
    
    import com.sky.constant.JwtClaimsConstant;
    import com.sky.context.BaseContext;
    import com.sky.properties.JwtProperties;
    import com.sky.utils.JwtUtil;
    import io.jsonwebtoken.Claims;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.web.method.HandlerMethod;
    import org.springframework.web.servlet.HandlerInterceptor;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * jwt令牌校验的拦截器
     */
    @Component
    @Slf4j
    public class JwtTokenUserInterceptor implements HandlerInterceptor {
    
        @Autowired
        private JwtProperties jwtProperties;
    
        /**
         * 校验jwt
         *
         * @param request
         * @param response
         * @param handler
         * @return
         * @throws Exception
         */
        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);
                BaseContext.setCurrentId(userId);
                //3、通过,放行
                return true;
            } catch (Exception ex) {
                //4、不通过,响应401状态码
                response.setStatus(401);
                return false;
            }
        }
    }
    

    在WebMvcConfiguration配置类中注册拦截器:

        @Autowired
        private JwtTokenUserInterceptor jwtTokenUserInterceptor;
        /**
         * 注册自定义拦截器
         * @param registry
         */
        protected void addInterceptors(InterceptorRegistry registry) {
            log.info("开始注册自定义拦截器...");
            //.........
    
            registry.addInterceptor(jwtTokenUserInterceptor)
                    .addPathPatterns("/user/**")
                    .excludePathPatterns("/user/user/login")
                    .excludePathPatterns("/user/shop/status");
        }
    

    相关文章

      网友评论

          本文标题:SpringBoot实战—HttpClient

          本文链接:https://www.haomeiwen.com/subject/uumwcjtx.html