Jackson常用注解

序列化注解

@JsonAnyGetter

像普通属性一样序列化Map

public class ExtendableBean {
public String name;
private Map<String, String> properties; @JsonAnyGetter
public Map<String, String> getProperties() {
return properties;
}
}

序列化示例:

{
"name":"My bean",
"attr2":"val2",
"attr1":"val1"
}

@JsonGetter

将指定的方法标记为getter方法。可以用来代替@JsonProperty

public class MyBean {
public int id;
private String name; @JsonGetter("name")
public String getTheName() {
return name;
}
}

序列化示例:

{
"id": 1,
"name":"My bean"
}

@JsonPropertyOrder

用在类上,在序列化的时候自定义属性输出顺序

@JsonPropertyOrder({ "name", "id" })
public class MyBean {
public int id;
public String name;
}

序列化示例:

{
"name":"My bean",
"id": 1
}

@JsonRawValue

完全按照原样序列化属性的值

public class RawBean {
public String name; @JsonRawValue
public String json;
}

例如:

RawBean bean = new RawBean("My bean", "{\"attr\":false}");

将序列化为:

{
"name":"My bean",
"json":{
"attr":false
}
}

而不是:

{
"name":"My bean",
"json":"{\"attr\":false}"
}

@JsonValue

定义整个实体的序列化方法,Jackson将会使用该方法的输出作为序列化输出。

public enum TypeEnumWithValue {
TYPE1(1, "Type A"), TYPE2(2, "Type 2"); private Integer id;
private String name; // standard constructors @JsonValue
public String getName() {
return name;
}
}

序列化示例:

{
"name": "Type 2"
}

@JsonRootName

如果需要将实体包装一层,可以使用@JsonRootName来指定根包装器的名称

@JsonRootName(value = "user")
public class UserWithRoot {
public int id;
public String name;
}

序列化示例:

{
"user": {
"id": 1,
"name": "John"
}
}

如果不用该注解,将会序列化为:

{
"id": 1,
"name": "John"
}

@JsonSerialize

用于指定自定义序列化器来序列化实体

public class Event {
public String name; @JsonSerialize(using = CustomDateSerializer.class)
public Date eventDate;
}

自定义序列化器如下:

public class CustomDateSerializer extends StdSerializer<Date> {

    private static SimpleDateFormat formatter
= new SimpleDateFormat("dd-MM-yyyy hh:mm:ss"); public CustomDateSerializer() {
this(null);
} public CustomDateSerializer(Class<Date> t) {
super(t);
} @Override
public void serialize(
Date value, JsonGenerator gen, SerializerProvider arg2)
throws IOException, JsonProcessingException {
gen.writeString(formatter.format(value));
}
}

输出示例:

{
"name": "test",
"eventDate": "20-12-2014 02:30:00"
}

反序列化注解

@JsonCreator

指定反序列化使用的构造函数或方法

待反序列化Json示例:

{
"id":1,
"theName":"My bean"
}
public class BeanWithCreator {
public int id;
public String name; @JsonCreator
public BeanWithCreator(@JsonProperty("id") int id, @JsonProperty("theName") String name) {
this.id = id;
this.name = name;
}
}

@JacksonInject

指定某个字段从注入赋值,而不是从Json

public class BeanWithInject {
@JacksonInject
public int id; public String name;
}

示例用法:

String json = "{\"name\":\"My bean\"}";

InjectableValues inject = new InjectableValues.Std()
.addValue(int.class, 1);
BeanWithInject bean = new ObjectMapper().reader(inject)
.forType(BeanWithInject.class)
.readValue(json);

@JsonAnySetter

在反序列化时,将Map当成普通属性

待反序列化Json:

{
"name":"My bean",
"attr2":"val2",
"attr1":"val1"
}
public class ExtendableBean {
public String name;
private Map<String, String> properties; @JsonAnySetter
public void add(String key, String value) {
properties.put(key, value);
}
}

properties字段的值将会是由 attr2 -> val2,attr1 -> val1组成的键值对。

@JsonSetter

将方法标记为setter方法,可以指定属性名称

