2 Star 12 Fork 1

xiaoch0209 / wast

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
README
Apache-2.0

wast

简介

性能评测数据
https://github.com/wycst/wast-jmh-test

2022-09-25 json性能测试数据
https://github.com/wycst/wast-jmh-test/blob/main/README_0925_json.md

2022-12-14 表达式引擎测试数据
https://github.com/wycst/wast-jmh-test/blob/main/README_1214_EL.md

此库不依赖任何第三方库,对JDK版本要求1.6及以上即可。

Maven


<dependency>
    <groupId>io.github.wycst</groupId>
    <artifactId>wast</artifactId>
    <version>0.0.12.1</version>
</dependency>

JSON

1 java语言整体性能最快的json库之一;
2 功能全面,支持IO流文件读写,JSON节点树按需解析, 局部解析,序列化格式化,驼峰下划线自动转换;
3 源码实现简单易懂,阅读调试都很容易;
4 代码轻量,使用安全,没有漏洞风险;

YAML

1 目前java语言解析yaml最快的库,性能大概是snakeyaml的5-20倍;
2 支持文件流,URL, 字符数组,字符串等解析;
3 支持常用yaml语法以及类型转换;
4 内置Yaml节点模型,支持路径查找(v0.0.4+);
5 支持yaml反向转换为字符串或者文件(v0.0.4+);

表达式引擎

1 java表达式引擎,以解析性能来说比现有开源的其他引擎都快,包括mvel, spel, fel等;
2 支持java中所有的操作运算符(加减乘除余,位运算,逻辑运算,字符串+);
3 支持**指数运算(java本身不支持);
4 支持函数以及自定义函数实现,函数可以任意嵌套;
5 科学记数法支持,16进制,8进制等解析,支持大数运算(大数统一转为double类型);
6 支持简单的三目运算;
7 代码轻量,使用安全,没有漏洞风险;
8 支持超长文本表达式执行;
9 支持表达式编译模式运行;

JDBC

1 集成了类似JdbcTemplate,Mybatis-Plus或者JPA等操作习惯的api;
2 代码轻量,没有任何代理,使用非常方便;
3 支持面向原始sql,sql模版,对象管理等三种操作模式用,后两种模式完全能避免SQL注入漏洞(根源解决);
4 理论上支持所有提供JDBC协议的数据库;

HttpClient

1 当前只支持http/1.1;
2 底层核心为URLConnection,封装了http客户端常用的API
3 支持文件上传(已封装API),文件下载也能轻松处理支持;
4 支持nacos和consul作为ServerZone提供源,可以通过服务实例来访问请求;
5 支持负载均衡(客户端)和高可用访问调用;

JSON

. 常用对象json序列化

Map map = new HashMap();
map.put("msg", "hello, wastjson !");
String result = JSON.toJsonString(map);

. 对象序列化到文件

Map map = new HashMap();
map.put("msg", "hello, wastjson !");
JSON.writeJsonTo(map, new File("/tmp/test.json"));

. 格式序列化

Map map = new HashMap();
map.put("name", "zhangsan");
map.put("msg", "hello, wastjson !");
JSON.toJsonString(map, WriteOption.FormatOut);

output: 
{
	"msg":"hello, wastjson !",
	"name":"zhangsan"
}

. 反序列化

String json = "{\"msg\":\"hello, wastjson !\",\"name\":\"zhangsan\"}";
Map map = (Map) JSON.parse(json);
System.out.println(map);
// 输出
{msg=hello, wastjson !, name=zhangsan}

. 指定类型反序列化

    String json = "{\"msg\":\"hello, wastjson !\",\"name\":\"zhangsan\"}";
    Map map = JSON.parseObject(json, Map.class);
    System.out.println(map);
    // 输出
    {msg=hello, wastjson !, name=zhangsan}

.个性化支持

1.针对实体bean的属性可以添加注解@JsonSerialize和@JsonDeserialize来实现定制化(使用见test模块custom目录例子)。

