CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-net-minidev--json-smart

JSON Small and Fast Parser - A lightweight, high-performance JSON processing library for Java

Pending
Overview
Eval results
Files

configuration.mddocs/

Output Formatting and Configuration

JSON-Smart provides extensive configuration options through JSONStyle for controlling JSON output formatting, compression levels, and parser behavior. This document covers all configuration aspects for both serialization and parsing.

JSONStyle - Output Formatting

JSONStyle controls how JSON is formatted during serialization, offering various compression levels and formatting options.

Predefined Styles

public static final JSONStyle NO_COMPRESS;
public static final JSONStyle MAX_COMPRESS;
public static final JSONStyle LT_COMPRESS;

Three predefined formatting styles for common use cases.

JSONObject obj = new JSONObject()
    .appendField("name", "John Doe")
    .appendField("age", 30)
    .appendField("active", true);

// No compression - readable formatting
String readable = obj.toJSONString(JSONStyle.NO_COMPRESS);
// {"name" : "John Doe", "age" : 30, "active" : true}

// Maximum compression - minimal size
String compressed = obj.toJSONString(JSONStyle.MAX_COMPRESS);
// {name:"John Doe",age:30,active:true}

// Light compression - balanced
String balanced = obj.toJSONString(JSONStyle.LT_COMPRESS);
// {"name":"John Doe","age":30,"active":true}

Flag Constants

public static final int FLAG_PROTECT_KEYS = 1;
public static final int FLAG_PROTECT_4WEB = 2;
public static final int FLAG_PROTECT_VALUES = 4;
public static final int FLAG_AGRESSIVE = 8;
public static final int FLAG_IGNORE_NULL = 16;

Individual flags that control specific formatting behaviors:

  • FLAG_PROTECT_KEYS: Always quote object keys
  • FLAG_PROTECT_4WEB: Use web-safe escaping
  • FLAG_PROTECT_VALUES: Always quote string values
  • FLAG_AGRESSIVE: Maximum compression (remove all unnecessary characters)
  • FLAG_IGNORE_NULL: Skip null values in output

Constructors

public JSONStyle();
public JSONStyle(int FLAG);

Create custom formatting styles.

// Default style
JSONStyle defaultStyle = new JSONStyle();

// Custom style with specific flags
JSONStyle customStyle = new JSONStyle(
    JSONStyle.FLAG_PROTECT_KEYS | JSONStyle.FLAG_IGNORE_NULL
);

// Multiple flags combined
int webSafeFlags = JSONStyle.FLAG_PROTECT_KEYS | 
                   JSONStyle.FLAG_PROTECT_4WEB | 
                   JSONStyle.FLAG_IGNORE_NULL;
JSONStyle webSafe = new JSONStyle(webSafeFlags);

Configuration Methods

public boolean protectKeys();
public boolean protectValues();
public boolean protect4Web();
public boolean ignoreNull();
public boolean indent();
public boolean mustProtectKey(String s);
public boolean mustProtectValue(String s);

Query current configuration and test protection requirements.

JSONStyle style = new JSONStyle(JSONStyle.FLAG_PROTECT_KEYS | JSONStyle.FLAG_IGNORE_NULL);

// Check configuration
boolean quotesKeys = style.protectKeys(); // true
boolean skipsNull = style.ignoreNull(); // true
boolean indented = style.indent(); // false

// Test specific values
boolean needsQuotes = style.mustProtectKey("validKey"); // true (always protect when flag set)
boolean valueNeedsQuotes = style.mustProtectValue("simple"); // depends on flag and content

Output Formatting Examples

Key Protection Examples

JSONObject obj = new JSONObject()
    .appendField("simpleKey", "value")
    .appendField("key with spaces", "value")
    .appendField("123numeric", "value")
    .appendField("key-with-dashes", "value");

// Default style - quotes only when necessary
String normal = obj.toJSONString();
// {simpleKey:"value","key with spaces":"value","123numeric":"value","key-with-dashes":"value"}