public class MyBean {
public int id;
private String name; @JsonSetter("name")
public void setTheName(String name) {
this.name = name;
}
}

@JsonDeserialize

用于指定自定义反序列化器来反序列化实体

public class Event {
public String name; @JsonDeserialize(using = CustomDateDeserializer.class)
public Date eventDate;
}

对应的反序列化器:

public class CustomDateDeserializer
extends StdDeserializer<Date> { private static SimpleDateFormat formatter
= new SimpleDateFormat("dd-MM-yyyy hh:mm:ss"); public CustomDateDeserializer() {
this(null);
} public CustomDateDeserializer(Class<?> vc) {
super(vc);
} @Override
public Date deserialize(
JsonParser jsonparser, DeserializationContext context)
throws IOException { String date = jsonparser.getText();
try {
return formatter.parse(date);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}

Jackson设置属性是否参与序列化

@JsonIgnoreProperties

在类上指定要忽略的属性

@JsonIgnoreProperties({ "id" })
public class BeanWithIgnore {
public int id;
public String name;
}

@JsonIgnore

在具体属性上忽略,使其不参与序列化过程

public class BeanWithIgnore {
@JsonIgnore
public int id; public String name;
}

@JsonIgnoreProperties是等效的。

@JsonIgnoreType

用在类上,将忽略该类所有属性

public class User {
public int id;
public Name name; @JsonIgnoreType
public static class Name {
public String firstName;
public String lastName;
}
}

@JsonInclude

用于排除值为empty/null/default的属性

@JsonInclude(Include.NON_NULL)
public class MyBean {
public int id;
public String name;
}

@JsonAutoDetect

强制序列化私有属性,不管它有没有getter方法

@JsonAutoDetect(fieldVisibility = Visibility.ANY)
public class PrivateBean {
private int id;
private String name;
}

Jackson处理多态

一般都是组合起来使用,有下面三个注解:

  • @JsonTypeInfo

指定序列化中包含的类型信息的详细信息

  • @JsonSubTypes

指定带注释类型的子类型

  • @JsonTypeName

指定用于带注释的类的逻辑类型名称

public class Zoo {
public Animal animal; @JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = As.PROPERTY,
property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "dog"),
@JsonSubTypes.Type(value = Cat.class, name = "cat")
})
public static class Animal {
public String name;
} @JsonTypeName("dog")
public static class Dog extends Animal {
public double barkVolume;
} @JsonTypeName("cat")
public static class Cat extends Animal {
boolean likesCream;
public int lives;
}
}

上述例子中,指定属性type为判断具体子类的依据,例如:type=dog,将被序列化为Dog类型。

Jackson通用注解(序列化反序列化都生效)

@JsonProperty

指定JSON中的属性名称

public class MyBean {
public int id;
private String name; @JsonProperty("name")
public void setTheName(String name) {
this.name = name;
} @JsonProperty("name")
public String getTheName() {
return name;
}
}

@JsonFormat

用于在序列化日期/时间值时指定格式。

public class Event {
public String name; @JsonFormat(
shape = JsonFormat.Shape.STRING,
pattern = "dd-MM-yyyy hh:mm:ss")
public Date eventDate;
}

@JsonUnwrapped

将对象中所有的属性与当前平级,不太好描述,简单说就是拆开包装。

public class UnwrappedUser {
public int id; @JsonUnwrapped
public Name name; public static class Name {
public String firstName;
public String lastName;
}
}

序列化示例:

{
"id":1,
"firstName":"John",
"lastName":"Doe"
}

如果不加@JsonUnwrapped注解,将被序列化为:

{
"id":1,
"name": {
"firstName":"John",
"lastName":"Doe"
}
}

@JsonView

指定视图,类似分组进行序列化/反序列化

定义视图:

public class Views {
public static class Public {}
public static class Internal extends Public {}
}

定义实体:

public class Item {
@JsonView(Views.Public.class)
public int id; @JsonView(Views.Public.class)
public String itemName; @JsonView(Views.Internal.class)
public String ownerName;
}

序列化示例:

String result = new ObjectMapper()
.writerWithView(Views.Public.class)
.writeValueAsString(item);

