七、转换器(Converter)

我们程序中的POJO是千变万化的,而且需求也是千奇百怪的,所以XStream中的内置的转换器的功能不一定能够满足我们的要求,所以我们就需要自己构建转换器。

1,一个基本的转换器

有如下代码:

  1. import com.thoughtworks.xstream.XStream;
  2. import com.thoughtworks.xstream.io.xml.DomDriver;
  3. public class XStreamTest4 {
  4. public static void main(String[] args) {
  5. Person person = new Person();
  6. person.setName("张三");
  7. XStream xstream = new XStream(new DomDriver());
  8. xstream.alias("person", Person.class);
  9. System.out.println(xstream.toXML(person));
  10. }
  11. }
  12. class Person {
  13. private String name;
  14. public String getName() {
  15. return name;
  16. }
  17. public void setName(String name) {
  18. this.name = name;
  19. }
  20. public String toString() {
  21. return getName();
  22. }
  23. }

运行结果是:

  1. <person>
  2. <name>张三</name>
  3. </person>

如果我们需要输出如下信息:

  1. <person>
  2. <fullname>张三</fullname>
  3. </person>

该怎么办?

当然,我们可以使用XStream默认的转换器

  1. xstream.aliasField("fullname", Person.class,"name");

,甚至我们可以直接使用注解@XStreamAlias。但是这不是我们要介绍的,我们需要创建自己的转换器PersonConverter。

PersonConverter需要有3个功能:

a)告诉XStream对象,它能够转换Person类的对象(canConvert方法)

b)能够将Person对象转换为XML(marshal方法)

c)能够将XML转换成为Person对象(unmarshal方法)

现在,我们实现第一个功能(canConvert方法):

  1. //告诉XStream对象,它能够转换Person类的对象
  2. public boolean canConvert(Class clazz) {
  3. return clazz.equals(Person.class);
  4. }

就这么简单!

然后,我们实现第二个功能(marshal方法):

  1. //能够将Person对象转换为XML
  2. public void marshal(
  3. Object value,            //我们将要转换的对象,这里是Person对象
  4. HierarchicalStreamWriter writer,//用于输出XML结果的writer
  5. MarshallingContext context     //序列化环境上下文
  6. ) {
  7. //写入顺序
  8. //1,强制转换为我们我们需要的类型
  9. Person person = (Person) value;
  10. //2,开始写入fullname节点,相当于写入<fullname>
  11. writer.startNode("fullname");
  12. //3,给fullname节点赋值
  13. writer.setValue(person.getName());
  14. //4,结束fullname节点,相当于写入</fullname>
  15. writer.endNode();
  16. //    //如果你愿意,顺便也可以写一点其他的东西
  17. //    writer.startNode("otherContent");
  18. //    writer.setValue("这是一大串其他内容,你可以根据自己的需要写内容!");
  19. //    writer.endNode();
  20. }

最后,我们实现第三个功能(unmarshal方法):

  1. //能够将XML转换成为Person对象
  2. public Object unmarshal(
  3. HierarchicalStreamReader reader,//用于读取XML的reader
  4. UnmarshallingContext context   //反序列化环境上下文
  5. ) {
  6. //1,先创建一个Person对象
  7. Person person = new Person();
  8. //2,判断<person>节点下还有没有其他可以读取的节点
  9. while(reader.hasMoreChildren()){
  10. //3,开始读取下一个(也可能是第一个)节点,选择当前<person>节点的子节点作为当前节点
  11. reader.moveDown();
  12. //4,获取当前节点的值
  13. String value = reader.getValue();
  14. if("fullname".equals(reader.getNodeName())){
  15. person.setName(value);
  16. }
  17. //输出当前节点的内容
  18. System.out.println("node="+reader.getNodeName()+";value="+value);
  19. //5,返回上一层节点<person>
  20. reader.moveUp();
  21. }
  22. return person;
  23. }

