Kat+ 一个轻量级的 KAT + XML + JSON 库
- 兼容 Kotlin
- 兼容 Android kitkat+
致力于安全性、规范性、拓展性和轻量性的微组件
Maven:
<dependency>
<groupId>plus.kat</groupId>
<artifactId>kat</artifactId>
<version>0.0.6-SNAPSHOT</version>
</dependency>Gradle:
dependencies {
implementation 'plus.kat:kat:0.0.6-SNAPSHOT'
}Kotlin Gradle:
dependencies {
implementation("plus.kat:kat:0.0.6-SNAPSHOT")
}Maven:
<dependency>
<groupId>plus.kat</groupId>
<artifactId>kat-netty</artifactId>
<version>0.0.6-SNAPSHOT</version>
</dependency>Java:
importplus.kat.*;
importplus.kat.netty.flow.*;
ByteBufbuf = ...
Flowflow = newByteBufFlow(buf);
Spare<User> spare = Spare.of(User.class);
Useruser = spare.read(flow); // see: 3.1Chanchan = spare.write(user);
ByteBufbuffer = ByteBufStream.of(chan);
chan.close();
// use buffer herebuffer.release(); // finally, call #releasetry(Chanchan = spare.write(user)) {
ByteBufbuffer = ByteBufStream.of(chan);
// use buffer herebuffer.release(); // finally, call #release
}
AsciiStringstr = ...
Flowflow = newAsciiStringFlow(str);
Flowflow = newAsciiStringFlow(str, index(), length());Maven:
<dependency>
<groupId>plus.kat</groupId>
<artifactId>kat-spring</artifactId>
<version>0.0.6-SNAPSHOT</version>
</dependency>Java:
importplus.kat.spring.http.*;
@ConfigurationpublicclassApplicationimplementsWebMvcConfigurer {
@OverridepublicvoidconfigureMessageConverters(
List<HttpMessageConverter<?>> converters
) {
// kat (if you need it)converters.add(
newMutableHttpMessageConverter("kat")
);
// xml (if you need it)converters.add(
newMutableHttpMessageConverter("xml")
);
// json (if you need it)converters.add(
0, newMutableHttpMessageConverter("json")
);
}
}Config:
<beans>
<mvc:annotation-driven>
<mvc:message-converters>
<!-- kat (if you need it) -->
<beanclass="plus.kat.spring.http.MutableHttpMessageConverter">
<constructor-argindex="0"value="kat"/>
</bean>
<!-- xml (if you need it) -->
<beanclass="plus.kat.spring.http.MutableHttpMessageConverter">
<constructor-argindex="0"value="xml"/>
</bean>
<!-- json (if you need it) -->
<beanclass="plus.kat.spring.http.MutableHttpMessageConverter">
<constructor-argindex="0"value="json"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
</beans>Maven:
<dependency>
<groupId>plus.kat</groupId>
<artifactId>kat-okhttp</artifactId>
<version>0.0.6</version>
</dependency>Maven:
<dependency>
<groupId>plus.kat</groupId>
<artifactId>kat-retrofit</artifactId>
<version>0.0.6</version>
</dependency>Java:
importplus.kat.*;
// katChankat = Kat.encode(obj);
Chankat = Kat.pretty(obj);
// xmlChanxml = Doc.encode(obj);
Chanxml = Doc.pretty(obj);
// jsonChanjson = Json.encode(obj);
Chanjson = Json.pretty(obj);Java:
importplus.kat.*;
// katHashMap<String, Object> data = Kat.decode(
HashMap.class, "{id=1,name=kraity}"
);
// xmlHashMap<String, Object> data = Doc.decode(
HashMap.class, "<user><id>1</id><name>kraity</name></user>"
);
// jsonHashMap<String, Object> data = Json.decode(
HashMap.class, "{\"id\":1,\"name\":\"kraity\"}"
);Java:
importplus.kat.*;
// katArrayList<Integer> data = Kat.decode(
ArrayList.class, "[1,2,3]"
);
// xmlArrayList<Integer> data = Doc.decode(
ArrayList.class, "<list><item>1</item><item>2</item></list>"
);
// jsonArrayList<Integer> data = Json.decode(
ArrayList.class, "[1,2,3]"
);Bean:
classUser {
privateintid;
privateStringname;
publicintgetId() {
returnid;
}
publicvoidsetId(intid) {
this.id = id;
}
publicStringgetName() {
returnname;
}
publicvoidsetName(Stringname) {
this.name = name;
}
}Java:
importplus.kat.*;
// katUseruser = Kat.decode(
User.class, "{id=1,name=kraity}"
);
// xmlUseruser = Doc.decode(
User.class, "<user><id>1</id><name>kraity</name></user>"
);
// jsonUseruser = Json.decode(
User.class, "{\"id\":1,\"name\":\"kraity\"}"
);Bean:
importplus.kat.actor.*;
@MagusinterfaceMeta {
intgetId();
StringgetTag();
}Java:
importplus.kat.*;
// katMetameta = Kat.decode(
Meta.class, "{id=1,tag=kat.plus}"
);
// xmlMetameta = Doc.decode(
Meta.class, "<meta><id>1</id><tag>kat.plus</tag></meta>"
);
// jsonMetameta = Json.decode(
Meta.class, "{\"id\":1,\"tag\":\"kat.plus\"}"
);Java:
importplus.kat.*;
// kattry (Katkat = newKat()) {
kat.set(null, it -> {
it.set("id", 100001);
it.set("title", "kat");
it.set("author", "User", user -> {
user.set("id", 1);
user.set("name", "kraity");
});
});
byte[] src = kat.toBinary();
Stringtext = kat.toString();
}
// xmltry (Docdoc = newDoc()) {
doit.set(null, it -> {
it.set("id", 100001);
it.set("title", "kat");
it.set("author", "User", user -> {
user.set("id", 1);
user.set("name", "kraity");
});
});
byte[] src = doc.toBinary();
Stringtext = doc.toString();
}
// jsontry (Jsonjson = newJson()) {
json.set(null, it -> {
it.set("id", 100001);
it.set("title", "kat");
it.set("author", "User", user -> {
user.set("id", 1);
user.set("name", "kraity");
});
});
byte[] src = json.toBinary();
Stringtext = json.toString();
}Kotlin:
importplus.kat.*// katval chan = kat {
it["id"] =100001
it["title"] ="kat"
it["meta"] = { meta ->
meta["view"] =99
}
it["author", "User"] = { user ->
user["id"] =1
user["name"] ="kraity"
}
}
chan.use {
val src = it.toBinary()
val text = it.toString()
}
// xmlval chan = doc {
it["id"] =100001
it["title"] ="kat"
it["meta"] = { meta ->
meta["view"] =99
}
it["author"] = { user ->
user["id"] =1
user["name"] ="kraity"
}
}
chan.use {
val src = it.toBinary()
val text = it.toString()
}
// jsonval chan = json {
it["id"] =100001
it["title"] ="kat"
it["meta"] = { meta ->
meta["view"] =99
}
it["author"] = { user ->
user["id"] =1
user["name"] ="kraity"
}
}
chan.use {
val src = it.toBinary()
val text = it.toString()
}Bean:
importplus.kat.actor.*;
@MagusclassUser {
@Magic("id")
privateintid;
@Magic("name")
privateStringname;
}Java:
importplus.kat.*;
// register UserSpare<User> spare = Spare.of(User.class);
// katUseruser = spare.read(
Flow.of(
"{id=1,name=kraity}"
)
);
Chankat = spare.write(user);
// xmlUseruser = spare.down(
Flow.of(
"<user><id>1</id><name>kraity</name></user>"
)
);
Chandoc = spare.mark(user);
// jsonUseruser = spare.parse(
Flow.of(
"{\"id\":1,\"name\":\"kraity\"}"
)
);
Chanjson = spare.serial(user);Bean:
importplus.kat.actor.*;
@MagusclassUser {
@Magic("id")
privateintid;
@Magic("name")
privateStringname;
}Use class type:
importplus.kat.spare.*;
// default supplierSuppliersupplier = Supplier.ins();
// katUseruser = supplier.read(
User.class, Flow.of(
"{id=1,name=kraity}"
);
);
// xmlUseruser = supplier.down(
User.class, Flow.of(
"<user><id>1</id><name>kraity</name></user>"
);
);
// jsonUseruser = supplier.parse(
User.class, Flow.of(
"{\"id\":1,\"name\":\"kraity\"}"
);
);Register custom Spare:
importplus.kat.spare.*;
// your SupplierSuppliersupplier = ...;
// register Spare of User// see: 4.4 Use custom Sparesupplier.active(
User.class, newUserSpare()
);Removes Spare of specified Class
importplus.kat.spare.*;
// your SupplierSuppliersupplier = ...;
// class typesupplier.revoke(User.class);
// class type and sparesupplier.revoke(User.class, getSpare());Bean:
importplus.kat.actor.*;
importplus.kat.spare.*;
@MagusclassUser {
@Magic("id")
privateintid;
@Magic("name")
privateStringname;
@Magic(value = "status", agent = StatusCoder.class)
privateStringstatus;
}Java:
importplus.kat.*;
importplus.kat.chan.*;
importplus.kat.spare.*;
classStatusCoderimplementsCoder<String> {
@OverridepublicStringread(
Flagflag,
Valuevalue
) throwsIOException {
if (value.equals("PUBLISH")) {
return"open";
}
if (value.equals("PRIVATE")) {
return"self";
}
return"unknown";
}
@Overridepublicvoidwrite(
Fluxflux,
Objectvalue
) throwsIOException {
switch ((String) value) {
case"open": {
flux.emit("PUBLISH");
break;
}
case"self": {
flux.emit("PRIVATE");
break;
}
default: {
flux.emit("UNKNOWN");
}
}
}
}Bean:
importplus.kat.actor.*;
// POJOclassUser {
privateintid;
privateStringname;
privatebooleanblocked;
privateUsercollaborator;
}
@MagusclassNote {
@Magic("id")
privateintid;
@Magic(value = "author", agent = AuthorCoder.class)
privateUserauthor;
}Java:
importplus.kat.*;
importplus.kat.chain.*;
importplus.kat.spare.*;
importjava.io.IOException;
classAuthorCoderimplementsCoder<User> {
@OverridepublicBooleangetScope() {
returntrue;
}
@OverridepublicBordergetBorder() {
returnBorder.BRACE;
}
@Overridepublicvoidwrite(
Chanchan,
Objectvalue
) throwsIOException {
Useruser = (User) value;
chan.set("id", user.getId());
chan.set("name", user.getName());
chan.set("blocked", user.isBlocked());
}
@OverridepublicFactorygetFactory(Typetype) {
returnnewAuthorBuilder();
}
}
classAuthorBuilderextendsBuilder<User> {
privateUseruser;
@OverridepublicvoidonCreate()
throwsIOException {
user = newUser();
}
@OverridepublicSpideronOpen(
Aliasalias,
Spacespace
) throwsIOException {
// check keyif (alias.equals("collaborator")) {
// by builderBuilder<?> member =
newAuthorBuilder();
returnmember.attach(this);
}
thrownewIOException(
"Unknown attribute: " + alias
);
}
@OverridepublicvoidonNext(
Objectvalue
) throwsIOException {
user.setCollaborator(
(User) value
);
}
@OverridepublicvoidonNext(
Aliasalias,
Spacespace,
Valuevalue
) throwsIOException {
if (alias.equals("id")) {
user.setId(
value.toInt()
);
} elseif (alias.equals("name")) {
user.setName(
value.toString()
);
} elseif (alias.equals("blocked")) {
user.setBlocked(
value.toBoolean()
);
} else {
thrownewIOException(
"Unknown attribute: " + alias
);
}
}
@OverridepublicUserbuild() {
returnuser;
}
@OverridepublicvoidonDestroy()
throwsIOException {
user = null;
}
}Bean:
importplus.kat.actor.*;
@Magus(agent = UserSpare.class)
classUser {
privateintid;
privateStringname;
}Java:
importplus.kat.*;
classUserSpareimplementsSpare<User> {
@OverridepublicStringgetSpace() {
return"plus.kat.User";
}
@OverridepublicBooleangetScope() {
returntrue;
}
@OverridepublicBooleangetBorder(
Flagflag
) {
returnBorder.BRACE;
}
@OverridepublicClass<User> getType() {
returnUser.class;
}
@Overridepublicvoidwrite(
Chanchan,
Objectvalue
) throwsIOException {
// see: 4.3 Use custom Coder
}
@OverridepublicFactorygetFactory(Typetype) {
// see: 4.3 Use custom BuilderreturnnewUserBuilder();
}
}Released under the Apache 2.0 license
Copyright 2022 Kat+ Team
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.