这时,将只会序列化iditemName字段

@JsonManagedReference, @JsonBackReference

@JsonManagedReference和@JsonBackReference注释用于处理父/子关系并解决循环问题。

例如,有两个相互引用的类:

public class ItemWithRef {
public int id;
public String itemName; @JsonManagedReference
public UserWithRef owner;
}
public class UserWithRef {
public int id;
public String name; @JsonBackReference
public List<ItemWithRef> userItems;
}

不加注解,会循环调用,导致内存溢出,这时候可以使用@JsonManagedReference@JsonBackReference来避免内存溢出。

@JsonIdentityInfo

用于指定在序列化/反序列化值时使用对象标识,例如,处理无限递归类型的问题。

@JsonIdentityInfo(
generator = ObjectIdGenerators.PropertyGenerator.class,
property = "id")
public class ItemWithIdentity {
public int id;
public String itemName;
public UserWithIdentity owner;
}

@JsonFilter

指定序列化期间要使用的过滤器。

@JsonFilter("myFilter")
public class BeanWithFilter {
public int id;
public String name;
}

示例代码:

BeanWithFilter bean = new BeanWithFilter(1, "My bean");

FilterProvider filters
= new SimpleFilterProvider().addFilter(
"myFilter",
SimpleBeanPropertyFilter.filterOutAllExcept("name")); String result = new ObjectMapper()
.writer(filters)
.writeValueAsString(bean);

自定义Jackson注解

可以使用@JacksonAnnotationsInside来开发自定义注解

@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonInclude(Include.NON_NULL)
@JsonPropertyOrder({ "name", "id", "dateCreated" })
public @interface CustomAnnotation {}

如何使用自定义注解:

@CustomAnnotation
public class BeanWithCustomAnnotation {
public int id;
public String name;
public Date dateCreated;
}

自定义注解可以增强代码复用,把一些通用的Jackson注解组合起来,形成一个新注解,新注解可以代替组合的注解。

Jackson MixIn 注解

动态地为某些类型增加统一的Jackson注解

实体:

public class Item {
public int id;
public String itemName;
public User owner;
}

MixIn类:

@JsonIgnoreType
public class MyMixInForIgnoreType {}

我们可以动态地让User类型不参与序列化:

Item item = new Item(1, "book", null);
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(User.class, MyMixInForIgnoreType.class);
result = mapper.writeValueAsString(item);

禁用Jackson注解

假设我们有一个带Jackson注解的实体:

@JsonInclude(Include.NON_NULL)
@JsonPropertyOrder({ "name", "id" })
public class MyBean {
public int id;
public String name;
}

我们可以这样来禁用该实体上的所有Jackson注解:

MyBean bean = new MyBean(1, null);
ObjectMapper mapper = new ObjectMapper();
mapper.disable(MapperFeature.USE_ANNOTATIONS);

Jackson的ObjectMapper用法

java类 转换为 json

可以直接序列化为Json字符串:

objectMapper.writeValueAsString(car);

或者,可以序列化到文件,文件内容是Json字符串:

objectMapper.writeValue(new File("target/car.json"), car);

json 转换为 java类

从字符串:

String json = "{ \"color\" : \"Black\", \"type\" : \"BMW\" }";
objectMapper.readValue(json, Car.class);

从文件:

objectMapper.readValue(new File("target/json_car.json"), Car.class);

从URL:

objectMapper.readValue(new URL("target/json_car.json"), Car.class);

json转换为Jackson JsonNode

String json = "{ \"color\" : \"Black\", \"type\" : \"FIAT\" }";
JsonNode jsonNode = objectMapper.readTree(json);
String color = jsonNode.get("color").asText();
// Output: color -> Black

json 转换为 java集合

String jsonCarArray =
"[{ \"color\" : \"Black\", \"type\" : \"BMW\" }, { \"color\" : \"Red\", \"type\" : \"FIAT\" }]";
List<Car> listCar = objectMapper.readValue(jsonCarArray, new TypeReference<List<Car>>(){});

json 转换为 Map