于是我们的PersonConverter就是:

  1. package cn.tjpu.zhw.xml.xstream4;
  2. import com.thoughtworks.xstream.converters.Converter;
  3. import com.thoughtworks.xstream.converters.MarshallingContext;
  4. import com.thoughtworks.xstream.converters.UnmarshallingContext;
  5. import com.thoughtworks.xstream.io.HierarchicalStreamReader;
  6. import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
  7. public class PersonConverter implements Converter {
  8. //告诉XStream对象,它能够转换Person类的对象
  9. public boolean canConvert(Class clazz) {
  10. return clazz.equals(Person.class);
  11. }
  12. //能够将Person对象转换为XML
  13. public void marshal(
  14. Object value,            //我们将要转换的对象,这里是Person对象
  15. HierarchicalStreamWriter writer,//用于输出XML结果的writer
  16. MarshallingContext context     //序列化环境上下文
  17. ) {
  18. //写入顺序
  19. //1,强制转换为我们我们需要的类型
  20. Person person = (Person) value;
  21. //2,开始写入fullname节点,相当于写入<fullname>
  22. writer.startNode("fullname");
  23. //3,给fullname节点赋值
  24. writer.setValue(person.getName());
  25. //4,结束fullname节点,相当于写入</fullname>
  26. writer.endNode();
  27. //    //如果你愿意,顺便也可以写一点其他的东西
  28. //    writer.startNode("otherContent");
  29. //    writer.setValue("这是一大串其他内容,你可以根据自己的需要写内容!");
  30. //    writer.endNode();
  31. }
  32. //能够将XML转换成为Person对象
  33. public Object unmarshal(
  34. HierarchicalStreamReader reader,//用于读取XML的reader
  35. UnmarshallingContext context   //反序列化环境上下文
  36. ) {
  37. //1,先创建一个Person对象
  38. Person person = new Person();
  39. //2,判断<person>节点下还有没有其他可以读取的节点
  40. while(reader.hasMoreChildren()){
  41. //3,开始读取下一个(也可能是第一个)节点,选择当前<person>节点的子节点作为当前节点
  42. reader.moveDown();
  43. //4,获取当前节点的值
  44. String value = reader.getValue();
  45. if("fullname".equals(reader.getNodeName())){
  46. person.setName(value);
  47. }
  48. //输出当前节点的内容
  49. System.out.println("node="+reader.getNodeName()+";value="+value);
  50. //5,返回上一层节点<person>
  51. reader.moveUp();
  52. }
  53. return person;
  54. }
  55. }

同时我们修改main方法文件:

  1. package cn.tjpu.zhw.xml.xstream4;
  2. import com.thoughtworks.xstream.XStream;
  3. import com.thoughtworks.xstream.io.xml.DomDriver;
  4. public class XStreamTest4 {
  5. public static void main(String[] args) {
  6. //创建Person对象
  7. Person person = new Person();
  8. person.setName("张三");
  9. //创建XStream对象
  10. XStream xstream = new XStream(new DomDriver());
  11. xstream.alias("person", Person.class);
  12. //注册PersonConverter转换器
  13. xstream.registerConverter(new PersonConverter());
  14. //使用marshal方法,将Person对象转换成为XML
  15. System.out.println("****使用marshal方法,将Person对象转换成为XML==>");
  16. String xml = xstream.toXML(person);
  17. System.out.println(xml);
  18. //使用unmarshal方法,将XML转换成为Person对象
  19. System.out.println();
  20. System.out.println("****使用unmarshal方法,将XML转换成为Person对象==>");
  21. Person p = (Person)xstream.fromXML(xml);
  22. //输出Person对象
  23. System.out.println();
  24. System.out.println("****输出Person对象==>");
  25. System.out.println(p);
  26. }
  27. }
  28. class Person {
  29. private String name;
  30. public String getName() {
  31. return name;
  32. }
  33. public void setName(String name) {
  34. this.name = name;
  35. }
  36. public String toString() {
  37. return "Person对象的name="+getName();
  38. }
  39. }

