{8.1.0-updated,8.2.0-updated} Swaps

{@link oaj.transform.PojoSwap Swaps} are a critical component of Juneau. They allow the serializers and parsers to handle Java objects that wouldn't normally be serializable.

Swaps are, simply put, 'object swappers' that swap in serializable objects for non-serializable ones during serialization, and vis-versa during parsing.

Some examples of non-serializable POJOs are File, Reader, Iterable, etc... These are classes that aren't beans and cannot be represented as simple maps, collections, or primitives.

In the following example, we introduce a PojoSwap that will swap in a bean of a particular type with a map containing customized key-value pairs:

// Sample swap for converting a bean to a specialized map of key-value pairs. public class MyBeanSwap extends PojoSwap<MyBean,OMap> { // Converts a bean to a generic map. @Override /* PojoSwap */ public OMap swap(BeanSession session, MyBean bean) { return OMap.of("foo", bean.getBar()); } // Converts the generic map back into a bean. @Override /* PojoSwap */ public MyBean unswap(BeanSession session, OMap omap, ClassMeta<?> hint) throws Exception { MyBean bean = new MyBean(); bean.setBar(omap.getString("foo")); return bean; } }

The swap can then be associated with serializers and parsers like so:

// Create a new JSON serializer with our swap. WriterSerializer serializer = JsonSerializer.create().simple().swaps(MyBeanSwap.class).build(); String json = serializer.serialize(new MyBean()); // Create a JSON parser with our swap. ReaderParser parser = JsonParser.create().swaps(MyBeanSwap.class).build(); MyBean bean = parser.parse(json, MyBean.class);

Another example of a PojoSwap is one that converts byte[] arrays to BASE64-encoded strings:

public class ByteArrayBase64Swap extends StringSwap<byte[]> { @Override /* StringSwap */ public String swap(byte[] bytes) throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); OutputStream b64os = MimeUtility.encode(baos, "base64"); b64os.write(bytes); b64os.close(); return new String(baos.toByteArray()); } @Override /* StringSwap */ public byte[] unswap(String string, ClassMeta<?> hint) throws Exception { byte[] bytes = string.getBytes(); ByteArrayInputStream bais = new ByteArrayInputStream(bytes); InputStream b64is = MimeUtility.decode(bais, "base64"); byte[] tmp = new byte[bytes.length]; int n = b64is.read(tmp); byte[] res = new byte[n]; System.arraycopy(tmp, 0, res, 0, n); return res; } }

The following example shows the BASE64 swap in use:

// Create a JSON serializer and register the BASE64 encoding swap with it. WriterSerializer serializer = JsonSerializer.create().simple().swaps(ByteArrayBase64Swap.class).build(); ReaderParser parser = JsonParser.create().swaps(ByteArrayBase64Swap.class).build(); byte[] bytes = {1,2,3}; String json = serializer.serialize(bytes); // Produces "'AQID'" bytes = parser.parse(json, byte[].class); // Reproduces {1,2,3} byte[][] bytes2d = {{1,2,3},{4,5,6},null}; json = serializer.serialize(bytes2d); // Produces "['AQID','BAUG',null]" bytes2d = parser.parse(json, byte[][].class); // Reproduces {{1,2,3},{4,5,6},null}