String json = "{ \"color\" : \"Black\", \"type\" : \"BMW\" }";
Map<String, Object> map = objectMapper.readValue(json, new TypeReference<Map<String,Object>>(){});

ObjectMapper的常用配置

忽略不识别的字段(json属性与目标实体存在属性上的差异):

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

允许原始值为null:

objectMapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);

允许将枚举序列化/反序列化为数字:

objectMapper.configure(DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS, false);

配置自定义序列化/反序列化器

假设有一个序列化器:

public class CustomCarSerializer extends StdSerializer<Car> {

    public CustomCarSerializer() {
this(null);
} public CustomCarSerializer(Class<Car> t) {
super(t);
} @Override
public void serialize(
Car car, JsonGenerator jsonGenerator, SerializerProvider serializer) {
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("car_brand", car.getType());
jsonGenerator.writeEndObject();
}
}

一个反序列化器:

public class CustomCarDeserializer extends StdDeserializer<Car> {

    public CustomCarDeserializer() {
this(null);
} public CustomCarDeserializer(Class<?> vc) {
super(vc);
} @Override
public Car deserialize(JsonParser parser, DeserializationContext deserializer) {
Car car = new Car();
ObjectCodec codec = parser.getCodec();
JsonNode node = codec.readTree(parser); // try catch block
JsonNode colorNode = node.get("color");
String color = colorNode.asText();
car.setColor(color);
return car;
}
}

ObjectMapper使用他们:

//添加自定义序列化器
module.addSerializer(Car.class, new CustomCarSerializer());
//添加自定义反序列化器
module.addDeserializer(Car.class, new CustomCarDeserializer());

处理日期格式化

ObjectMapper objectMapper = new ObjectMapper();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm a z");
objectMapper.setDateFormat(df);

处理集合

反序列化为数组:

String jsonCarArray =
"[{ \"color\" : \"Black\", \"type\" : \"BMW\" }, { \"color\" : \"Red\", \"type\" : \"FIAT\" }]";
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true);
Car[] cars = objectMapper.readValue(jsonCarArray, Car[].class);

反序列化为集合:

String jsonCarArray =
"[{ \"color\" : \"Black\", \"type\" : \"BMW\" }, { \"color\" : \"Red\", \"type\" : \"FIAT\" }]";
ObjectMapper objectMapper = new ObjectMapper();
List<Car> listCar = objectMapper.readValue(jsonCarArray, new TypeReference<List<Car>>(){});

ObjectMapper的基本用法

ObjectMapper可以通过configure方法设置全局序列化/反序列化行为,例如:

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

常用的一些设置:

  1. DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES:忽略不识别的字段
  2. DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES:允许使用属性的默认值进行反序列化
  3. DeserializationFeature.FAIL_ON_NUMBERS_FOR_ENUMS:允许将枚举值序列化/反序列化为数字

注册自定义序列化/反序列化程序

//创建一个模块
SimpleModule module = new SimpleModule("CustomCarSerializer", new Version(1, 0, 0, null, null, null));
//将自定义序列化/反序列化程序注册到模块
module.addSerializer(Car.class, new CustomCarSerializer());
//module.addDeserializer(Car.class, new CustomCarDeserializer());
//注册模块
mapper.registerModule(module);

处理日期格式

DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm a z");
mapper.setDateFormat(df);

处理集合

处理数组

String jsonCarArray = "[{ \"color\" : \"Black\", \"type\" : \"BMW\" }, { \"color\" : \"Red\", \"type\" : \"FIAT\" }]";
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.USE_JAVA_ARRAY_FOR_JSON_ARRAY, true);
Car[] cars = objectMapper.readValue(jsonCarArray, Car[].class);

处理集合

String jsonCarArray = "[{ \"color\" : \"Black\", \"type\" : \"BMW\" }, { \"color\" : \"Red\", \"type\" : \"FIAT\" }]";
ObjectMapper objectMapper = new ObjectMapper();
List<Car> listCar = objectMapper.readValue(jsonCarArray, new TypeReference<List<Car>>(){});

Jackson注解扩展

@JsonIdentityReference

使用指定的标识来序列化Java对象,而不是序列化整个对象

例如:

@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
@JsonIdentityReference(alwaysAsId = true)
public class BeanWithoutIdentityReference {
private int id;
private String name;
}

将被序列化为:

1

@JsonAppend

运行在序列化时添加额外的属性

@JsonAppend(attrs = {
@JsonAppend.Attr(value = "version")
})
public class BeanWithAppend {
private int id;
private String name; // constructor, getters and setters
}

例如,我们在序列化时手动增加version = 1.0的属性

BeanWithAppend bean = new BeanWithAppend(2, "Bean With Append Annotation");
ObjectWriter writer = mapper.writerFor(BeanWithAppend.class).withAttribute("version", "1.0");
String jsonString = writer.writeValueAsString(bean);

序列化结果:

{
"id": 2,
"name": "Bean With Append Annotation",
"version": "1.0"
}

@JsonNaming

指定序列化的时候属性命名方式

有四种选项:

  • KEBAB_CASE

由连字符分割,例如:kebab-case

  • LOWER_CASE

所有的字母都转换为小写,例如:lowercase

  • SNAKE_CASE

所有的字母都转换为小写,并且由下划线分割,例如:snake_case

  • UPPER_CAMEL_CASE

所有名称元素,包括第一个元素,都以大写字母开头,后跟小写字母,并且没有分隔符,例如:UpperCamelCase

使用举例:

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class NamingBean {
private int id;
private String beanName;
}

@JsonPropertyDescription

用于生成字段的描述信息

例如,有下面一个实体:

public class PropertyDescriptionBean {
private int id;
@JsonPropertyDescription("This is a description of the name property")
private String name;
}

我们可以输出该类的信息:

SchemaFactoryWrapper wrapper = new SchemaFactoryWrapper();
mapper.acceptJsonFormatVisitor(PropertyDescriptionBean.class, wrapper);
JsonSchema jsonSchema = wrapper.finalSchema();
String jsonString = mapper.writeValueAsString(jsonSchema);

结果如下:

{
"type": "object",
"id": "urn:jsonschema:com:baeldung:jackson:annotation:extra:PropertyDescriptionBean",
"properties":
{
"name":
{
"type": "string",
"description": "This is a description of the name property"
}, "id":
{
"type": "integer"
}
}
}

@JsonPOJOBuilder

自定义生成器类,来控制json的反序列化行为

@JsonPOJOBuilder有两个属性:

  • buildMethodName

将JSON字段绑定到bean的属性后,用于实例化预期bean的无参构造的名称。默认名称为build

  • withPrefix

用于自动检测JSON和bean属性之间匹配的名称前缀。默认前缀为with

假设我们要反序列化的json如下:

{
"id": 5,
"name": "POJO Builder Bean"
}

对应的pojo:

@JsonDeserialize(builder = BeanBuilder.class)
public class POJOBuilderBean {
private int identity;
private String beanName; // constructor, getters and setters
}

对应的生成器:

@JsonPOJOBuilder(buildMethodName = "createBean", withPrefix = "construct")
public class BeanBuilder {
private int idValue;
private String nameValue; public BeanBuilder constructId(int id) {
idValue = id;
return this;
} public BeanBuilder constructName(String name) {
nameValue = name;
return this;
} public POJOBuilderBean createBean() {
return new POJOBuilderBean(idValue, nameValue);
}
}

使用ObjectMapper反序列化:

String jsonString = "{\"id\":5,\"name\":\"POJO Builder Bean\"}";
POJOBuilderBean bean = mapper.readValue(jsonString, POJOBuilderBean.class);