运行结果如下:

  1. ****使用marshal方法,将Person对象转换成为XML==>
  2. <person>
  3. <fullname>张三</fullname>
  4. </person>
  5. ****使用unmarshal方法,将XML转换成为Person对象==>
  6. node=fullname;value=张三
  7. ****输出Person对象==>
  8. Person对象的name=张三

我们成功了!!!!!!

2,另一个简单的转换器

现在我们需要程序输出如下:

<person>张三</person>

该咋办?

我们再创建一个转换器:

  1. package cn.tjpu.zhw.xml.xstream4;
  2. import com.thoughtworks.xstream.converters.basic.AbstractSingleValueConverter;
  3. public class AnotherPersonConverter extends AbstractSingleValueConverter {
  4. // 告诉XStream对象,它能够转换Person类的对象
  5. public boolean canConvert(Class clazz) {
  6. return clazz.equals(Person.class);
  7. }
  8. // 将Person对象转换为XML,参数obj就是要转换的Person对象,返回值就是<person>节点的值
  9. public String toString(Object obj) {
  10. Person p = (Person) obj;
  11. return p.getName();
  12. }
  13. // 将XML转换成为Person对象,参数str就是<person>节点的值,返回值就是转换得到的Person对象
  14. public Object fromString(String str) {
  15. Person person = new Person();
  16. person.setName(str);
  17. System.out.println("参数str="+str);
  18. return person;
  19. }
  20. }

修改Main方法:

  1. public class XStreamTest4 {
  2. public static void main(String[] args) {
  3. //创建Person对象
  4. Person person = new Person();
  5. person.setName("张三");
  6. //创建XStream对象
  7. XStream xstream = new XStream(new DomDriver());
  8. xstream.alias("person", Person.class);
  9. //    //注册PersonConverter转换器
  10. //    xstream.registerConverter(new PersonConverter());
  11. //注册AnotherPersonConverter转换器
  12. xstream.registerConverter(new AnotherPersonConverter());
  13. //使用toString方法,将Person对象转换成为XML
  14. System.out.println("****使用toString方法,将Person对象转换成为XML==>");
  15. String xml = xstream.toXML(person);
  16. System.out.println(xml);
  17. //使用fromString方法,将XML转换成为Person对象
  18. System.out.println();
  19. System.out.println("****使用fromString方法,将XML转换成为Person对象==>");
  20. Person p = (Person)xstream.fromXML(xml);
  21. //输出Person对象
  22. System.out.println();
  23. System.out.println("****输出Person对象==>");
  24. System.out.println(p);
  25. }
  26. }

运行结果:

  1. ****使用toString方法,将Person对象转换成为XML==>
  2. <person>张三</person>
  3. ****使用fromString方法,将XML转换成为Person对象==>
  4. 参数str=张三
  5. ****输出Person对象==>
  6. Person对象的name=张三

这正是我们预期的结果!!!

3,时间转换器

通过上面两个例子我们知道了Converter接口的简单工作方式,现在我们创建一个新的时间转换器DateConverter,这个时间转换器将以Local对象作为构造方法的参数。

这个时间转换器同样有类似PersonConverter转换器的功能:

a)告诉XStream对象,它能够转换Calendar类的对象(canConvert方法)

b)能够将Calendar对象转换为XML(marshal方法)

c)能够将XML转换成为Calendar对象(unmarshal方法)

现在实现第一个功能:

  1. // 告诉XStream对象,它能够转换Calendar类及其所有子类定义的对象
  2. public boolean canConvert(Class clazz) {
  3. return Calendar.class.isAssignableFrom(clazz);
  4. }

然后,实现第二个功能:

  1. // 能够将Calendar对象转换为XML
  2. public void marshal(Object value, HierarchicalStreamWriter writer,
  3. MarshallingContext context) {
  4. //value是将要转换的Calendar对象
  5. Calendar calendar = (Calendar) value;
  6. Date date = calendar.getTime();
  7. //设定格式化格式
  8. DateFormat formatter = DateFormat.getDateInstance(DateFormat.FULL,
  9. this.locale);
  10. //格式化并输出Calendar对象
  11. writer.setValue(formatter.format(date));
  12. }