// Always protect keys
JSONStyle protectKeys = new JSONStyle(JSONStyle.FLAG_PROTECT_KEYS);
String quoted = obj.toJSONString(protectKeys);
// {"simpleKey":"value","key with spaces":"value","123numeric":"value","key-with-dashes":"value"}

Value Protection Examples

JSONObject obj = new JSONObject()
    .appendField("string", "simple")
    .appendField("number", 42)
    .appendField("boolean", true)
    .appendField("special", "string with \"quotes\" and \n newlines");

// Default style
String normal = obj.toJSONString();
// {string:simple,number:42,boolean:true,special:"string with \"quotes\" and \n newlines"}

// Always protect string values  
JSONStyle protectValues = new JSONStyle(JSONStyle.FLAG_PROTECT_VALUES);
String quoted = obj.toJSONString(protectValues);
// {string:"simple",number:42,boolean:true,special:"string with \"quotes\" and \n newlines"}

Null Handling Examples

JSONObject obj = new JSONObject()
    .appendField("name", "John")
    .appendField("middle", null)
    .appendField("age", 30)
    .appendField("email", null);

// Default style - includes nulls
String withNulls = obj.toJSONString();
// {name:"John",middle:null,age:30,email:null}

// Ignore null values
JSONStyle ignoreNull = new JSONStyle(JSONStyle.FLAG_IGNORE_NULL);
String noNulls = obj.toJSONString(ignoreNull);
// {name:"John",age:30}

Web-Safe Formatting

JSONObject obj = new JSONObject()
    .appendField("html", "<script>alert('xss')</script>")
    .appendField("path", "/api/users")
    .appendField("callback", "jsonp_callback_123");

// Default style
String normal = obj.toJSONString();
// {html:"<script>alert('xss')</script>",path:"/api/users",callback:"jsonp_callback_123"}

// Web-safe escaping
JSONStyle webSafe = new JSONStyle(JSONStyle.FLAG_PROTECT_4WEB);
String safe = obj.toJSONString(webSafe);
// {html:"\\u003cscript\\u003ealert('xss')\\u003c\\/script\\u003e",path:"\\/api\\/users",callback:"jsonp_callback_123"}

Output Writing Methods

JSONStyle provides methods for writing JSON output with specific formatting.

String Writing

public void writeString(Appendable out, String value) throws IOException;
public void escape(String s, Appendable out);

Write strings with appropriate escaping and quoting.

JSONStyle style = new JSONStyle(JSONStyle.FLAG_PROTECT_VALUES);
StringBuilder sb = new StringBuilder();

// Write quoted string
style.writeString(sb, "Hello World");
System.out.println(sb.toString()); // "Hello World"

// Write with escaping
sb.setLength(0);
style.escape("Text with \"quotes\"", sb);
System.out.println(sb.toString()); // Text with \"quotes\"

Structure Writing Methods

public void objectStart(Appendable out) throws IOException;
public void objectStop(Appendable out) throws IOException;
public void objectFirstStart(Appendable out) throws IOException;
public void objectNext(Appendable out) throws IOException;
public void objectElmStop(Appendable out) throws IOException;
public void objectEndOfKey(Appendable out) throws IOException;

public void arrayStart(Appendable out) throws IOException;
public void arrayStop(Appendable out) throws IOException;
public void arrayfirstObject(Appendable out) throws IOException;
public void arrayNextElm(Appendable out) throws IOException;
public void arrayObjectEnd(Appendable out) throws IOException;

Low-level methods for manual JSON construction with consistent formatting.

JSONStyle style = JSONStyle.NO_COMPRESS;
StringBuilder json = new StringBuilder();

// Manual object construction
style.objectStart(json);           // {
style.objectFirstStart(json);      // 
json.append("\"name\"");
style.objectEndOfKey(json);        // :
style.writeString(json, "John");   // "John"
style.objectNext(json);            // ,
json.append("\"age\"");
style.objectEndOfKey(json);        // :
json.append("30");
style.objectElmStop(json);         //
style.objectStop(json);            // }

