java 轻量级 job_oxygen: 一个轻量级Java框架,包含ioc、aop、config、cache、job、Jdbc、web等...
oxygen
轻量级Java框架
介绍
一个轻量级Java框架
oxygen-core
配置管理,支持${attrs.key:defaultValue}表达式获取配置
加解密管理,提供加解密服务内置基础加密实现,例如SHA-1、SHA-256、MD5
异常管理,提供异常包装,统一异常编码,便于国际化
i18n国际化
资源文件加载,提供file,jar,classpath等文件加载
类扫描器
部分工具类
retry重试
oxygen-ioc
基于构造器的轻量级依赖注入
oxygen-aop
基于cglib实现的切面
轻巧简单,可单独使用
可使用注解Aspect或直接实现Interceptor编写切面
oxygen-cache
内置Ehcache和LocalCache缓存
提供基于注解Cacheable的方法缓存
oxygen-job
提供基于注解Scheduled的定时任务
oxygen-jdbc
小巧简单的jdbc实现,纯jdk实现,无第三方jar
支持多数据源
基于sql进行crud,不提供类似Hibernate的链式方法(原因:sql作为数据库领域的DSL,已经很自然优雅,Less is more)
oxygen-web
轻量级web框架支持注解声明和函数式编程
支持Servlet3.0 ServletContainerInitializer 自动加载,省略web.xml
支持i18n动态切换
提供WebHook进行请求拦截处理
支持自定义全局异常处理
特性
轻量级,使用简单
支持插件扩展
函数式编程
流式风格
快速开始
创建Maven项目
-tomcat
vip.justlive
oxygen-web${oxygen.server}
${oxygen.version}
或Gradle
compile 'vip.justlive:oxygen-web-tomcat:$oxygenVersion'
不需要webapp项目框架,支持Servlet3.0
编写 main 函数写一个 Hello World
public static void main(String[] args) {
Router.router().path("/").handler(ctx -> ctx.response().write("hello world"));
Server.server().listen(8080);
}
用浏览器打开 http://localhost:8080 这样就可以看到 hello world 了!
内容详解
注册路由
硬编码方式
Router.router().path("/").handler(ctx -> ctx.response().write("hello world"));
Router.router().path("/get").method(HttpMethod.GET).handler(get);
Router.router().path("/post").method(HttpMethod.POST).handler(post);
注解方式
@Router("/book")
public class BookRouter {
// 视图
@Mapping("/")
public ViewResult index() {
return Result.view("/book.html");
}
// json
@Mapping(value = "/ajax", method = {HttpMethod.POST})
public Book find(RoutingContext ctx) {
// ...
return new Book();
}
}
获取请求参数
表单参数或json请求参数
项目将json请求参数与表单参数合并,使用相同的方法或注解获取
使用RoutingContext获取
Router.router().path("/").handler(ctx -> {
String id = ctx.request().getParam("id");
ctx.response().write(id);
});
使用注解获取
@Mapping(value = "/ajax", method = {HttpMethod.POST})
public Book find(@Param Long id, @Param("tp") String type) {
// ...
return new Book();
}
restful参数
使用RoutingContext获取
Router.router().path("/{id}").handler(ctx -> {
String id = ctx.request().getPathVariable("id");
ctx.response().write(id);
});
使用注解获取
@Mapping(value = "/{id}", method = {HttpMethod.POST})
public void ajax(@PathParam("id") Long id) {
// ...
}
header参数
使用RoutingContext获取
Router.router().path("/").handler(ctx -> {
String id = ctx.request().getHeader("id");
ctx.response().write(id);
});
使用注解获取
@Mapping(value = "/", method = {HttpMethod.POST})
public void ajax(@HeaderParam("id") Long id) {
// ...
}
cookie参数
使用RoutingContext获取
Router.router().path("/").handler(ctx -> {
String id = ctx.request().getCookie("id");
ctx.response().write(id);
});
使用注解获取
@Mapping(value = "/", method = {HttpMethod.POST})
public void ajax(@CookieParam("id") Long id) {
// ...
}
参数转对象
实体类
@Data
public class Book {
private String name;
private String author;
}
使用RoutingContext转换
Router.router().path("/").handler(ctx -> {
// 表单或json请求参数绑定
Book book = ctx.bindParam(Book.class);
// cookie参数绑定
book = ctx.bindCookie(Book.class);
// header参数绑定
book = ctx.bindHeader(Book.class);
// restful参数绑定
book = ctx.bindPathVariables(Book.class);
});
使用注解获取
@Mapping(value = "/", method = {HttpMethod.POST})
public void ajax(@Param Book b1, @CookieParam Book b2, @HeaderParam Book b3, @PathParam Book b4) {
// ...
}
静态资源
内置默认将classpath下/public,/static作为静态资源目录,支持webjars,映射到/public
自定义静态资源可使用下面代码
Router.staticRoute().prefix("/lib").location("classpath:lib");
也可以通过配置文件指定
web.static.prefix=/public
web.static.path=/public,/static,classpath:/META-INF/resources/webjars
上传文件
使用RoutingContext获取
Router.router().path("/").handler(ctx -> {
MultipartItem file = ctx.request().getMultipartItem("file");
// ...
});
使用注解获取
@Mapping("/")
public void upload(MultipartItem image, @MultipartParam("file1") MultipartItem file) {
// 不使用注解则使用方法参数名作为请求参数名称
// 使用注解指定请求参数名称
}
结果渲染
渲染json
// 使用RoutingContext返回
Router.router().path("/").handler(ctx -> {
ctx.response().json(new Book("Java", "xxx"));
});
// 注解式
@Mapping("/")
public Book find() {
// 直接返回对象,框架默认处理成json
return new Book("Java", "xxx");
}
渲染文本
// 使用RoutingContext返回
Router.router().path("/").handler(ctx -> {
ctx.response().text("hello world");
});
渲染html
// 使用RoutingContext返回
Router.router().path("/").handler(ctx -> {
ctx.response().html("
hello world");
});
渲染模板
内置支持了jsp和thymeleaf模板,默认对应resources下的WEB-INF和templates目录
# 可通过下面配置进行更改模板目录
web.view.jsp.prefix=WEB-INF
web.view.thymeleaf.prefix=/templates
模板使用
// 使用RoutingContext
Router.router().path("/").handler(ctx -> {
ctx.response().template("index.html");
});
Router.router().path("/").handler(ctx -> {
Map attrs = new HashMap<>();
// ...
ctx.response().template("index.html", attrs);
});
// 注解式
@Mapping("/")
public Result index() {
return Result.view("index.html");
}
@Mapping("/")
public Result index() {
Map attrs = new HashMap<>();
// ...
return Result.view("index.html").addAttributes(attrs);
}
重定向
Router.router().path("/").handler(ctx -> {
ctx.response().redirect("https://github.com/justlive1");
});
@Mapping("/a")
public Result index() {
// 内部地址 相对于根目录: /b
// return Result.redirect("/b");
// 内部地址 相对于当前路径: /a/b
// return Result.redirect("b");
// 协议地址
return Result.redirect("https://github.com/justlive1");
}
写入cookie
@Mapping("/")
public void index(RoutingContext ctx) {
ctx.response().setCookie("hello", "world");
ctx.response().setCookie("java", "script", 100);
ctx.response().setCookie("uid", "xxx", ".justlive.vip", "/", 3600, true);
}
添加header
@Mapping("/")
public void index(RoutingContext ctx) {
ctx.response().setHeader("hello", "world");
}
写入session
@Mapping("/")
public void index(RoutingContext ctx) {
ctx.request().getSession().put("key", "value");
}
拦截器
WebHook是拦截器接口,可以实现执行前、执行后和结束拦截处理
@Slf4j
@Bean
public class LogWebHook implements WebHook {
@Override
public boolean before(RoutingContext ctx) {
log.info("before");
return true;
}
@Override
public void after(RoutingContext ctx) {
log.info("after");
}
@Override
public void finished(RoutingContext ctx) {
log.info("finished");
}
}
异常处理
框架默认提供了一个异常处理器,如需自定义处理异常,可以像下面这样使用
@Bean
public class CustomExceptionHandler extends ExceptionHandlerImpl {
@Override
public void handle(RoutingContext ctx, Exception e, int status) {
if (e instanceof CustomException) {
// do something
} else {
super.handle(ctx, e, status);
}
}
}
部署项目
修改端口
编码指定
Server.server().listen(8080);
配置文件
server.port=8081
启动命令
java -jar -Dserver.port=8090 app.jar
运行项目
使用内嵌容器启动
启动类
public class Application {
public static void main(String[] args) {
Server.server().listen();
}
}
通用打包方式
${mainClass}为上面的启动类
会生成lib目录存放依赖jar
org.apache.maven.plugins
maven-compiler-plugin
${maven.compiler.source}
${maven.compiler.target}
UTF-8
org.apache.maven.plugins
maven-jar-plugin
true
lib/
${mainClass}
org.apache.maven.plugins
maven-dependency-plugin
copy
package
copy-dependencies
${project.build.directory}/lib
打成fat-jar:
使用springboot打包插件
org.springframework.boot
spring-boot-maven-plugin
1.3.8.RELEASE
package
repackage
使用外部容器(jetty、tomcat等)
无需web.xml配置,打包成war放入容器即可,实现机制可查看WebContainerInitializer
false
外部化配置
框架可以通过使用配置文件进行修改默认属性
##### 基础配置
# 配置覆盖地址,用户外部配置覆盖项目配置 例 file:/config/*.properties,classpath*:/config/*.properties,xx.properties
config.override.path=
# 类扫描路径属性
main.class.scan=vip.justlive
# 临时文件根目录
main.temp.dir=.oxygen
# 缓存实现类,自定义缓存时使用
cache.impl.class=
##### web
# embedded 启动端口
server.port=8080
# context path
server.contextPath=
# session失效时间,单位秒
web.session.expired=3600
# 默认静态资源请求前缀
web.static.prefix=/public
# 默认静态资源目录
web.static.path=/public,/static,classpath:/META-INF/resources/webjars
# 静态资源缓存时间
web.static.cache=3600
# jsp路径前缀
web.view.jsp.prefix=WEB-INF
# thymeleaf 路径前缀
web.view.thymeleaf.prefix=/templates
# thymeleaf 视图后缀
web.view.thymeleaf.suffix=.html
# 内置简单视图处理 路径前缀
web.view.simple.prefix=/templates
# 内置简单视图处理 视图后缀
web.view.simple.suffix=.htm
# 是否开启模板缓存
web.view.cache.enabled=true
##### 定时任务job
# job线程名称格式
job.thread.name.format=jobs-%d
# job核心线程池大小
job.core.pool.size=10
##### i18n国际化
# i18n配置文件地址
i18n.path=classpath:message/*.properties
# i18n默认语言
i18n.default.language=zh
# i18n默认国家
i18n.default.country=CN
# i18n参数key
i18n.param.key=locale
# i18n Session key
i18n.session.key=I18N_SESSION_LOCALE
##### jetty
# 虚拟主机
server.jetty.virtualHosts=
# 连接器在空闲状态持续该时间后(单位毫秒)关闭
server.jetty.idleTimeout=30000
# 温和的停止一个连接器前等待的时间(毫秒)
server.jetty.stopTimeout=30000
# 等待处理的连接队列大小
server.jetty.acceptQueueSize=
# 允许Server socket被重绑定,即使在TIME_WAIT状态
server.jetty.reuseAddress=true
# 是否启用servlet3.0特性
server.jetty.configurationDiscovered=true
# 最大表单数据大小
server.jetty.maxFormContentSize=256 * 1024 * 1024
# 最大表单键值对数量
server.jetty.maxFormKeys=200
##### tomcat
# 最大请求队列数
server.tomcat.acceptCount=100
# 最大连接数
server.tomcat.maxConnections=5000
# 最大工作线程数
server.tomcat.maxThreads=200
# 最小线程数
server.tomcat.minSpareThreads=10
# 最大请求头数据大小
server.tomcat.maxHttpHeaderSize=8 * 1024
# 最大表单数据大小
server.tomcat.maxHttpPostSize=2 * 1024 * 1024
# 连接超时
server.tomcat.connectionTimeout=20000
# URI解码编码
server.tomcat.uriEncoding=utf-8
# 调用backgroundProcess延迟时间
server.tomcat.backgroundProcessorDelay=10
# 是否启用访问日志
server.tomcat.accessLogEnabled=false
# 访问日志是否开启缓冲
server.tomcat.accessLogBuffered=true
# 是否设置请求属性,ip、host、protocol、port
server.tomcat.accessLogRequestAttributesEnabled=false
# 每日日志格式
server.tomcat.accessLogFileFormat=.yyyy-MM-dd
# 日志格式
server.tomcat.accessLogPattern=common
##### undertow
# 主机名
server.undertow.host=0.0.0.0
# io线程数
server.undertow.ioThreads=
# worker线程数
server.undertow.workerThreads=
# 是否开启gzip压缩
server.undertow.gzipEnabled=false
# gzip处理优先级
server.undertow.gzipPriority=100
# 压缩级别,默认值 -1。 可配置 1 到 9。 1 拥有最快压缩速度,9 拥有最高压缩率
server.undertow.gzipLevel=-1
# 触发压缩的最小内容长度
server.undertow.gzipMinLength=1024
# url是否允许特殊字符
server.undertow.allowUnescapedCharactersInUrl=true
# 是否开启http2
server.undertow.http2enabled=false
联系信息
java 轻量级 job_oxygen: 一个轻量级Java框架,包含ioc、aop、config、cache、job、Jdbc、web等...相关推荐
- getconnection java_在MyEclipse用java写的一个GetConnection1.java,用于连接MySQL,却总是出错。(没有财富值了,见谅!)...
在MyEclipse用java写的一个GetConnection1.java,用于连接MySQL,却总是出错.求救!!!packageJavaBean1;importjava.sql.*;import ...
- java play_Play是一个全栈框架
背景 没有了Spring MVC,你就什么都不会了吗? no no no ! 作为一个工程师你必须了解更多,Play MVC就是是你必备的技能,Play framework非常强大堪比Spring f ...
- 邯郸 java高级_一个高级java工程师的进阶之路
1. JAVA.要想成为JAVA(高级)工程师肯定要学习JAVA.一般的程序员或许只需知道一些JAVA的语法结构就可以应付了.但要成为JAVA(高级) 工程师,您要对JAVA做比较深入的研究.您应该多 ...
- 计算机编程老鸟的心得,java入门123——一个老鸟java学习心得.docx
java入门123--一个老鸟的java学习心得 学习Java心得体会 学习了一学期的Java课程,觉得是该总结自己的心得体会了.开始学习任何一门课(包括java),兴趣最重要.一直觉得自己在学计算机 ...
- JAVA三维可视化组件:Matplot 3D for JAVA(V3.0) 一个纯JAVA开发的科学数据可视化组件包 类似 Python 的matplotlib(含示例代码)
目录 概述 组件下载及项目地址 效果展示和示例代码 概述 Matplot3D for JAVA(V3.0) 是一个基于JAVA SE 1.8环境开发的三维图形图表组件. 组件由纯JAVA SE 实现( ...
- Java 如何判断一个字符串中是否包含某一 子字符串
对于以上问题的解决,我一般使用String.indexOf("子串")的方式解决, 请看代码: public class IndexOfTest {public static v ...
- 使用java代码判断一个字符串里是否包含中文字符
测试代码: package unicode;import org.apache.commons.lang3.StringUtils;public class ChineseTest {public s ...
- java国际象棋_chess 一个用JAVA编写的国际象棋的程序 - 下载 - 搜珍网
一个java做的国际象棋小游戏/build/javaChess.jar 一个java做的国际象棋小游戏/docs/javadoc/allclasses-frame.html 一个java做的国际象棋小 ...
- java drawboard_学习一个月JAVA写的黑白棋程序(欢迎高手来指点)
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 public void clean(Graphics g) //清屏 { g.setColor(0xffffff); g.fillRect(0,0,180 ...
最新文章
- Nature Method :Rob Knight发布Striped UniFrac算法轻松分析微生物组大数据
- 13. python 类
- CentOS7 0安装Maven
- webService初探
- 小黑小波比.搭建个人网站
- 休眠锁定模式– OPTIMISTIC_FORCE_INCREMENT锁定模式如何工作
- String Start!
- 背后的故事之 - 快乐的Lambda表达式(二)
- Java开发者必备:超全的Java问题排查工具单
- linux服务器用户组和权限管,linux 用户管理,用户权限管理,用户组管理
- library的英语怎么读音_如何让你的英语口音无限接近母语者?英语语音语调的独家训练方法...
- TCPIP详解三次握手和四次挥手
- 网页版office服务器,Office 网页版服务说明
- 6.2 数据通路的建立
- 女程序员:秃头的富婆不好当
- (2)ARCH效应、均值方程、GARCH族模型、对波动率建模、预测(包含R语言代码)
- web页面实现拨打电话,发短信等功能
- 读书笔记--《原则》
- java面试-多线程常见面试题
- bk-02 C++ vector用法 博客园
热门文章
- 【秃头系列】-【本科生毕设论文格式Word】自动生成页面布局
- 如何免费获取县级气象数据?
- C3P0的使用 Spring配置数据库连接池
- python用来查看变量类型的函数是什么_python查看变量类型的函数
- 计算机文化基础008,2013 中国成人教育 翻转课堂在高校计算机文化基础课中的应用研究_刘桂花...
- 小程序推送服务通知(前后端代码)
- Linux比windows更适合工作和娱乐
- html5保护环境作品,保护环境的绘画作品图片
- 传奇自定义技能栏技术分享-GEE
- DM数据库开启归档模式的三种方式