最后,实现最后一个功能:

  1. // 能够将XML转换成为Calendar对象
  2. public Object unmarshal(HierarchicalStreamReader reader,
  3. UnmarshallingContext context) {
  4. //创建一个Calendar对象
  5. GregorianCalendar calendar = new GregorianCalendar();
  6. //设定解析格式
  7. DateFormat formatter = DateFormat.getDateInstance(DateFormat.FULL,
  8. this.locale);
  9. try {
  10. //解析指定格式的Calendar对象
  11. calendar.setTime(formatter.parse(reader.getValue()));
  12. } catch (ParseException e) {
  13. throw new ConversionException(e.getMessage(), e);
  14. }
  15. //返回解析成功的Calendar对象
  16. return calendar;
  17. }

于是,我们的DateConverter定义如下:

  1. package cn.tjpu.zhw.xml.xstream4;
  2. import java.text.DateFormat;
  3. import java.text.ParseException;
  4. import java.util.Calendar;
  5. import java.util.Date;
  6. import java.util.GregorianCalendar;
  7. import java.util.Locale;
  8. import com.thoughtworks.xstream.converters.ConversionException;
  9. import com.thoughtworks.xstream.converters.Converter;
  10. import com.thoughtworks.xstream.converters.MarshallingContext;
  11. import com.thoughtworks.xstream.converters.UnmarshallingContext;
  12. import com.thoughtworks.xstream.io.HierarchicalStreamReader;
  13. import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
  14. public class DateConverter implements Converter {
  15. private Locale locale;
  16. public DateConverter(Locale locale) {
  17. super();
  18. this.locale = locale;
  19. }
  20. // 告诉XStream对象,它能够转换Calendar类及其所有子类定义的对象
  21. public boolean canConvert(Class clazz) {
  22. return Calendar.class.isAssignableFrom(clazz);
  23. }
  24. // 能够将Calendar对象转换为XML
  25. public void marshal(Object value, HierarchicalStreamWriter writer,
  26. MarshallingContext context) {
  27. //value是将要转换的Calendar对象
  28. Calendar calendar = (Calendar) value;
  29. Date date = calendar.getTime();
  30. //设定格式化格式
  31. DateFormat formatter = DateFormat.getDateInstance(DateFormat.FULL,
  32. this.locale);
  33. //格式化并输出Calendar对象
  34. writer.setValue(formatter.format(date));
  35. }
  36. // 能够将XML转换成为Calendar对象
  37. public Object unmarshal(HierarchicalStreamReader reader,
  38. UnmarshallingContext context) {
  39. //创建一个Calendar对象
  40. GregorianCalendar calendar = new GregorianCalendar();
  41. //设定解析格式
  42. DateFormat formatter = DateFormat.getDateInstance(DateFormat.FULL,
  43. this.locale);
  44. try {
  45. //解析指定格式的Calendar对象
  46. calendar.setTime(formatter.parse(reader.getValue()));
  47. } catch (ParseException e) {
  48. throw new ConversionException(e.getMessage(), e);
  49. }
  50. //返回解析成功的Calendar对象
  51. return calendar;
  52. }
  53. }

再写我们的main方法:

  1. package cn.tjpu.zhw.xml.xstream4;
  2. import java.text.DateFormat;
  3. import java.util.Calendar;
  4. import java.util.GregorianCalendar;
  5. import java.util.Locale;
  6. import com.thoughtworks.xstream.XStream;
  7. import com.thoughtworks.xstream.io.xml.DomDriver;
  8. public class DateMain {
  9. public static void main(String[] args) {
  10. // 获取当前时间
  11. Calendar calendar = new GregorianCalendar();
  12. // 创建XStream对象
  13. XStream xstream = new XStream(new DomDriver());
  14. xstream.alias("date", Calendar.class);
  15. // 注册我们定义的时间转换器
  16. xstream.registerConverter(new DateConverter(new Locale("zh", "cn")));
  17. // 转换并输出XML
  18. String xml = xstream.toXML(calendar);
  19. System.out.println(xstream.toXML(calendar));
  20. // 加载XML中的时间数据
  21. Calendar loaded = (Calendar) xstream.fromXML(xml);
  22. //格式化并输出时间
  23. System.out.println(DateFormat.getDateInstance(DateFormat.MEDIUM).format(
  24. loaded.getTime()));
  25. }
  26. }