System.out.println(json.toString()); // {"name" : "John", "age" : 30}

Custom Style Creation

Custom Compression Style

// Create highly compressed style for APIs
public class APICompressionStyle extends JSONStyle {
    
    public APICompressionStyle() {
        super(FLAG_AGRESSIVE | FLAG_IGNORE_NULL | FLAG_PROTECT_4WEB);
    }
    
    @Override
    public boolean mustProtectKey(String key) {
        // Never protect keys that are simple identifiers
        if (key.matches("^[a-zA-Z_][a-zA-Z0-9_]*$")) {
            return false;
        }
        return super.mustProtectKey(key);
    }
    
    @Override
    public boolean mustProtectValue(String value) {
        // Don't protect simple numeric strings
        if (value.matches("^\\d+$")) {
            return false;
        }
        return super.mustProtectValue(value);
    }
}

// Usage
JSONStyle apiStyle = new APICompressionStyle();
JSONObject data = new JSONObject()
    .appendField("userId", "12345")
    .appendField("status", "active")
    .appendField("count", null);

String compressed = data.toJSONString(apiStyle);
// {userId:12345,status:active}  (null ignored, minimal quotes)

Debug-Friendly Style

public class DebugJSONStyle extends JSONStyle {
    
    public DebugJSONStyle() {
        super(FLAG_PROTECT_KEYS | FLAG_PROTECT_VALUES);
    }
    
    @Override
    public void objectStart(Appendable out) throws IOException {
        out.append("{\n  ");
    }
    
    @Override
    public void objectStop(Appendable out) throws IOException {
        out.append("\n}");
    }
    
    @Override
    public void objectNext(Appendable out) throws IOException {
        out.append(",\n  ");
    }
    
    @Override
    public void objectEndOfKey(Appendable out) throws IOException {
        out.append(" : ");
    }
    
    @Override
    public void arrayStart(Appendable out) throws IOException {
        out.append("[\n    ");
    }
    
    @Override
    public void arrayStop(Appendable out) throws IOException {
        out.append("\n  ]");
    }
    
    @Override
    public void arrayNextElm(Appendable out) throws IOException {
        out.append(",\n    ");
    }
}

// Usage
JSONStyle debugStyle = new DebugJSONStyle();
JSONObject obj = new JSONObject()
    .appendField("name", "John")
    .appendField("items", Arrays.asList("a", "b", "c"));

String formatted = obj.toJSONString(debugStyle);
/*
{
  "name" : "John",
  "items" : [
    "a",
    "b", 
    "c"
  ]
}
*/

Parser Configuration

While JSONStyle controls output formatting, parser configuration is handled through JSONParser mode flags.

Common Parser Configurations

// Strict web API parsing
int webApiMode = JSONParser.MODE_RFC4627 | JSONParser.REJECT_127_CHAR;
JSONParser webParser = new JSONParser(webApiMode);

// Lenient file parsing  
int fileMode = JSONParser.MODE_PERMISSIVE | 
               JSONParser.ACCEPT_SIMPLE_QUOTE |
               JSONParser.ACCEPT_USELESS_COMMA;
JSONParser fileParser = new JSONParser(fileMode);

// High-precision financial parsing
int financialMode = JSONParser.MODE_PERMISSIVE | 
                    JSONParser.USE_HI_PRECISION_FLOAT |
                    JSONParser.BIG_DIGIT_UNRESTRICTED;
JSONParser financialParser = new JSONParser(financialMode);

Configuration Validation

public class ConfigurationValidator {
    
    public static void validateStyleConfiguration(JSONStyle style) {
        System.out.println("Style Configuration:");
        System.out.println("  Protect Keys: " + style.protectKeys());
        System.out.println("  Protect Values: " + style.protectValues());
        System.out.println("  Web Safe: " + style.protect4Web());
        System.out.println("  Ignore Null: " + style.ignoreNull());
        System.out.println("  Indent: " + style.indent());
    }
    
