国庆7天,写了一个轻量级API框架
有些项目是我们自己或者为朋友所开发的,功能比较简单,接口也比较少,但通常使用SpringBoot开发后,少说也得20M,传输部署也不方便,且这个jar中很可能有80%-90%的代码是永远得不到执行的,但他可能被虚拟机所加载,占用一部分内存。所以在国庆7天写了一个小型的后端框架,称为mini-api,他的源码只有141KB,但由于引入了其他框架,所以最终大小为10M,可以使用下面方式将min-api
前言
有些项目是我们自己或者为朋友所开发的,功能比较简单,接口也比较少,但通常使用SpringBoot开发后,少说也得20M,传输部署也不方便,且这个jar中很可能有80%-90%的代码是永远得不到执行的,但他可能被虚拟机所加载,占用一部分内存。
所以在国庆7天写了一个小型的后端框架,称为mini-api
,他的源码只有141KB,但由于引入了其他框架,所以最终大小为10M,可以使用下面方式将min-api
引入到你的项目。
Gradle
implementation 'com.houxinlin:mini-api:1.0.3'
Maven
<dependency>
<groupId>com.houxinlin</groupId>
<artifactId>mini-api</artifactId>
<version>1.0.3</version>
</dependency>
注意,1.0.0
、1.0.2
由于测试不周到,存在一些问题,需要从1.0.3开始。
框架本身依赖的第三方库如下
- gson:作用于json解析
- asm:作用于class文件解析
- kotlin,由于项目是kotlin方法,所以会包含一些kotlin必备的库
- mybatis:数据库查询
- mysql:mysql驱动
项目地址:
https://github.com/houxinlin/mini-api
示例
创建实例
CoolMini的构造方法需要一个端口号,且调用start后表示启动服务,他的参数同SpringBoot启动方法一样,会扫描目标Class所在包下的所有子包,这些子包下应包含标有@RestController
注解的类,同SpringBoot一样。
public class Main {
public static void main(String[] args) throws Throwable {
CoolMini coolMini = new CoolMini(7070);
coolMini.start(Main.class);
}
}
简单请求
创建请求同SpringBoot中一样,mini-api
提供了@GetMapping
、@PostMapping
、@PutMapping
、@DeleteMapping
映射。
获取参数也一样,mini-api
提供了以下几个注解用于从请求中获取参数。
-
@RequestParam
用于从请求url、请求体中
Content-Type
类型为application/x-www-form-urlencoded
、form-data中获取参数,参数类型可以根据实际参数类型改变,不一定是String类型,但为了方便,提供了一个HttpParameterTypeConverter
参数转换器,在后面会说。
@RestController
public class IndexController {
@GetMapping("/get")
public String index(@RequestParam("name") String name,@RequestParam("age") int age) {
System.out.println(name +" "+age);
return name;
}
}
@PathVariable
同SpringBoot
@GetMapping("/get/{user}")
public String index(@PathVariable("user") String user) {
return user;
}
@RequestUri
获取请求url地址
@RestController
public class IndexController {
@GetMapping("/get/{user}")
public String index(@RequestUri String url) {
return url;
}
}
@RequestBody
获取请求体,参数类型不一定是String,可以是具体对象,也可以是List,解析使用Gson解析,但也可以自定义json解析器。
@PostMapping("/get")
public String index(@RequestBody String body) {
return body;
}
文件请求
由于不是基于Servlet规范,以往的Servlet方法在mini-api
中都无法使用,而对于文件请求,可以直接使用下面方式获取,如果多个文件,可以使用List<FilePart>
接收。
@RestController
public class IndexController {
@PostMapping("/get")
public String index(
@RequestParam("name")String name,
@RequestParam("file") FilePart filePart) throws IOException {
byte[] buffer =new byte[((int) filePart.getContentLength())];
filePart.inputStream.read(buffer);
Files.write(Paths.get("/home/HouXinLin/temp-files/temp.txt"),buffer);
return "OK";
}
}
Session
mini-api
提供了简单的session功能,用来在服务端存储一些数据,可以用来做认证。
@RestController
public class IndexController {
@GetMapping("/get")
public String get(Session session) {
return session.getAttibute("name","").toString();
}
@GetMapping("/set")
public String set(Session session) {
session.setTnvalidTime(1000*10);
session.setAttribute("name","张三");
return "OK";
}
}
HttpParameterTypeConverter接口
用于把请求参数转换为自定义数据类型,比如url中有个参数为name=张三,如果你想通过下面方法接收。
@RestController
public class IndexController {
@GetMapping("/get")
public String index(@RequestParam("name") User name,@RequestParam("age") int age) {
System.out.println(name +" "+age);
return name.toString();
}
}
那么需要添加一个参数转换器
public class Main {
public static void main(String[] args) throws Throwable {
CoolMini coolMini = new CoolMini(7070);
coolMini.addHttpParameterTypeConverter(true,new HttpParameterTypeConverter<User>(){
@Override
public boolean canConvert(@NotNull MethodParameter methodParameter, @NotNull String s) {
//返回是否能转换此参数
return User.class.equals(methodParameter.param.getType());
}
@Nullable
@Override
public User typeConvert(String value) {
return new User(value);
}
});
coolMini.start(Main.class);
}
}
HttpIntercept接口
用于拦截所有请求,intercept方法如果返回true则表示拦截,那么postHandler方法将会被调用,可以通过httpRequestAdapter.setResponse
设置响应。
CoolMini coolMini = new CoolMini(7070);
coolMini.addHttpIntercept(new HttpIntercept() {
@Override
public boolean intercept(@NotNull HttpRequestAdapter httpRequestAdapter) {
return false;
}
@Override
public void postHandler(@NotNull HttpRequestAdapter httpRequestAdapter) {
httpRequestAdapter.setResponse("拦截");
}
});
coolMini.start(Main.class);
ArgumentResolver接口
用于参数转换,不同于HttpParameterTypeConverter,HttpParameterTypeConverter用于已知参数名,但无法把String类型参数转换为目标方法中的实际参数类型。
ArgumentResolver接口则可以最大能力进行参数转换,多数用于从请求体中进行获取。
coolMini.addArgumentResolvers(true, new ArgumentResolver() {
@Override
public boolean support(@NotNull MethodParameter methodParameter, @NotNull HttpRequestAdapter httpRequestAdapter) {
return methodParameter.param.getType()== User.class;
}
@Nullable
@Override
public Object resolver(@NotNull MethodParameter methodParameter, @NotNull HttpRequestAdapter httpRequestAdapter, @NotNull MappingInfo mappingInfo) {
String requestBody = new String(httpRequestAdapter.getRequestBody());
return new User(requestBody);
}
});
@RestController
public class IndexController {
@PostMapping("/get")
public String index( User user) {
return user.toString();
}
}
全局认证器
mini-api
提供了一个全局认证器,所有请求都会拦截(如果被设置了的话),所以就需要提供一个登录接口地址,用于认证。
coolMini.setAuthorization(new MiniAuthentication("/login", new AuthenticationIntercept() {
@Override
public boolean intercept(@NotNull HttpRequestAdapter httpRequestAdapter) {
// 返回true则表示拦截
return false;
}
@Override
public void postHandler(@NotNull HttpRequestAdapter httpRequestAdapter) {
}
}));
DataSource
mini-api
结合了mybatis进行数据库查询,扩展了动态sql,但也保留了原来mybatis通过接口+注解的方式查询,但在查询之前,需要提供一个数据源。
CoolMini coolMini = new CoolMini(7070);
coolMini.setDataSource(new MysqlDataSource("root","pass-+","jdbc:mysql://localhost:3306/day"));
coolMini.start(Main.class);
这里的动态sql不是指mybatis的动态标签,而是可以直接以字符方式进行查询,如下。
@RestController
public class IndexController {
@AutowriteCrud
MybatisCrudRepository crudRepository;
@GetMapping("/get")
public List<User> index( ) {
List<User>users =crudRepository.list("select * from aunt_day", User.class);
return users;
}
}
在设置了数据源后,就可以通过@AutowriteCrud
注解自动注入一个BaseCrudRepository
实例,默认实现是MybatisCrudRepository,未来可能会加入其他,如果不想通过字符串这种方式,可以使用mybatis原生Mapper接口方式,但不支持xml方式。
@RestController
public class IndexController {
interface Mapper{
@Select("select * from aunt_day")
List<User> listUser();
}
@AutowriteCrud
MybatisCrudRepository crudRepository;
private Mapper mapper;
public void init(){
mapper =crudRepository.getMapper(Mapper.class);
}
@GetMapping("/get")
public List<User> index( ) {
List<User>users =mapper.listUser();
return users;
}
}
更多推荐
所有评论(0)