Jackson使用指南的更多相关文章

  1. Jackson 工具类使用及配置指南

    目录 前言 Jackson使用工具类 Jackson配置属性 Jackson解析JSON数据 Jackson序列化Java对象 前言 Json数据格式这两年发展的很快,其声称相对XML格式有很对好处: ...

  2. Jackson工具类使用及配置指南、高性能配置(转)

    Jackson使用工具类 通常,我们对JSON格式的数据,只会进行解析和封装两种,也就是JSON字符串--->Java对象以及Java对象--->JSON字符串. public class ...

  3. Retrofit结合RxJava使用指南

    Retrofit结合RxJava使用指南 Retrofit是一个当前很流行的网络请求库, 官网的介绍是: "Type-safe HTTP client for Android and Jav ...

  4. [翻译]Java日志终极指南

    本文由 ImportNew - Wing 翻译自 loggly.欢迎加入翻译小组.转载请见文末要求. Java日志基础 Java使用了一种自定义的.可扩展的方法来输出日志.虽然Java通过java.u ...

  5. web之困:现代web应用安全指南

    <web之困:现代web应用安全指南>在web安全领域有“圣经”的美誉,在世界范围内被安全工作者和web从业人员广为称道,由来自google chrome浏览器团队的世界顶级黑客.国际一流 ...

  6. Android最佳实践指南

    Updated on 2016/1/6 修正了一些翻译段落欢迎转载,但请保留译者链接:http://www.jianshu.com/p/613d28a3c8a0 Lessons learned fro ...

  7. Java日志终极指南

    Java日志基础 Java使用了一种自定义的.可扩展的方法来输出日志.虽然Java通过java.util.logging包提供了一套基本的日志处理API,但你可以很轻松的使用一种或者多种其它日志解决方 ...

  8. 分布式消息系统Jafka入门指南之二

    分布式消息系统Jafka入门指南之二 作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chszs 三.Jafka的文件夹结构 1.安装tree命令 $ sudo yu ...

  9. spring 4 升级踩雷指南

    spring 4 升级踩雷指南 前言 最近,一直在为公司老项目做核心库升级工作.本来只是想升级一下 JDK8 ,却因为兼容性问题而不得不升级一些其他的库,而其他库本身依赖的一些库可能也要同步升级.这是 ...

随机推荐

  1. Altium Designer 14安装破解

    Altium Designer 14简称AD14,是一款专业的PCB设计软件,利用他可以计出专业的PCB元件.Altium Designer 14.3.10是目前的最新版本. Altium Desig ...

  2. sqlserver install on linux chapter two

    The previous chapter is tell us how to install sqlerver on linuix Today, we will see how to make it ...

  3. 安装symfony3.4的坑,也是PHP7.3的经典坑之解决办法

    对于刚入手symfony3.4的同学,肯定会发现,安装symfony后部署后看到的往往不是hello world,也不是symfony的欢迎页面,而是给你一个下马威,唉,给你来个bug开开胃. 当然这 ...

  4. [Effective Java 读书笔记] 第三章 对所有对象都通用的方法 第十---十一条

    第十条 始终覆盖toString() toString的实现可以使类使用起来更加舒适,在执行println等方法时打印出定制信息. 一单实现了自己的toString,指定输出的固定格式,在方法的文档说 ...

  5. Java范型学习笔记

    对于范型的使用或者说印象只有集合,其他地方即使使用过也不知道,反正就是只停留在List<E> Map<K, V>,最近刚好闲来无事,就找找资料学习一下:下列为个人学习总结,欢迎 ...

  6. ajax面试要点

    目录 目录 ajax是什么? 优点 缺点 ajax的工作原理 如何创建一个ajax(ajax的交互模型) ajax过程中get和post的区别 同步和异步的区别 JavaScript 的同源策略 如何 ...

  7. javascript 动态加载javascript文件

    /* loadFile(data, callback): 动态加载js文件 data: 存放需要加载的js文件的url("url" || ["url", &qu ...

  8. Shell脚本 小程序演示

    一般的shell编程 场景贯穿了几个熟知的步骤: ●显示消息●获取用户输入●存储值到文件●处理存储的数据 这里写一个小程序 包含以上几部 #!/bin/bash while true do #echo ...

  9. apache/tomcat安装过程略

    apache/tomcat安装过程略 一些变量 apache安装目录 APACHE_PREFIX=/Data/app/apache apache配置文件 APACHE_CONF=/etc/httpd/ ...

  10. Java集合效率问题

    凑算式 B DEFA + --- + ------- = 10 C GHI (如果显示有问题,可以参见[图1.jpg]) 这个算式中A~I代表1~9的数字,不同的字母代表不同的数字. 比如:6+8/3 ...