    public static void testStyleOutput(JSONStyle style) {
        JSONObject testObj = new JSONObject()
            .appendField("simpleKey", "simpleValue")
            .appendField("key with spaces", "value with \"quotes\"")
            .appendField("nullValue", null)
            .appendField("number", 42)
            .appendField("htmlContent", "<script>alert('test')</script>");
        
        String output = testObj.toJSONString(style);
        System.out.println("Output: " + output);
        System.out.println("Length: " + output.length());
    }
}

// Usage
JSONStyle customStyle = new JSONStyle(
    JSONStyle.FLAG_PROTECT_KEYS | 
    JSONStyle.FLAG_IGNORE_NULL | 
    JSONStyle.FLAG_PROTECT_4WEB
);

ConfigurationValidator.validateStyleConfiguration(customStyle);
ConfigurationValidator.testStyleOutput(customStyle);

Performance Considerations

Style Selection for Performance

// Fastest serialization - minimal processing
JSONStyle fastest = JSONStyle.MAX_COMPRESS;

// Memory efficient - excludes nulls
JSONStyle memoryEfficient = new JSONStyle(JSONStyle.FLAG_IGNORE_NULL);

// Network efficient - maximum compression + null exclusion
JSONStyle networkEfficient = new JSONStyle(
    JSONStyle.FLAG_AGRESSIVE | JSONStyle.FLAG_IGNORE_NULL
);

// Benchmark different styles
public void benchmarkStyles(Object testData, int iterations) {
    JSONStyle[] styles = {
        JSONStyle.NO_COMPRESS,
        JSONStyle.LT_COMPRESS,
        JSONStyle.MAX_COMPRESS,
        networkEfficient
    };
    
    for (JSONStyle style : styles) {
        long start = System.nanoTime();
        for (int i = 0; i < iterations; i++) {
            String json = JSONValue.toJSONString(testData, style);
        }
        long end = System.nanoTime();
        
        String sample = JSONValue.toJSONString(testData, style);
        System.out.printf("Style: %s, Time: %dms, Size: %d bytes%n",
            style.getClass().getSimpleName(),
            (end - start) / 1_000_000,
            sample.length());
    }
}

Configuration Caching

public class StyleCache {
    private static final Map<String, JSONStyle> STYLE_CACHE = new ConcurrentHashMap<>();
    
    public static JSONStyle getOrCreateStyle(String name, int flags) {
        return STYLE_CACHE.computeIfAbsent(name, k -> new JSONStyle(flags));
    }
    
    // Predefined cached styles
    public static final JSONStyle WEB_API_STYLE = getOrCreateStyle("webApi",
        JSONStyle.FLAG_PROTECT_KEYS | JSONStyle.FLAG_PROTECT_4WEB | JSONStyle.FLAG_IGNORE_NULL);
    
    public static final JSONStyle MOBILE_API_STYLE = getOrCreateStyle("mobileApi",
        JSONStyle.FLAG_AGRESSIVE | JSONStyle.FLAG_IGNORE_NULL);
    
    public static final JSONStyle DEBUG_STYLE = getOrCreateStyle("debug",
        JSONStyle.FLAG_PROTECT_KEYS | JSONStyle.FLAG_PROTECT_VALUES);
}

// Usage
String webJson = JSONValue.toJSONString(data, StyleCache.WEB_API_STYLE);
String mobileJson = JSONValue.toJSONString(data, StyleCache.MOBILE_API_STYLE);

Complete Configuration Examples

REST API Configuration

public class RestApiConfig {
    // Input parsing - strict but allow common relaxations
    private static final int API_PARSER_MODE = 
        JSONParser.MODE_RFC4627 |
        JSONParser.ACCEPT_TAILLING_SPACE |
        JSONParser.USE_INTEGER_STORAGE;
    