2.通过JSON静态方法针对不同的类型来做个性化支持或者功能支持,非常方便;

    JSON.registerTypeMapper(java.time.ZoneId.class, new JSONTypeMapper<ZoneId>() {
        @Override
        public ZoneId read(Object any) {
            return any == null ? null : ZoneId.of((String) any);
        }

        @Override
        public void write(JSONWriter writer, ZoneId zoneId, JSONConfig jsonConfig, int indent) {
            try {
                writer.writeJSONString(zoneId == null ? "null" : zoneId.getId());
            } catch (IOException e) {
            }
        }
    });

. 基于输入流的读取解析

    Map result = null;
    
    // 1 url
    result = JSON.read(new URL("https://developer.aliyun.com/artifact/aliyunMaven/searchArtifactByGav?groupId=spring&artifactId=&version=&repoId=all&_input_charset=utf-8"), Map.class);
    
    // 2 stream
    InputStream inputStream = InputStreamTest.class.getResourceAsStream("/sample.json");
    result = JSON.read(inputStream, Map.class);
    
    // 3 file
    result = JSON.read(new File("/tmp/smaple.json"), Map.class);

. 基于输入流的按需解析

提供JSONReader类可按需解析一个输入流,自定义解析,可随时终止(不用将整个文件流读完)。

        final JSONReader reader = JSONReader.from(new File(f));
        reader.read(new JSONReader.ReaderCallback(JSONReader.ReadParseMode.ExternalImpl) {
            @Override
            public void parseValue(String key, Object value, Object host, int elementIndex, String path) throws Exception {
                super.parseValue(key, value, host, elementIndex, path);
                if(path.equals("/features/[100000]/properties/STREET")) {
                     // 终止读取;
                    abort();
                }
            }
        }, true);

. 强大的JSONNode功能

1、支持对大文本json的懒加载解析功能,即访问时解析,当需要读取一个大文本json中一个或多个属性值时非常有用。
2、支持按需解析;
3、支持上下文查找;
4、支持在大文本json中提取部分内容作为解析上下文结果,使用JSONNode.from(source, path, lazy?)
5、支持对节点的属性修改,删除等,节点的JSON反向序列化;
6、支持直接提取功能(v0.0.2+支持),参考JSONPath;

使用'/'作为路径的分隔符,数组下标使用[n]访问支持[], [n+], [n-],[n]等复合下标访问,例如/store/book/[]/author(注意不是/store/book[*]/author, 中括号[]可以省略)

  String json = "{\"name\": \"li lei\", \”properties\": {\"age\": 23}}";
  JSONNode node = JSONNode.parse(json);
  // 获取当前节点(根节点)的name属性
  String name = node.getChildValue("name", String.class);
  
  // 通过getPathValue方法可以获取任意路径上的值
  int age = node.getPathValue("/properties/age", int.class);
  
  // 通过path可以定位到任何路径节点
  JSONNode anyNode = JSONNode.get(path);
  
  // 通过root方法可以在任何节点回到根节点
  JSONNode root = anyNode.root();
  // root == node true
  
  // 根据路径局部解析
  JSONNode propertiesRoot = JSONNode.from(json, "/properties");
  // 局部解析懒加载(一般在获取某个数组的长度或者对象的keys等特别适用)
  JSONNode propertiesRoot = JSONNode.from(json, "/properties", true);
  propertiesRoot.keyNames();
  
  
  String json2 = `{
                      "store": {
                        "book": [
                          {
                            "category": "reference",
                            "author": "Nigel Rees",
                            "title": "Sayings of the Century",
                            "attr": {
                              "pos": "p1"
                            },
                            "price": 8.95
                          },
                          {
                            "category": "fiction",
                            "author": "Evelyn Waugh",
                            "title": "Sword of Honour",
                            "attr": {
                              "pos": "p2"
                            },
                            "price": 12.99
                          },
                          {
                            "category": "fiction",
                            "author": "Herman Melville",
                            "title": "Moby Dick",
                            "isbn": "0-553-21311-3",
                            "attr": {
                              "pos": "p3"
                            },
                            "price": 8.99
                          },
                          {
                            "category": "fiction",
                            "author": "J. R. R. Tolkien",
                            "title": "The Lord of the Rings",
                            "isbn": "0-395-19395-8",
                            "attr": {
                              "pos": "p4"
                            },
                            "price": 22.99
                          }
                        ],
                        "bicycle": {
                          "color": "red",
                          "price": 19.95
                        }
                      },
                      "expensive": 10
                    }`
