CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-fasterxml-jackson-core--jackson-annotations

Core annotations used for value types, used by Jackson data binding package.

Pending
Overview
Eval results
Files

object-structure.mddocs/

Object Structure

Annotations that modify how objects are structured in JSON, including unwrapping nested objects and controlling value representation.

Capabilities

JsonUnwrapped

Unwrap nested object properties into the parent object.

/**
 * Unwrap nested object properties into parent object
 * @param enabled Whether to enable unwrapping (default: true)
 * @param prefix Prefix to add to unwrapped property names
 * @param suffix Suffix to add to unwrapped property names
 */
@JsonUnwrapped(boolean enabled = true,
               String prefix = "",
               String suffix = "")
public @interface JsonUnwrapped;

Usage Examples:

public class Person {
    private String firstName;
    private String lastName;
    
    @JsonUnwrapped
    private Address address;
    
    @JsonUnwrapped(prefix = "work_")
    private Address workAddress;
}

public class Address {
    private String street;
    private String city;
    private String zipCode;
}

// Without @JsonUnwrapped:
// {"firstName": "John", "lastName": "Doe", "address": {"street": "123 Main St", "city": "NYC", "zipCode": "10001"}}

// With @JsonUnwrapped:
// {"firstName": "John", "lastName": "Doe", "street": "123 Main St", "city": "NYC", "zipCode": "10001", "work_street": "456 Office Blvd", "work_city": "NYC", "work_zipCode": "10002"}

JsonValue

Use a single method or field value as the JSON representation of the entire object.

/**
 * Use single value as JSON representation of entire object
 * @param value Whether to use this as the JSON value (default: true)
 */
@JsonValue(boolean value = true)
public @interface JsonValue;

Usage Examples:

public enum Status {
    ACTIVE("active"),
    INACTIVE("inactive"),
    PENDING("pending");
    
    private final String code;
    
    Status(String code) {
        this.code = code;
    }
    
    @JsonValue
    public String getCode() {
        return code;
    }
}

// Serializes as: "active" instead of {"code": "active"}

public class Money {
    private final BigDecimal amount;
    private final String currency;
    
    public Money(BigDecimal amount, String currency) {
        this.amount = amount;
        this.currency = currency;
    }
    
    @JsonValue
    public String toString() {
        return amount + " " + currency;
    }
}

// Serializes as: "100.50 USD" instead of {"amount": 100.50, "currency": "USD"}

JsonRawValue

Serialize string value as raw JSON without quotes or escaping.

/**
 * Serialize string value as raw JSON without quotes/escaping
 * @param value Whether to use raw value serialization (default: true)
 */
@JsonRawValue(boolean value = true)
public @interface JsonRawValue;

Usage Examples:

public class JsonContainer {
    private String name;
    
    @JsonRawValue
    private String jsonData;
    
    @JsonRawValue
    private String configJson;
}

// If jsonData contains: {"settings": {"theme": "dark"}, "count": 42}
// Result: {"name": "container", "jsonData": {"settings": {"theme": "dark"}, "count": 42}, "configJson": {...}}
// Instead of: {"name": "container", "jsonData": "{\"settings\": {\"theme\": \"dark\"}, \"count\": 42}"}

JsonKey

Use property value as Map key during serialization.

/**
 * Use property value as Map key during serialization
 * @param value Whether to use this property as key (default: true)
 */
@JsonKey(boolean value = true)
public @interface JsonKey;

Usage Examples:

public class KeyedItem {
    @JsonKey
    private String identifier;
    
    private String name;
    private String description;
}

// When used in a collection context, the identifier becomes the map key:
// List<KeyedItem> items -> Map<String, KeyedItem> structure
// [{"identifier": "item1", "name": "First"}, {"identifier": "item2", "name": "Second"}]
// becomes: {"item1": {"name": "First"}, "item2": {"name": "Second"}}

JsonAnyGetter and JsonAnySetter

Handle dynamic properties with Map-based storage.

/**
 * Mark method returning Map to serialize as additional properties
 * @param enabled Whether to enable any-getter behavior (default: true)
 */