运行,结果如下:

  1. <date>2013年12月24日 星期二</date>
  2. 2013-12-24

4,更加复杂的转换器

复杂的转换器都是由一系列基本的转换器组成的,我们只需要将这些基本的转换器按照适当的顺序排列组合就行了。

下面有一个复杂的Birthday类:

  1. package cn.tjpu.zhw.xml.xstream4;
  2. import java.util.Calendar;
  3. public class Birthday {
  4. private Person person;
  5. private Calendar date;
  6. private char gender;
  7. public Person getPerson() {
  8. return person;
  9. }
  10. public void setPerson(Person person) {
  11. this.person = person;
  12. }
  13. public Calendar getDate() {
  14. return date;
  15. }
  16. public void setDate(Calendar date) {
  17. this.date = date;
  18. }
  19. public char getGender() {
  20. return gender;
  21. }
  22. public void setGenderMale() {
  23. this.gender = 'm';
  24. }
  25. public void setGenderFemale() {
  26. this.gender = 'f';
  27. }
  28. public String toString(){
  29. return "{person="+person+"};{date="+date.getTime()+"};{gender="+gender+"}";
  30. }
  31. }

我们将怎样转换这个类呢?

答案是,我们只需要将现有的转换器组合成一个BirthdayConverter转换器就成了!

  1. package cn.tjpu.zhw.xml.xstream4;
  2. import java.util.Calendar;
  3. import com.thoughtworks.xstream.converters.ConversionException;
  4. import com.thoughtworks.xstream.converters.Converter;
  5. import com.thoughtworks.xstream.converters.MarshallingContext;
  6. import com.thoughtworks.xstream.converters.UnmarshallingContext;
  7. import com.thoughtworks.xstream.io.HierarchicalStreamReader;
  8. import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
  9. public class BirthdayConverter implements Converter {
  10. // 告诉XStream对象,它能够转换Birthday类的对象
  11. public boolean canConvert(Class clazz) {
  12. return Birthday.class == clazz;
  13. }
  14. // 能够将Birthday对象转换为XML
  15. public void marshal(Object value, HierarchicalStreamWriter writer,
  16. MarshallingContext context) {
  17. //value是将要被转换的Birthday对象
  18. Birthday birthday = (Birthday) value;
  19. //给<birthday>节点添加gender属性
  20. if (birthday.getGender() != '\0') {
  21. writer.addAttribute("gender",
  22. Character.toString(birthday.getGender()));
  23. }
  24. //给<birthday>节点添加子节点<person>
  25. if (birthday.getPerson() != null) {
  26. writer.startNode("person");
  27. context.convertAnother(birthday.getPerson());
  28. writer.endNode();
  29. }
  30. //给<birthday>节点添加子节点<birth>
  31. if (birthday.getDate() != null) {
  32. writer.startNode("birth");
  33. context.convertAnother(birthday.getDate());
  34. writer.endNode();
  35. }
  36. }
  37. // 能够将XML转换成为Birthday对象
  38. public Object unmarshal(HierarchicalStreamReader reader,
  39. UnmarshallingContext context) {
  40. //创建Birthday对象
  41. Birthday birthday = new Birthday();
  42. //当前节点是<birthday>
  43. //解析<birthday>节点的gender属性
  44. String gender = reader.getAttribute("gender");
  45. if (gender != null) {
  46. if (gender.length() > 0) {
  47. if (gender.charAt(0) == 'f') {
  48. birthday.setGenderFemale();
  49. } else if (gender.charAt(0) == 'm') {
  50. birthday.setGenderMale();
  51. } else {
  52. throw new ConversionException("Invalid gender value: "
  53. + gender);
  54. }
  55. } else {
  56. throw new ConversionException(
  57. "Empty string is invalid gender value");
  58. }
  59. }
  60. //遍历解析<birthday>节点的所有子节点
  61. while (reader.hasMoreChildren()) {
  62. //将下一个(也可能是第一个)子节点作为当前节点
  63. reader.moveDown();
  64. //解析<person>节点
  65. if ("person".equals(reader.getNodeName())) {
  66. Person person = (Person) context.convertAnother(birthday,
  67. Person.class);
  68. birthday.setPerson(person);
  69. }
  70. //解析<birth>节点
  71. else if ("birth".equals(reader.getNodeName())) {
  72. Calendar date = (Calendar) context.convertAnother(birthday,
  73. Calendar.class);
  74. birthday.setDate(date);
  75. }
  76. //返回到<birthday>节点作为当前节点
  77. reader.moveUp();
  78. }
  79. //返回解析得到的Birthday对象
  80. return birthday;
  81. }
  82. }