;
  
  // 直接提取所有的author使用[*]
  List authors = JSONNode.extract(json2, "/store/book/[*]/author");
  
  // 提取第2本书的作者author使用指定的下标[n]
  String author = JSONNode.extract(json2, "/store/book/[1]/author").get(1);
  (或者 JSONNode.from(json2, "/store/book/[1]/author").getStringValue();性能大体一致)
  
  // 提取前2本书的作者使用下标[n-](包含n)
  List authors = JSONNode.extract(json2, "/store/book/[1-]/author").get(1);
  
  // 提取从第2本书开始后面所有的作者使用下标[n+](包含n)
  List authors = JSONNode.extract(json2, "/store/book/[1+]/author");
  
  

. SpringBoot(Spring MVC) 集成

supports/json-springmvc/JSONHttpMessageConverter.java

  @Configuration
  public class AppConfiguration implements WebMvcConfigurer {
 
       @Bean
       public HttpMessageConverters jsonHttpMessageConverters() {
           JSONHttpMessageConverter jsonHttpMessageConverter = new JSONHttpMessageConverter();
           jsonHttpMessageConverter.setWriteOptions(WriteOption... writeOptions);
           jsonHttpMessageConverter.setReadOptions(ReadOption... readOptions);
           return new HttpMessageConverters(jsonHttpMessageConverter);
       }
 
  }

10 序列化和反序列化支持配置

序列化配置枚举类:WriteOption

枚举值 说明
FormatOut 格式化缩进输出
FormatOutColonSpace 格式化缩进支持冒号后面补一个空格更加美观
FormatIndentUseTab 使用tab符来缩进美化,当FormatOut启用时默认开启使用此模式
FormatIndentUseSpace 使用空格符(4个空格)来缩进美化JSON
FormatIndentUseSpace8 使用8个空格符代表一个缩进级别进行美化JSON
FullProperty 输出完整的属性字段
WriteDateAsTime 默认将日期格式化输出,配置此项可以序列化为时间戳
SkipCircularReference 开始后探测序列化是否会存在循环引用造成的死循环
BytesArrayToHex 默认情况下byte数组会输出为base64字符串,开启配置后将bytes数组输出为16进制字符串
BytesArrayToNative 默认情况下byte数组会输出为base64字符串,开启配置后将bytes数组输出原生字节数组
SkipGetterOfNoneField 是否跳过不存在属性域的getter方法序列化
KeepOpenStream 序列化后不关闭流,默认自动关闭流,开启后不会调用close
AllowUnquotedMapKey 默认情况下map的key统一加双引号输出,开启后将根据实际的key值类型序列化
UseFields 默认通过实体类的getter方法序列化,开启后使用field字段进行序列化
WriteDecimalUseToString 默认浮点数的序列化使用科学计算法运算,启用配置可使用JDK内置的toString

反序列化配置枚举类:ReadOption