@JsonAnyGetter(boolean enabled = true)
public @interface JsonAnyGetter;

/**
 * Mark method/field as fallback for unrecognized properties during deserialization
 * @param enabled Whether to enable any-setter behavior (default: true)
 */
@JsonAnySetter(boolean enabled = true)
public @interface JsonAnySetter;

Usage Examples:

public class FlexibleObject {
    private String name;
    private String type;
    
    private Map<String, Object> additionalProperties = new HashMap<>();
    
    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return additionalProperties;
    }
    
    @JsonAnySetter
    public void setAdditionalProperty(String key, Object value) {
        additionalProperties.put(key, value);
    }
}

// JSON: {"name": "test", "type": "sample", "customField": "value", "count": 42}
// additionalProperties will contain: {"customField": "value", "count": 42}
// Serialization includes all additional properties at the top level

Advanced Structure Patterns

Nested Unwrapping

public class Employee {
    private String employeeId;
    
    @JsonUnwrapped
    private PersonalInfo personal;
    
    @JsonUnwrapped(prefix = "contact_")
    private ContactInfo contact;
    
    @JsonUnwrapped(prefix = "work_", suffix = "_info")
    private WorkInfo work;
}

public class PersonalInfo {
    private String firstName;
    private String lastName;
    private LocalDate birthDate;
}

public class ContactInfo {
    private String email;
    private String phone;
}

public class WorkInfo {
    private String department;
    private String position;
}

// Result: {
//   "employeeId": "E123",
//   "firstName": "John", "lastName": "Doe", "birthDate": "1990-01-15",
//   "contact_email": "john@company.com", "contact_phone": "555-0123",
//   "work_department_info": "Engineering", "work_position_info": "Senior Developer"
// }

Conditional Raw Values

public class ConfigurableResponse {
    private String status;
    private String message;
    
    @JsonRawValue
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private String rawData;  // Only included if not null, and as raw JSON
    
    @JsonRawValue
    private String getFormattedConfig() {
        // Method can return formatted JSON string
        return configService.getJsonConfig();
    }
}

Complex Value Objects

public class Coordinate {
    private final double x;
    private final double y;
    
    @JsonCreator
    public Coordinate(@JsonProperty("x") double x, @JsonProperty("y") double y) {
        this.x = x;
        this.y = y;
    }
    
    @JsonValue
    public String toWktString() {
        return String.format("POINT(%f %f)", x, y);
    }
    
    // Custom deserializer would be needed to parse the WKT string back
}

// Serializes as: "POINT(10.500000 20.300000)"

Dynamic Property Handling

public class ApiResource {
    private String id;
    private String type;
    
    // Store metadata separately
    @JsonIgnore
    private Map<String, Object> metadata = new HashMap<>();
    
    // Store dynamic fields separately  
    @JsonIgnore
    private Map<String, Object> dynamicFields = new HashMap<>();
    
    @JsonAnyGetter
    public Map<String, Object> getDynamicFields() {
        Map<String, Object> all = new HashMap<>(metadata);
        all.putAll(dynamicFields);
        return all;
    }
    
    @JsonAnySetter
    public void setDynamicField(String key, Object value) {
        if (key.startsWith("meta_")) {
            metadata.put(key.substring(5), value);
        } else {
            dynamicFields.put(key, value);
        }
    }
}

Wrapper and Container Patterns

public class ApiResponse<T> {
    private String status;
    private String message;
    
    @JsonUnwrapped
    private T data;  // Unwrap the actual data into the response
    
    private Map<String, Object> meta;
}

// Usage:
ApiResponse<User> response = new ApiResponse<>();
response.setData(new User("john", "john@email.com"));

// Result: {"status": "success", "message": "OK", "username": "john", "email": "john@email.com", "meta": {...}}

Install with Tessl CLI

npx tessl i tessl/maven-com-fasterxml-jackson-core--jackson-annotations

docs

configuration.md

formatting.md

inclusion-exclusion.md

index.md

object-creation.md

object-identity.md

object-structure.md

polymorphic-types.md

property-control.md

tile.json