MySQL数据库,实战SpringCloud通用请求字段拦截处理

Posted 程序员超时空

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL数据库,实战SpringCloud通用请求字段拦截处理相关的知识,希望对你有一定的参考价值。

 }

}


简单来说,ThreadLocal最关键的get()和set()方法,都是针对当前线程来操作的,调用set()方法时把值放到ThreadMap(Map的一种实现)中,以当前线程的hash值为key,get()方法则对应以当前线程作为key来取值,从而实现每个线程的数据是隔离的效果。

另附上ThreadLocal类源码解读的导图,仅供参考

![](https://upload-images.jianshu.io/upload_images/13465705-1a535a0bdf7e496f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

### 案例实战

我们对实际业务系统进行简化处理,假定header信息固定有ip,uid,deviceId三个信息,按照上文的实现思路,开始案例演示。

#### DTO定义

通用的header信息,使用Dto对象进行封装:

@Data
public class CommonHeader implements Serializable {

private static final long serialVersionUID = -3949488282201167943L;

/**
 * 真实ip
 */
private String ip;

/**
 * 设备id
 */
private String deviceId;

/**
 * 用户uid
 */
private Long uid;

// 省略getter/setter/构造器

}


定义Request请求的封装类Dto,并引入ThreadLocal:

/**

  • 将公共请求头信息放在ThreadLocal中去
    */
    public class RequestWrap {

    private static ThreadLocal current = new ThreadLocal<>();

    /**

    • 获取静态的ThreadLocal对象
    • @return
      */
      public static ThreadLocal getCurrent() {
      return current;
      }

    /**

    • 获取ip
    • @return
      */
      public static String getIp() {
      CommonHeader request = current.get();
      if (request == null) {
      return StringUtils.EMPTY;
      }
      return request.getIp();
      }

    /**

    • 获取uid
    • @return
      */
      public static Long getUid() {
      CommonHeader request = current.get();
      if (request == null) {
      return null;
      }
      return request.getUid();
      }

    /**

    • 获取封装对象
    • @return
      */
      public static CommonHeader getCommonReq() {
      CommonHeader request = current.get();
      if (request == null) {
      return new CommonHeader(StringUtils.EMPTY, StringUtils.EMPTY,0L);
      }
      return request;
      }
      }

#### 工具类

这里添加一个简单的工具类,将HttpServletRequest通过getHeader方法,生成CommonHeader类:

public class HttpUtil {
/**
* 获取请求头信息
*
* @param request
* @return
*/
public static CommonHeader getCommonHeader(HttpServletRequest request) {
String UID = request.getHeader(“uid”);
Long uid = null;
if (StringUtils.isNotBlank(UID)) {
uid = Long.parseLong(UID);
}
return new CommonHeader(HttpUtil.getIp(request), request.getHeader(“deviceId”), uid);
}

/**
 * 获取IP
 *
 * @param request
 * @return
 */
public static String getIp(HttpServletRequest request) {
	String ip = request.getHeader("X-Forwarded-For");

	if (null != ip && !"".equals(ip.trim()) && !"unknown".equalsIgnoreCase(ip)) {
		int index = ip.indexOf(',');
		if (index != -1) {
			return ip.substring(0, index);
		} else {
			return ip;
		}
	}
	ip = request.getHeader("X-Real-IP");
	if (null != ip && !"".equals(ip.trim()) && !"unknown".equalsIgnoreCase(ip)) {
		return ip;
	}
	return request.getRemoteAddr();
}

}


#### 拦截器类实现

最核心的实现终于出场了,这里继承HandlerInterceptorAdapter,这里作了简化处理:

/**

  • 请求头处理

  • @author yangfei
    */
    @Component
    public class BaseInterceptor extends HandlerInterceptorAdapter {

    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(BaseInterceptor.class);

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
    throws Exception {
    RequestWrap.getThreadLocal().set(HttpUtil.getCommonHeader(request));
    return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
    ModelAndView modelAndView) throws Exception {
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
    throws Exception {
    RequestWrap.getThreadLocal().remove();
    }

    @Override
    public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler)
    throws Exception {
    }
    }


如上一章节描述的逻辑,在preHandle方法内将request中的ip,uid,deviceId封装到RequestWrap对象里,在afterCompletion中对该线程的ThreadLocal值进行释放。

#### 业务接口方法的使用

在Controller类的接口方法中,如要获取uid信息,只需要调用RequestWrap.getUid()方法即可,再也不需要在每个接口上声明uid参数了,如下示例:

最后

现在其实从大厂招聘需求可见,在招聘要求上有高并发经验优先,包括很多朋友之前都是做传统行业或者外包项目,一直在小公司,技术搞的比较简单,没有怎么搞过分布式系统,但是现在互联网公司一般都是做分布式系统。

所以说,如果你想进大厂,想脱离传统行业,这些技术知识都是你必备的,下面自己手打了一份Java并发体系思维导图,希望对你有所帮助。

资料获取方式:戳这里免费下载

,包括很多朋友之前都是做传统行业或者外包项目,一直在小公司,技术搞的比较简单,没有怎么搞过分布式系统,但是现在互联网公司一般都是做分布式系统。

所以说,如果你想进大厂,想脱离传统行业,这些技术知识都是你必备的,下面自己手打了一份Java并发体系思维导图,希望对你有所帮助。

资料获取方式:戳这里免费下载

以上是关于MySQL数据库,实战SpringCloud通用请求字段拦截处理的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 5.7新支持--------通用表空间实战

springCloud分布式事务实战准备数据库和创建第一个微服务

基于SpringBoot+SpringCloud+Vue前后端分离项目实战 --开篇

一套牛逼的SpringCloud微服务电商实战项目,文档贼全!

SpringCloud系列——nacos组件服务注册与发现功能实战

springCloud分布式事务实战编写第二个微服务