枚举值 说明
ByteArrayFromHexString 目标类型为byte[],解析到字符串标记时将按16进制字符串转化为byte[]数组(2个字符转化为一个字节)
AllowComment 非标准json特性:允许JSON存在注释,仅仅支持//和/+* *+/,默认关闭注释解析
AllowUnquotedFieldNames 非标准json特性:允许JSON字段的key没有双引号
AllowSingleQuotes 非标准json特性:允许JSON字段的key使用单引号,注意仅仅是key
UnknownEnumAsNull 不存在的枚举类型解析时默认抛出异常,开启后解析为null
UseDefaultFieldInstance 解析实体bean的场景下,如果其属性的类型为普通抽象类或者接口(Map和Collection极其子类接口除外),如果指定了默认实例将使用默认实例对象,从使用上解决类型映射问题,而不用趟AutoType带来的各种安全漏洞的坑
UseBigDecimalAsDefaultNumber 开启后在不确定number类型情况下,统一转化为BigDecimal;默认自动判断number类型转化为int或long或者double
UseJDKDoubleParser 默认的double解析模式通过科学计算法运算, 启用配置可使用JDK内置的API进行解析
AllowLastEndComma 支持对象或者数组最后一个属性或者元素后面存在逗号,比如[1,2,3,]开启后也能正常解析
UnMatchedEmptyAsNull 解析到空字符串但目标类型又不是字符串时,返回null,否则抛出异常

YAML

    
    // yaml string
    String yamlStr = StringUtils.fromResource("/yaml/t2.yaml");
    
    // read as doc
    YamlDocument yamlDoc = YamlDocument.parse(yamlStr);
    
    // as properties
    Properties properties = yamlDoc.toProperties();
    System.out.println(properties);
    
    // to map
    yamlDoc.toMap();
    
    // to bean
    YamlTest bean = yamlDoc.toEntity(YamlTest.class);
    
    // get root
    YamlNode yamlRoot = yamlDoc.getRoot();
    
    // find node
    YamlNode nameNode = yamlRoot.get("/metadata/name");
    
    // get /metadata/name
    String metadataName = yamlRoot.getPathValue("/metadata/name", String.class);
    // or nameNode.getValue();
    System.out.println(" metadataName " + metadataName);
    
    // update
    yamlRoot.setPathValue("/metadata/name", "this is new Value ");
    
    String newMetadataName = (String) nameNode.getValue();
    System.out.println(newMetadataName.equals("this is new Value "));
    
    // string
    System.out.println(yamlDoc.toYamlString());
    
    // file
    yamlDoc.writeTo(new File("/tmp/test.yaml"));
    

表达式引擎

1 直接运行模式

Expression.eval("1+1");  // 2
Expression.eval("1+1+'a'");  // 2a

Map map = new HashMap();
map.put("a", 1);
map.put("b", 2);
map.put("c", 3);
Expression.eval("a+b+c",map);  // 6

2 解析模式

将表达式解析为模型,一般使用在动态表达式场景

Map map = new HashMap();
map.put("a", 1);
map.put("b", 2);
map.put("c", 3);
Expression varExpr = Expression.parse("a + b + c"); 
varExpr.evaluate(map);     // 6

map.put("c", 30);
varExpr.evaluate(map);     // 33

3 编译模式

使用原生java编译或者javassist(按需加载)将表达式动态编译为java类进行运行。

String el = "arg.a+arg.b+b+c";
CompilerEnvironment compileEnvironment = new CompilerEnvironment();

// 如果设置false会将表达式进行先解析再编译;
// 如果设置为true将跳过解析在代码中直接return,此时最好使用setVariableType来声明变量类型
// 不伦是否设置skipParse,使用setVariableType来声明变量类型都是不错的选择,能大大提高效率
compileEnvironment.setSkipParse(true);
compileEnvironment.setVariableType(int.class, "arg.a", "arg.b", "b", "c");

// 输出编译的源代码
System.out.println(CompilerExpression.generateJavaCode(el, compileEnvironment));
CompilerExpression compiler = CompilerExpression.compile(el, compileEnvironment, CompilerExpression.Coder.Native);


Map aa = new HashMap();
aa.put("a", 120);
aa.put("b", 150);

Map var = new HashMap();
var.put("arg", aa);
var.put("b", 8);
var.put("c", 1);

// run
System.out.println("==== eval result " + compiler.evaluate(var));

