通过代码对接ConvertX
背景
有一个需求是通过代码对接一个格式转换的开源项目用于格式转换,最后选定了ConvertX这个项目,但是发现没有提供直接可用的API接口,只有WEB端的接口,最后通过分析WEB端的接口请求,成功对接了ConvertX的接口。
ConvertX接口分析
1 | async ({ jwt, redirect, cookie: { auth, jobId } }) => { |
cookie管理的代码如上述,在用户访问时会检查是否有认证cookie,如果没有则会重定向到登录页面,如果有则会验证JWT并在数据库中创建一个新的转换任务,并将任务ID存储在cookie中。
因此,虽然可以在客户端手动生成JWT并设置cookie来模拟登录状态,但更推荐的方式是直接调用后端接口来获取JWT和任务ID,以确保与ConvertX的任务管理兼容。
接口介绍
开启授权的情况下通过登录接口获取cookie
输入:
x-www-form-urlencoded格式的请求体,包含以下字段:
- email: 用户的邮箱地址
- password: 用户的密码
输出:
接口会返回一个set-cookie头,包含认证cookie和任务ID cookie。
1 | set-cookie auth=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjAiLCJleHAiOjE3NzEyOTY2OTYsImlhdCI6MTc3MDY5MTg5Nn0.AnraVgNbtmD4qHENEZNokc2N-kg4_K0bRXJUsSauULw; Max-Age=86400; Path=/; HttpOnly; SameSite=Strict |
1 | curl --location --request POST 'http://127.0.0.1:4523/m1/7789919-7536610-default/login' \ |
未授权的情况下直接获取cookie
在关闭鉴权,比如用容器部署时将ALLOW_UNAUTHENTICATED设置为false时,访问根路径会直接返回一个新的JWT和任务ID,并设置在cookie中,内容同登录接口。
1 | set-cookie auth=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjAiLCJleHAiOjE3NzEyOTY2OTYsImlhdCI6MTc3MDY5MTg5Nn0.AnraVgNbtmD4qHENEZNokc2N-kg4_K0bRXJUsSauULw; Max-Age=86400; Path=/; HttpOnly; SameSite=Strict |
1 | curl --location --request GET 'http://127.0.0.1:4523/m1/7789919-7536610-default/' |
文件上传
form-data格式的请求体,包含以下字段:
- file: 要上传的文件,使用文件上传的方式发送,字段名为file
1 | curl --location --request POST 'http://127.0.0.1:4523/m1/7789919-7536610-default/upload' \ |
获取可用的转换策略
json格式的请求体,包含以下字段:
- fileType: 要转换的目标文件类型,例如docx、pdf等
输出:接口会返回一个html,会被渲染成一个包含可用转换策略的页面,用户可以在页面上选择转换策略并开始转换。
这个地方可以用正则提取出来需要的转换策略信息。可以选择(?<=data-value=")[^"]+或者(?<=option value=")[^"]+
1 | curl --location --request POST 'http://127.0.0.1:4523/m1/7789919-7536610-default/conversions' \ |
样例数据:
最后用正则提取出来的数据为(目标格式,转换工具)的列表
1 | azw3,calibre |
开始转换
json格式的请求体,包含以下字段:
- file_names: 要转换的文件名列表,格式为JSON字符串,例如[“文件名”]
- convert_to: 转换策略,也就是上一步提取出来的转换工具和目标格式的组合,例如pdf,calibre
1 | curl --location --request POST 'http://127.0.0.1:4523/m1/7789919-7536610-default/convert' \ |
获取转换进度和最终结果
此处接口设计有点奇怪,是一个没有body的POST请求,在url中需要使用path 参数传入cookie中存储的任务ID。
输出:
此处需要注意一下
- 这个接口每次调用会返回一个html页面,页面渲染的时候会展示转换进度,如果有需要可以用正则提取出来。
- 直到文件转换完成后,接口才会返回最终结果的下载链接,因此需要轮询调用这个接口来获取转换进度和最终结果,最终结果可以用正则
(?<=href=")/download/[^"]+(?="\s+download=)提取
1 | curl --location --request POST 'http://127.0.0.1:4523/m1/7789919-7536610-default/progress/{id}' |
下载文件
下载接口有鉴权,所以需要带上cookie
- download_path: 从上一个接口提取出来的下载链接中的路径部分,例如/download/0/1/xx.pdf
1 | curl --location --request GET 'http://127.0.0.1:4523/m1/7789919-7536610-default/{download_path}' |
获取最终结果
此处可以获取任务的最终结果,同样是path 参数传入任务ID,接口会返回一个html页面,页面中包含最终结果的下载链接,可以用正则提取出来。
这个接口用处不大,因为转换完成后,进度接口就会返回最终结果的下载链接了。
1 | curl --location --request GET 'http://127.0.0.1:4523/m1/7789919-7536610-default/results/' |
OkHttpClient中如何管理cookie
CookieJar接口是OkHttpClient中用于管理cookie的接口,可以简单实现这个接口,直接将cookie存储在内存中
1 | public static class InMemoryCookieJar implements CookieJar { |
使用方式
1 | OkHttpClient client = new OkHttpClient.Builder() |