下面写main方法:

  1. package cn.tjpu.zhw.xml.xstream4;
  2. import java.util.GregorianCalendar;
  3. import com.thoughtworks.xstream.XStream;
  4. public class BirthdayMain {
  5. public static void main(String[] args) {
  6. //创建Birthday对象
  7. Birthday birthday = new Birthday();
  8. Person p = new Person();
  9. p.setName("张三");
  10. birthday.setPerson(p);
  11. birthday.setDate(new GregorianCalendar());
  12. birthday.setGenderMale();
  13. //创建XStream对象
  14. XStream xstream = new XStream();
  15. xstream.alias("birthday", Birthday.class);
  16. //注册BirthdayConverter转换器
  17. xstream.registerConverter(new BirthdayConverter());
  18. //将Birthday对象转换成为XML并输出
  19. String xml = xstream.toXML(birthday);
  20. System.out.println("**************将Birthday对象转换成为XML并输出**************");
  21. System.out.println(xml);
  22. //将XML转换成为Birthday对象
  23. Birthday b = (Birthday)xstream.fromXML(xml);
  24. //输出Birthday对象
  25. System.out.println();
  26. System.out.println("**************将XML转换成为Birthday对象**************");
  27. System.out.println(b);
  28. }
  29. }

运行结果:

  1. **************将Birthday对象转换成为XML并输出**************
  2. <birthday gender="m">
  3. <person>
  4. <name>张三</name>
  5. </person>
  6. <birth>
  7. <time>1387897906531</time>
  8. <timezone>Asia/Shanghai</timezone>
  9. </birth>
  10. </birthday>
  11. **************将XML转换成为Birthday对象**************
  12. {person=Person对象的name=张三};{date=Tue Dec 24 23:11:46 CST 2013};{gender=m}