4 函数和自定义函数使用

内置函数: max/min/sum/avg/abs/sqrt/lower/upper/size/ifNull
源码见: BuiltInFunction
自定义函数可以是全局函数不需要类名作为命名空间,使用@max直接调用,全局函数可以通过两种方式注册:

 // mode 1
 evaluateEnvironment.registerStaticMethods(true, Math.class, String.class);
 // mode 2
 evaluateEnvironment.registerFunction("min", new ExprFunction<Object, Number>() {
        @Override
        public Number call(Object... params) {
        Arrays.sort(params);
        return (Number) params[params.length - 1];
        }
});

也可以是命名空间函数,使用时需要添加类名简称(命名空间)如@Math.max(a,b) 函数使用@标记+函数名称

        Map context = new HashMap();
        context.put("tip", "1 ");
        context.put("name", "zhangsan, %s");
        context.put("msg", "hello");
        context.put("type", 1);
        context.put("a", 1);
        context.put("b", 12);
        context.put("c", 111);
        context.put("B6_AvgCpuUsed", 1.0);
        context.put("B5_AvgCpuUsed", 2.0);
        context.put("B4_AvgCpuUsed", 3.0);
        context.put("vars", new String[] {"hello"});
        
        EvaluateEnvironment evaluateEnvironment = EvaluateEnvironment.create(context);
        evaluateEnvironment.registerStaticMethods(Math.class, String.class);

        evaluateEnvironment.registerFunction("min", new ExprFunction<Object, Number>() {
            @Override
            public Number call(Object... params) {
                Arrays.sort(params);
                return (Number) params[params.length - 1];
            }
        });

        System.out.println( Expression.eval("@min(@sum(a,b,c), 50, 125, 2, -11)", evaluateEnvironment));
        System.out.println( Expression.eval("@max(@sum(a,b,c), 50, 125, 55, 152)", evaluateEnvironment));

JDBC

构建执行器

 DefaultSqlExecuter sqlExecuter = new DefaultSqlExecuter();

设置数据源

 sqlExecuter.setDataSource(datasource); // 

至此可以像JdbcTemplate一样操作数据库了

面向sql操作

以下是sqlExecuter常用的api:

// 查询列表(Map)
public List<Map> queryList(final String sql, final Object... params);

// 查询列表并将封装到指定类型(E)
public <E> List<E> queryList(final String sql, final Class<E> cls, final Object... params);

// 插入操作
public Serializable insert(final String sql, final boolean returnGeneratedKeys, final Object... params) ;

// 更新操作
public int update(final String sql, final Object... params);

// 执行一个sql语句(包括ddl)
public int executeUpdate(final String sql);

// 执行一个脚本(文件,以分号结尾换行的多条sql)
public void executeScript(InputStream is) throws IOException;

// 批量操作(使用同一个)
sqlExecuter.executePipelined(new SqlExecuteCall<Object>() {

    @Override
    public Object execute(Connection connection) throws SQLException {
        // 使用原生的jdbc语法操作
        // 连接在这里不用关闭
        return null;
    }
});

// 分页查询
public Page<Map> queryPage(final String sql, long pageNum, int limit, final Object... params);
// 分页查询转对象
public <E> Page<E> queryPage(final String sql, long pageNum, int limit, final Class<E> cls, final Object... params);
// 根据构造好的page进行分页查询
public <E> void queryPage(Page<E> page, final String sql, final Object... params);

面向模板操作

模板语法和mybatis相似,sql中使用#{}占位替换?,使用${}占位进行值拼接

比如:

select * from fact where type = #{type} and name like '%${name}%'

在运行时将转化为(假设name=test):

select * from fact where type = ? and name like '%test%'

通过sqlExecuter获取模板执行对象(注:sqlExecuter的大部分sql操作的api都有对应的模板api)

TemplateSqlExecuter templateSqlExecuter = sqlExecuter.getTemplateExecutor();

