Skip to content

Commit 3d1437a

Browse files
authored
Update java-extension.md
1 parent 8b26614 commit 3d1437a

File tree

1 file changed

+42
-2
lines changed

1 file changed

+42
-2
lines changed

java-extension.md

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,7 +311,7 @@ public class CustomizedSetter {
311311

312312
The setter parameters, constructor parameters and fields are all just bindings. Those bindings can be updated by extension, to change data source and decoder.
313313

314-
# Full extension interface
314+
# Extension & Iterator
315315

316316
```
317317
public interface Extension {
@@ -357,4 +357,44 @@ To summary it up, you have these options:
357357
* the setters to use, and the parameter binding of setters
358358
* all bindings (fields, setter parameters, constructor parameters) can change data source (even map to multiple fields) and change decoder
359359

360-
Also the decoder interface is powered with iterator-api to iterate on the lowest level. I believe all the flexibility you will ever need
360+
Also the decoder interface is powered with iterator-api to iterate on the lowest level. I believe this should provide all the flexibility you will ever need. If you are still not on board, here is another shot.
361+
362+
There is a feature flag of jackson called `ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT`. The intention is to decode input like `[]` as null, as PHP might treat empty object as empty array. To support this feature, we can register a extension
363+
364+
```
365+
JsonIterator.registerExtension(new EmptyExtension() {
366+
@Override
367+
public Decoder createDecoder(final String cacheKey, final Type type) {
368+
if (cacheKey.endsWith(".original")) {
369+
// avoid infinite loop
370+
return null;
371+
}
372+
if (type != Date.class) {
373+
return null;
374+
}
375+
return new Decoder() {
376+
@Override
377+
public Object decode(JsonIterator iter) throws IOException {
378+
if (iter.whatIsNext() == ValueType.ARRAY) {
379+
if (iter.readArray()) {
380+
// none empty array
381+
throw iter.reportError("decode [] as null", "only empty array is expected");
382+
} else {
383+
return null;
384+
}
385+
} else {
386+
// just use original decoder
387+
TypeLiteral typeLiteral = TypeLiteral.create(type, "original");
388+
return iter.read(typeLiteral);
389+
}
390+
}
391+
};
392+
}
393+
});
394+
JsonIterator iter = JsonIterator.parse("[]");
395+
assertNull(iter.read(Date.class));
396+
```
397+
398+
Using iterator we can detect if input is `[]`, and act accordingly. If input is not array, we can even fallback to default behavior. It works like servlet filter, if one decoder can not handle it, it can fallback to the next one.
399+
400+

0 commit comments

Comments
 (0)