使用XStream是实现XML与Java对象的转换(4)--转换器的更多相关文章

  1. 使用XStream是实现XML与Java对象的转换(6)--持久化

    九.持久化 在第八节的示例中,当我们操作一组对象时,我们可以指定Writer.OutputStream来写出序列化后的XML数据,我们还可以指定Reader.InputStream来读取序列化后的XM ...

  2. 使用XStream是实现XML与Java对象的转换(3)--注解

    六.使用注解(Annotation) 总是使用XStream对象的别名方法和注册转换器,会让人感到非常的乏味,又会产生很多重复性代码,于是我们可以使用注解的方式来配置要序列化的POJO对象. 1,最基 ...

  3. 使用XStream是实现XML与Java对象的转换(2)--别名

    五.使用别名(Alias) 首先,有这样一段Java代码: import java.util.ArrayList; import java.util.List; import com.thoughtw ...

  4. 使用XStream是实现XML与Java对象的转换(1)--简介及入门示例

    一.简单介绍 XStream是thoughtworks开发的开源框架,用于实现XML数据于Java对象.Json数据的转换.它不需要schema或其他的mapping文件就可以进行java对象和xml ...

  5. 使用XStream是实现XML与Java对象的转换(5)--Object Stream

    八,Object Stream 之前的例子我们都是直接输出Xml成为String类型或者从String中获得并解析Xml,现在我们要处理输入流和输出流! 1,输出流(ObjectOutputStrea ...

  6. 不规矩的xml与JAVA对象互相转换的小技巧-使用Marshaller

    摘要:将XML文档与JAVA对象互转是很常见的需求,如果XML定义很规整这很好实现.然而在现实中“不规矩”的XML可能更常见,Marshaller便无能为力了吗?下面是一个小技巧,调整一下思维便能重用 ...

  7. XStream轻松转换xml和java对象

    首先引入所需的jar: xstream-1.4.9.xpp3_min-1.1.4c.dom4j-1.6.1, 或用maven管理jar包时在pom.xml中添加: <!-- https://mv ...

  8. xml-mapping xml 与 java 对象转换映射框架,像 XStream 一样优雅地读写xml

    xml xml 是 java 实现的 xml 框架. 希望以最优雅的方式进行 xml 和 java 之间的转换处理,一行代码搞定一切. 特点 对象的和 xml 的互相映射 支持注解 @Alias 指定 ...

  9. XML 和 java对象相互转换

    XML 和 java对象相互转换 博客分类: XML 和 JSON   下面使用的是JDK自带的类,没有引用任何第三方jar包. Unmarshaller 类使客户端应用程序能够将 XML 数据转换为 ...

随机推荐

  1. Android开发学习之路--React-Native之初体验

      近段时间业余在学node.js,租了个阿里云准备搭建后端,想用node.js,偶尔得知react-native可以在不同平台跑,js在iOS和android上都可以运行ok,今天就简单学习下rea ...

  2. 【ShaderToy】基础篇之谈谈点、线的绘制

    写在前面 写前面一篇的时候,发现还是不够基础.因此打算增加几篇基础篇,从点线面开始,希望可以更好理解. 其实用Pixel Shader的过程很像在纸上绘画的过程.屏幕上的每一个像素对应了纸上的一个方格 ...

  3. CentOs查看文件的几种方式

    有许多命令都可以查看文件,不同的命令有不同的优点,可以针对不同的需要分别选择命令以提高效率:   cat     由第一行开始显示内容,并将所有内容输出   tac     从最后一行倒序显示内容,并 ...

  4. AsyncTask(异步任务)讲解-android的学习之旅(四十六)

    AsyncTask简介 Android的UI线程主要处理用户的按键,触屏和View的绘制等,不能在里面处理耗时的操作,否则会出现ANR,因此耗时的操作要单独开一个线程处理,但是新线程不能直接处理UI线 ...

  5. java设计模式---状态模式

    在阎宏博士的<JAVA与模式>一书中开头是这样描述状态(State)模式的: 状态模式,又称状态对象模式(Pattern of Objects for States),状态模式是对象的行为 ...

  6. 尚学堂马士兵struts2 课堂笔记(一)

    06_尚学堂马士兵_Struts2_Struts2_HelloWorld_5 <constant name="struts.devMode" value="true ...

  7. Java 8新特性探究(三)泛型的目标类型推断

    简单理解泛型 泛型是Java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数.通俗点将就是"类型的变量".这种类型变量可以用在类.接口和方法 ...

  8. Java创建二叉搜索树,实现搜索,插入,删除操作

    Java实现的二叉搜索树,并实现对该树的搜索,插入,删除操作(合并删除,复制删除) 首先我们要有一个编码的思路,大致如下: 1.查找:根据二叉搜索树的数据特点,我们可以根据节点的值得比较来实现查找,查 ...

  9. /sbin/insserv: No such file or directory

    /sbin/insserv: No such file or directory在Ubuntu下安装service服务,可能会报如下错误:/sbin/insserv: No such file or ...

  10. 用CSS指定外部链接的样式

    大部分的信息类网站,比如维基百科,都会对外部链接(<a>标签)指定特定的样式.作为用户,一眼就知道该链接是指向另一个站点的资源是很好的体验.许多网站在服务器端做外部链接检查,添加一个`re ...