// 插入对象
Fact fact = new Fact();
fact.setId(1);
fact.setName("test");

// 插入
sqlExecuter.getTemplateExecutor().insert("insert into fact(id, name) values(#{id}, #{name})", fact);

// 查询
Fact f = sqlExecuter.getTemplateExecutor().queryObject("select * from fact where id = #{id}", 1, Fact.class);

面向对象操作

使用过jpa(hibernate)或者mybatis-plus的可以很快就上手。 使用前在前面初始化基础上需要设置实体的扫描包集合

 EntityManagementFactory.defaultManagementFactory().scanPackages("com.xxx.entitys", "com.xxx.entitys1");

实体不用继承任何类或实现接口;
主键通过注解@Id来标识,支持自增(数据库自增策略),算法生成(雪花算法)以及程序代码设置等几种策略;
其他字段通过注解@Column来映射字段名称,如果没有注解@Column,字段会默认将属性的驼峰格式转为下划线名称作为字段映射;

获取实体对象操作执行者

EntityExecuter entityExecuter = sqlExecuter.getEntityExecuter();

实体对象

@Table(name = "t_fact")
public class Fact {
    @Id
    private String id;
   
    @Column
    private String name;
    // setter getter 省略
}

常用的面向对象操作

Fact fact = new Fact();
fact.setId(1);
fact.setName("test");

// 插入对象
entityExecuter.insert(fact);

// 更新对象
entityExecuter.update(fact);

// 根据主键查询
Fact record = entityExecuter.get(Fact.class, 1);

// 根据主键删除
entityExecuter.delete(Fact.class, 1);

// 根据条件查询
Fact param = new Fact();
param.setId(1);
List<Fact> factList = entityExecuter.queryBy(Fact.class, param)

HttpClient

基本使用方法

HttpClient httpClient = HttpClient.create();

// 1 get 
httpClient.get("https://www.xxx.com", String.class)

// 2 上传 upload
HttpClientConfig httpClientConfig = new HttpClientConfig();
httpClientConfig.setMultipart(true);
httpClientConfig.addFileParameter("file", new File("/tmp/data.txt"), null);
httpClient.upload("https://localhost:8999/", httpClientConfig);

// 3 下载 download
HttpClientResponse clientResponse = client.get("http://devplatform-service/export/1");

// attachment;filename=FileName.txt 
String contentDisposition = clientResponse.getHeader("content-disposition");

// 如果知道文件名或者不关心可以跳过上面content-disposition的解析
String fileName = "FileName.txt";

// 文件内容(不适合文件超级大的场景下使用)
byte[] content = clientResponse.content();
FileOutputStream fos = new FileOutputStream(new File("/tmp/FileName.txt"));
fos.write(content);
fos.flush();
fos.close();

nacos集成案例

Properties properties = new Properties();
properties.put("cloud.nacos.server_addr", "192.168.1.140:8848");
properties.put("cloud.nacos.username", "nacos");
properties.put("cloud.nacos.password", "nacos");
properties.put("cloud.nacos.auth.enabled", "true");
properties.put("cloud.nacos.auth.tokenRefreshInterval", "3600");
properties.put("cloud.nacos.instance.namespaceId", "hlj-cloud-platform");
DefaultServiceProvider serviceProvider = new NacosServiceProvider(properties);
client.setServiceProvider(serviceProvider);
client.setEnableLoadBalance(true);

Thread.sleep(2000); 
// 此处devplatform-service为注册在nacos里面的服务名称,如果存在多个实例会进行负载处理
client.get("http://devplatform-service/dev-platform/");  

...

更多操作可以自行发现。

Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

简介

WAST是一个高性能Java工具集库包,包括JSON、YAML、CSV、HttpClient、JDBC和EL引擎 展开 收起
Java
Apache-2.0
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
Java
1
https://gitee.com/xiaoch0209/wast.git
git@gitee.com:xiaoch0209/wast.git
xiaoch0209
wast
wast
main

搜索帮助