转载请声明:http://blog.csdn.net/yoyo_newbie/article/details/51909533
经常做项目发现有种字符串格式需要解析---- "a=xxx;b=xxx;c=xxx;..." , 然而这种格式在网上并没有人写对应的框架工具去解析它并且去规范它。因此,菜鸡的我没办法去偷懒,所以只能去自己去写。我的封装原则就是一旦封装,用起来就得无脑且能偷懒则偷懒。
"a=xxx;b=xxx;c=xxx;..." 这个格式比较像url的拼接,所以本菜鸡取名叫Uson。。。呵呵勿喷。
需求1:
解析字符串“ name='猫';skill=\"抓老鼠\" ”,取出name, skill的值
那么我解析Uson过程如下。
首先根据预知这字符串字段有name, skill 都是String类型
因此定义一个类,类名随意,但成员名字得一样,可以有多余的:
public class Animal {
private String name;
private String skill;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSkill() {
return skill;
}
public void setSkill(String skill) {
this.skill = skill;
}
}
然后利用本菜鸡写的超轻量级Uson框架(下面会贴出源码),进行反序列化
public static void main(String[] values) {
parseAnimal("name='猫';skill=\"抓老鼠\"");
}
public static void parseAnimal(String animalUson)
{
Animal animal = Uson.getBean(animalUson, Animal.class);
System.out.println("动物名称:"+animal.getName());
System.out.println("特点:"+animal.getSkill());
}
运行结果:
动物名称:猫
特点:抓老鼠
----------------------------
是不是很爽?那么支持多类型吗?答案:肯定能写。
需求2:
解析字符串“name='Sam';age=999;qq=474850601;dddd=xxx”,获取出,name, age, qq的值
和上面例子一样,定义出一个实体,含有name, age, qq,的成员。
public class Person {
private long qq;
private String name;
private int age;
private String other;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public long getQq() {
return qq;
}
public void setQq(long qq) {
this.qq = qq;
}
public String getOther() {
return other;
}
public void setOther(String other) {
this.other = other;
}
}
开始写反序列化代码。biu ,biu ,biu ~
public static void main(String[] values) {
parsePerson("name='Sam';age=999;qq=474850601;dddd=xxx");
}
public static void parsePerson(String personUson) {
Person person = Uson.getBean(personUson, Person.class);
System.out.println("name:"+person.getName());
System.out.println("age:"+person.getAge());
System.out.println("qq:"+person.getQq());
System.out.println("other:"+person.getOther());
}
运行结果:
name:Sam
age:999
qq:474850601
other:null
由于字符串里面没有other所以为null,其中ddd不是需求中要获取的,可以不写。
如果这字符串是动态的怎么办?这情况可以转成Map
public static void main(String[] values) {
parsePerson("name='Sam';age=999;qq=474850601");
}
public static void parsePerson(String personUson) {
Map<String, String> map = Uson.toMap(personUson);
System.out.println("name:"+map.get("name"));
System.out.println("age:"+map.get("age"));
System.out.println("qq:"+map.get("qq"));
System.out.println("other:"+map.get("other"));
}
运行结果:
name:Sam
age:999
qq:474850601
other:null
这时候,突然他么后台有个傻逼,说他也要这个Uson格式字符串怎么办?
答案:放心,这东西本菜鸡都想好了。
需求3:
构造一段“name='Sam';age=999;qq=474850601”字符串
可以重用上面的Person类,用IsUsonParam注解标识那些要进行序列化的字段,这里是name, age, qq。
public class Person {
@IsUsonParam(true)
private long qq;
@IsUsonParam(true)
private String name;
@IsUsonParam(true)
private int age;
private String other;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public long getQq() {
return qq;
}
public void setQq(long qq) {
this.qq = qq;
}
public String getOther() {
return other;
}
public void setOther(String other) {
this.other = other;
}
}
public static void main(String[] values) {
Person person = new Person();
person.setAge(999);
person.setName("Sam");
person.setQq(474850601);
System.out.println("person's uson : ");
System.out.println(Uson.toUson(person));
}
结果如下:
person's uson :
qq=474850601;name='Sam';age=999
下面是框架源码,为了偷懒,赶紧贴。
package com.yoyonewbie;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
public final class Uson {
/**
* 根据 a=xxx;b=xxx;c=xxx;...格式转成Map
* @param uson
* @return
*/
public static Map<String, String> toMap(String uson) {
Map<String, String> params = new HashMap<String, String>();
uson = uson.replaceAll(" ", "").replaceAll("\r", "").replace("\n", "");
String[] resValues = uson.split(";");
for (int i = 0; i < resValues.length; i++) {
try {
String[] kv = resValues[i].split("=", 2);
String key = kv[0];
String val = kv[1].replaceAll("\"", "").replaceAll(";", "").replaceAll("'", "");
params.put(key, val);
} catch (ArrayIndexOutOfBoundsException e) {
}
}
return params;
}
/**
* 根据 a=xxx;b=xxx;c=xxx;...格式转成实体引用
* @param url “a=xxx;b=xxx;c=xxx;...” 格式字符串
* @param classType 有a,b,c...成员的Class
* @return
*/
public static <T> T getBean (String uson , Class<T> classType)
{
Object object = null;
try {
object = classType.newInstance();
} catch (InstantiationException | IllegalAccessException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if(null == object)
return null;
uson = uson.replaceAll(" ", "").replaceAll("\r", "").replace("\n", "");
String[] resValues = uson.split(";");
for (int i = 0; i < resValues.length; i++) {
try {
String[] kv = resValues[i].split("=", 2);
String key = kv[0];
String val = kv[1].replaceAll("\"", "").replaceAll(";", "").replaceAll("'", "");
Field field = classType.getDeclaredField(key);
if(null == field || null == val)
continue;
Class<?> fileType = field.getType();
field.setAccessible(true);
String temp = val.trim();
if(!temp.isEmpty() && (int.class.isAssignableFrom(fileType) || Integer.class.isAssignableFrom(fileType)))
{
field.set(object, Integer.parseInt(val));
}
else if (!temp.isEmpty() && (long.class.isAssignableFrom(fileType) || Long.class.isAssignableFrom(fileType)))
{
field.set(object, Long.parseLong(val));
}
else if (!temp.isEmpty() && (short.class.isAssignableFrom(fileType) || Short.class.isAssignableFrom(fileType)))
{
field.set(object, Short.parseShort(val));
}
else if (!temp.isEmpty() && (double.class.isAssignableFrom(fileType) || Double.class.isAssignableFrom(fileType)))
{
field.set(object, Double.parseDouble(val));
}
else if (!temp.isEmpty() && (float.class.isAssignableFrom(fileType) || Float.class.isAssignableFrom(fileType)))
{
field.set(object, Float.parseFloat(val));
}
else if (!temp.isEmpty() && (byte.class.isAssignableFrom(fileType) || Byte.class.isAssignableFrom(fileType)))
{
field.set(object, Byte.parseByte(val));
}
else if (!temp.isEmpty() && (char.class.isAssignableFrom(fileType) || Character.class.isAssignableFrom(fileType)))
{
field.set(object, val.charAt(0));
}
else if(String.class.isAssignableFrom(fileType))
{
field.set(object, val);
}
} catch (Exception ex)
{
}
}
return (T) object;
}
/**
* 将Object序列化成uson
* @param usonObj 需要序列化的object
* @return uson
*/
public static String toUson(Object usonObj)
{
if(null ==usonObj)
return "";
Class<?> classType = usonObj.getClass();
Field[] fields = classType.getDeclaredFields();
if(null == fields || fields.length < 1)
return "";
StringBuilder stringBuilder = new StringBuilder();
for(Field f : fields)
{
if(f.isAnnotationPresent(IsUsonParam.class))
{
f.setAccessible(true);
IsUsonParam isUsonParam = f.getAnnotation(IsUsonParam.class);
if(isUsonParam.value())
{
Object value=null;
try {
value = f.get(usonObj);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Class<?> fclass = f.getType();
if(null == value)
continue;
if( String.class.isAssignableFrom(fclass)||char.class.isAssignableFrom(fclass)||Character.class.isAssignableFrom(fclass))
{
stringBuilder.append(f.getName()+"='"+value+"';");
}
else
{
stringBuilder.append(f.getName()+"="+value+";");
}
}
}
}
int len = stringBuilder.length();
if(len>0)
stringBuilder.deleteCharAt(len-1);
return stringBuilder.toString();
}
}
package com.yoyonewbie;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface IsUsonParam {
boolean value();
}