获取http请求头参数-构建http请求上下文

11 篇文章 0 订阅
5 篇文章 0 订阅

一.序言

项目接口中经常会出现获取操作人信息的场景,简单的实现方案通常是从单个接口的HttpServletReuqest中获取解析,比较繁琐。今天在一个新的项目中遇到了,便想着用全局的上下文解决。以下作具体探讨和实现。

二.方案概述

a. 通过HttpServletRequest获取

@PostMapping("/parseHeader")
    public String messageLog(HttpServletRequest request){
        String token = request.getHeader("token");
        return getUserNameByToken(token);
    }

b. 通过@RequestHeader解析

@PostMapping("/parseHeader")
    public String messageLog(@RequestHeader String token){
        return getUserNameByToken(token);
    }

c. 构件全局Http上下文,接口中调用

@PostMapping("/parseHeader")
    public String messageLog(){
        String userName = AppContextUtil.getUserName();
        return userName;
    }

前两种方案在有新的请求头增加时,需要在每一处频繁改动方法签名,而第三种方案只需要在Http上下文中增加解析结果参数,便可以在所有地方使用,比较灵活,代码实现也更简洁。

三.代码实现(第三种解决方案)

  • controller层

    @PostMapping("/parseHeader")
        public String messageLog(){
            String userName = AppContextUtil.getUserName();
            return userName;
        }
    
  • Appcontext(Http上下文)

    @Data
    public class AppContext {
        /**
         * 身份令牌
         */
        private String token;
    
        /**
         * 用户Id
         */
        private String userId;
    
        /**
         * 用户名称
         */
        private String userName;
    
        /**
         * 请求IP
         */
        private String ip;
    }
    
  • 拦截器

    //方便下文注入时获取
    public class PmsInterceptor extends HandlerInterceptorAdapter {
    }
    
    @Component
    @Slf4j
    public class AppContextInterceptor extends PmsInterceptor{
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            AppContext appContext = new AppContext();
            String token = request.getHeader("token");
            appContext.setToken(token);
            appContext.setIp(RequestUtil.getRealIp());
            if(StringUtils.isNotEmpty(token)){
                UserInfo user = getUserFromToken(token);
                if(user != null){
                    appContext.setUserId(user.getUserId());
                    appContext.setUserName(user.getUserName());
                }
            }
    
            request.setAttribute(Constants.APP_CONTEXT, appContext);
            return super.preHandle(request, response, handler);
        }
    
        public UserInfo getUserFromToken(String token){
            //此处添加自己的实现,如从token解密后从数据库中查询用户信息
            UserInfo userInfo = new UserInfo();
            userInfo.setUserId("666");
            userInfo.setUserName("Ciao");
            return userInfo;
        }
    }
    
  • MvcConfig拦截器注册(否则拦截器不生效)

    @Configuration
    @Slf4j
    public class MvcConfig implements WebMvcConfigurer {
        @Resource
        List<PmsInterceptor> pmsInterceptorList;
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            if(CollectionUtils.isEmpty(pmsInterceptorList)){
                return;
            }
    
            for(PmsInterceptor pmsInterceptor : pmsInterceptorList){
                log.info("添加拦截器:{}", pmsInterceptor);
                registry.addInterceptor(pmsInterceptor);
            }
            WebMvcConfigurer.super.addInterceptors(registry);
        }
    }
    
  • RequestUtil请求工具类

    @Slf4j
    public class RequestUtil {
        private RequestUtil(){
        }
    
        public static HttpServletRequest getCurrentHttpRequest() {
            return getCurrentHttpRequest(true);
        }
    
        public static HttpServletRequest getCurrentHttpRequest(boolean warnlog){
            RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
            if(requestAttributes instanceof ServletRequestAttributes){
                return ((ServletRequestAttributes) requestAttributes).getRequest();
            }else{
                if(warnlog){
                    log.warn("not called in the context of attribute");
                }
                return null;
            }
        }
      ...可以自行补充其他方法,如:IPUserAgentHost
    }
    
  • AppContextUtil上下文获取工具类

    public class AppContextUtil {
        private AppContextUtil(){
        }
    
        public static AppContext getAppContext(){
            HttpServletRequest request = RequestUtil.getCurrentHttpRequest();
            if(request == null){
                return new AppContext();
            }
    
            Object attribute = request.getAttribute(Constants.APP_CONTEXT);
            return attribute == null? new AppContext() : (AppContext) attribute;
        }
    
        public static String getUserName(){
            return getAppContext().getUserName();
        }
    
        public static String getToken(){
            return getAppContext().getToken();
        }
    
        public static String getUserId(){
            return getAppContext().getUserId();
        }
    }
    

后续会展开讲解springmvc的调用链路,对拦截器和过滤器的使用场景和区别作详细说明。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用 HttpURLConnection 发送 HTTPS 请求,需要进行以下步骤: 1. 创建一个 URL 对象,指定 HTTPS 请求的地址。 ``` URL url = new URL("https://example.com/api"); ``` 2. 打开 HTTPS 连接,并设置连接属性。 ``` HttpsURLConnection con = (HttpsURLConnection) url.openConnection(); con.setRequestMethod("GET"); con.setConnectTimeout(5000); con.setReadTimeout(5000); ``` 3. 设置 SSL 上下文,包括证书、信任管理器等。 ``` SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom()); con.setSSLSocketFactory(sslContext.getSocketFactory()); ``` 其中,`keyManagerFactory` 和 `trustManagerFactory` 分别是用于管理客户端证书和信任证书的工厂类。 4. 发送请求并获取响应。 ``` BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); String inputLine; StringBuilder response = new StringBuilder(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); ``` 完整代码示例: ``` import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.URL; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; import java.security.KeyStore; import java.security.SecureRandom; public class HttpsURLConnectionExample { public static void main(String[] args) throws Exception { // 1. 创建 URL 对象 URL url = new URL("https://example.com/api"); // 2. 打开 HTTPS 连接,并设置连接属性 HttpsURLConnection con = (HttpsURLConnection) url.openConnection(); con.setRequestMethod("GET"); con.setConnectTimeout(5000); con.setReadTimeout(5000); // 3. 设置 SSL 上下文 KeyStore keyStore = KeyStore.getInstance("JKS"); keyStore.load(HttpsURLConnectionExample.class.getResourceAsStream("/client.jks"), "password".toCharArray()); KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagerFactory.init(keyStore, "password".toCharArray()); KeyStore trustStore = KeyStore.getInstance("JKS"); trustStore.load(HttpsURLConnectionExample.class.getResourceAsStream("/truststore.jks"), "password".toCharArray()); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagerFactory.init(trustStore); SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom()); con.setSSLSocketFactory(sslContext.getSocketFactory()); // 4. 发送请求并获取响应 BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); String inputLine; StringBuilder response = new StringBuilder(); while ((inputLine = in.readLine()) != null) { response.append(inputLine); } in.close(); System.out.println(response.toString()); } } ``` 需要注意的是,这个示例中使用了自签名证书,如果使用的是公开的证书,可以省略第三步。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值