    // Output formatting - web-safe and compact
    private static final JSONStyle API_OUTPUT_STYLE = new JSONStyle(
        JSONStyle.FLAG_PROTECT_KEYS |
        JSONStyle.FLAG_PROTECT_4WEB |
        JSONStyle.FLAG_IGNORE_NULL
    );
    
    public static final JSONParser API_PARSER = new JSONParser(API_PARSER_MODE);
    
    public static <T> T parseRequest(String json, Class<T> type) throws ParseException {
        return API_PARSER.parse(json, type);
    }
    
    public static String formatResponse(Object data) {
        return JSONValue.toJSONString(data, API_OUTPUT_STYLE);
    }
}

// Usage
try {
    MyRequest request = RestApiConfig.parseRequest(requestJson, MyRequest.class);
    MyResponse response = processRequest(request);
    String responseJson = RestApiConfig.formatResponse(response);
    return responseJson;
} catch (ParseException e) {
    String errorJson = RestApiConfig.formatResponse(
        Map.of("error", "Invalid JSON", "details", e.getMessage())
    );
    return errorJson;
}

File Processing Configuration

public class FileProcessingConfig {
    // Lenient parsing for user-generated files
    private static final int FILE_PARSER_MODE =
        JSONParser.MODE_PERMISSIVE |
        JSONParser.ACCEPT_SIMPLE_QUOTE |
        JSONParser.ACCEPT_USELESS_COMMA |
        JSONParser.ACCEPT_LEADING_ZERO |
        JSONParser.IGNORE_CONTROL_CHAR;
    
    // Readable output for file generation
    private static final JSONStyle FILE_OUTPUT_STYLE = JSONStyle.NO_COMPRESS;
    
    public static final JSONParser FILE_PARSER = new JSONParser(FILE_PARSER_MODE);
    
    public static Object parseFile(Path filePath) throws IOException, ParseException {
        try (Reader reader = Files.newBufferedReader(filePath)) {
            return FILE_PARSER.parse(reader);
        }
    }
    
    public static void writeFile(Object data, Path filePath) throws IOException {
        try (Writer writer = Files.newBufferedWriter(filePath)) {
            JSONValue.writeJSONString(data, writer, FILE_OUTPUT_STYLE);
        }
    }
}

Configuration Testing Utility

public class ConfigurationTester {
    
    public static void testConfiguration(String name, JSONParser parser, JSONStyle style) {
        System.out.println("Testing configuration: " + name);
        
        // Test various JSON inputs
        String[] testInputs = {
            "{\"valid\": \"json\"}",
            "{'single': 'quotes'}",
            "{\"trailing\": \"comma\",}",
            "{\"leading\": 007}",
            "{\"unicode\": \"\\u0041\"}",
            "{\"null\": null}",
            "{\"number\": 123.456789012345678901234567890}"
        };
        
        for (String input : testInputs) {
            try {
                Object parsed = parser.parse(input);
                String output = JSONValue.toJSONString(parsed, style);
                System.out.printf("  ✓ %s -> %s%n", input, output);
            } catch (ParseException e) {
                System.out.printf("  ✗ %s -> ERROR: %s%n", input, e.getMessage());
            }
        }
        
        System.out.println();
    }
    
    public static void main(String[] args) {
        // Test different configurations
        testConfiguration("Strict Web API",
            new JSONParser(JSONParser.MODE_RFC4627),
            new JSONStyle(JSONStyle.FLAG_PROTECT_KEYS | JSONStyle.FLAG_PROTECT_4WEB));
        
        testConfiguration("Lenient File Processing",
            new JSONParser(JSONParser.MODE_PERMISSIVE),
            JSONStyle.NO_COMPRESS);
        
        testConfiguration("High Performance API",
            new JSONParser(JSONParser.MODE_PERMISSIVE),
            JSONStyle.MAX_COMPRESS);
    }
}

Install with Tessl CLI

npx tessl i tessl/maven-net-minidev--json-smart

docs

configuration.md

core-api.md

customization.md

index.md

navigation.md

parsing.md

tile.json