缓存request流

当接口请求的时候使用application/json之类的文本格式的时候,获取的时候需要从request的body体里获取,当需要使用过滤器、拦截器或者AOP的时候,难免会遇到读流的问题,拦截到的request读取过一次之后在Controller中就无法再获取,此处记录解决方案:

1
2
3
4
5
6
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
// 缓存request到ApiHttpServletRequestWrapper中
ApiHttpServletRequestWrapper wrapper = new ApiHttpServletRequestWrapper(request);
String jsonStr = RequestJsonUtil.getRequestJsonString(wrapper);
Map<String, Object> param = JSONObject.fromObject(jsonStr);

阅读更多

springmvc实现restful api版本控制并兼容swagger

开发的时候经常会出现接口的变更,而接口的变更又常需兼容老的客户端版本,此时便需要做接口的版本控制,比较好的方案是在header带上version参数,但是不排除有些在url上做控制的,类似/v1/xxx/xxx,/v2_0/xxx/xxx,此文为第二种,使用如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@RestController
@Api(value = "测试", tags = {"测试"})
@RequestMapping("/{version}/test/")
public class TestController {
@Autowired
private TestService testService;
@ApiOperation(value = "测试接口", notes = "测试")
@PostMapping(value = "test")
@ApiVersion("1_0")
public Object region(@RequestBody TestReq model) {
return testService.test(model);
}
}

阅读更多

使用kong0.10.x配置oauth2.0的坑

kong的安装和配置启动之前一篇博文已经讲过,这里推荐一个UI管理:kong-dashboard,功能还不是很强大,但是可以省去一些比较基础的配置(api,consumers,plugins的管理),安装配置地址如下: 官方链接

阅读更多

游泳攻略

游泳攻略

阅读更多

使用kong管理api

摘要:Kong,Mashape开源的API层。是基于Nginx_Lua模块写的。是一个基于openresty的api代理层,数据采用了 Apache Cassandra/PostgreSQL存储,并且提供了一些优秀的插件,比如验证,日志,调用频次限制等。
详细资料见官网:https://getkong.org
环境:ubuntu 16.04
1、下载kong:https://getkong.org/install/ 在此页面选择你的系统,之后再下载相应的系统版本,因为我是 unbuntu 16.04,则下载https://github.com/Mashape/kong/releases/download/0.10.3/kong-0.10.3.xenial_all.deb

阅读更多

springboot+rabbitmq简单使用

搭建springboot的时候比较喜欢用多模块管理,所以先新建一个父maven程序,select archetype时选择maven-archetype-site-simple,创建完后,pom.xml如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>per.example.mq</groupId>
<artifactId>example-mq-parent</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>example-mq-parent</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencyManagement>
<dependencies>
<!-- Import dependency management from Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.3.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--如果要把springboot工程打包成war执行,需要该jar -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-legacy</artifactId>
<version>1.0.2.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>
</project>

阅读更多

AOP拦截Controller处理@RequestBody注入参数问题

问题: 使用springMVC,一些请求前的校验,都可以在拦截器或者过滤器里做处理,处理完后到Controller层再根据喜好做相关操作,但是遇到content-type是application/json等放在body体里的就尴尬了,读完body,在Controller就无法再获取一次了,或许你可以把request的inputStream读出来缓存两份。但这要动根基了,不划算。另外,如果需要改变某个参数再由@RequestBody注入,又是一个尴尬的问题,可以把配置的Json处理写成自己的逻辑。但所有请求都经过这个也显得累赘。

阅读更多

使用redis维护token

用redis维护token的思路:

存入

1
2
3
4
5
6
7
8
// 生成token
String token = UUID.randomUUID().toString();
// 将对象转为Json串
String json = JacksonUtils.newInstance().obj2json(user);
// 以token为key,对象为value缓存到redis
jedisUtils.set(token, json, 120 * 60);
// 将userId - token以key - value的形式放入到一个hash表中,这里最好遵循标准的命名规则:(项目:模块:形式)
jedisUtils.hset("project:sso:uid_token", "project:sso:".concat(user.getUserId()), token);

阅读更多

Java下载文件损坏问题

开发的过程中经常需要导出各种报表,生成表的过程此处不表。说说下载遇到的问题:

下载可以分为2种,一种是将文件保存到某个位置,然后返回url让client进行访问下载,但大多数时候我们并不需要这些文件,这个时候就浪费了磁盘空间,即便后面做了清理,也是比较不友好的一种情况。所以我们一般都是直接以流的形式将文件传给client
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@RequestMapping("/export")
public ResponseEntity<byte[]> export() {
byte[] body = null;
String url = "你的资源文件url";
HttpURLConnection conn = (HttpURLConnection) (new URL(url)).openConnection();
// 不管你是读本地文件,网络文件还是Workbook等等,这里以网络文件为例
InputStream in = conn.getInputStream();
body = new byte[in.available()];
in.read(body);
HttpHeaders headers = new HttpHeaders();
// 响应头的名字和响应头的值
headers.add("Content-Disposition", "attachment;filename=" + "文件名,要加后缀");
HttpStatus statusCode = HttpStatus.OK;
ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(body, headers, statusCode);
return response;
}

阅读更多

Spring boot的入门使用

pom.xml的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>test</name>
<url>http://maven.apache.org</url>
<!-- 若已经有父项目依赖,则在父项目中添加如下代码 -->
<!-- <dependencyManagement>
<dependencies>
<dependency>
Import dependency management from Spring Boot
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.2.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement> -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.0.RELEASE</version>
</parent>
<properties>
<!-- 项目编码配置 start -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- 项目编码配置 end -->
<!-- 依赖的jar的版本号控制 start -->
<!-- 依赖的jar的版本号控制 end -->
</properties>
<dependencies>
<!-- 核心模块,包括自动配置支持、日志和YAML -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- 测试模块,包括JUnit、Hamcrest、Mockito -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Web模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>1.2.5.RELEASE</version>
</dependency>
</dependencies>
<configuration>
<!-- 热部署配置 -->
<jvmArguments>
-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005
</jvmArguments>
<!-- spring-boot 默认使用1.6,若使用其它版本,需要指定好相应版本 -->
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

阅读更多