class JsonFileItemWriter<T> extends AbstractFileItemWriter<T> {

	private static final char JSON_OBJECT_SEPARATOR = ',';

	private static final char JSON_ARRAY_START = '[';

	private static final char JSON_ARRAY_STOP = ']';

	private JsonObjectMarshaller<T> jsonObjectMarshaller;

	/**
	 * Create a new {@link JsonFileItemWriter} instance.
	 * @param resource to write json data to
	 * @param jsonObjectMarshaller used to marshal object into json representation
	 */
	public JsonFileItemWriter(WritableResource resource, JsonObjectMarshaller<T> jsonObjectMarshaller) {
		Assert.notNull(resource, "resource must not be null");
		Assert.notNull(jsonObjectMarshaller, "json object marshaller must not be null");
		setResource(resource);
		setJsonObjectMarshaller(jsonObjectMarshaller);
		setHeaderCallback(writer -> writer.write(JSON_ARRAY_START));
		setFooterCallback(writer -> writer.write(this.lineSeparator + JSON_ARRAY_STOP + this.lineSeparator));
		setExecutionContextName(ClassUtils.getShortName(JsonFileItemWriter.class));
	}

	/**
	 * Assert that mandatory properties (jsonObjectMarshaller) are set.
	 *
	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
	 */
	@Override
	public void afterPropertiesSet() throws Exception {
		if (this.append) {
			this.shouldDeleteIfExists = false;
		}
	}

	/**
	 * Set the {@link JsonObjectMarshaller} to use to marshal object to json.
	 * @param jsonObjectMarshaller the marshaller to use
	 */
	public void setJsonObjectMarshaller(JsonObjectMarshaller<T> jsonObjectMarshaller) {
		this.jsonObjectMarshaller = jsonObjectMarshaller;
	}

	@Override
	public String doWrite(Chunk<? extends T> items) {<FILL_FUNCTION_BODY>}

}

		StringBuilder lines = new StringBuilder();
		Iterator<? extends T> iterator = items.iterator();
		if (!items.isEmpty() && state.getLinesWritten() > 0) {
			lines.append(JSON_OBJECT_SEPARATOR).append(this.lineSeparator);
		}
		while (iterator.hasNext()) {
			T item = iterator.next();
			lines.append(' ').append(this.jsonObjectMarshaller.marshal(item));
			if (iterator.hasNext()) {
				lines.append(JSON_OBJECT_SEPARATOR).append(this.lineSeparator);
			}
		}
		return lines.toString();
	
<methods>public non-sealed void <init>() ,public void close() ,public void open(org.springframework.batch.item.ExecutionContext) throws org.springframework.batch.item.ItemStreamException,public void setAppendAllowed(boolean) ,public void setEncoding(java.lang.String) ,public void setFooterCallback(org.springframework.batch.item.file.FlatFileFooterCallback) ,public void setForceSync(boolean) ,public void setHeaderCallback(org.springframework.batch.item.file.FlatFileHeaderCallback) ,public void setLineSeparator(java.lang.String) ,public void setResource(org.springframework.core.io.WritableResource) ,public void setSaveState(boolean) ,public void setShouldDeleteIfEmpty(boolean) ,public void setShouldDeleteIfExists(boolean) ,public void setTransactional(boolean) ,public void update(org.springframework.batch.item.ExecutionContext) ,public void write(Chunk<? extends T>) throws java.lang.Exception<variables>public static final java.lang.String DEFAULT_CHARSET,public static final java.lang.String DEFAULT_LINE_SEPARATOR,public static final boolean DEFAULT_TRANSACTIONAL,private static final java.lang.String RESTART_DATA_NAME,private static final java.lang.String WRITTEN_STATISTICS_NAME,protected boolean append,private java.lang.String encoding,private org.springframework.batch.item.file.FlatFileFooterCallback footerCallback,private boolean forceSync,private org.springframework.batch.item.file.FlatFileHeaderCallback headerCallback,protected java.lang.String lineSeparator,protected static final org.apache.commons.logging.Log logger,private org.springframework.core.io.WritableResource resource,private boolean saveState,private boolean shouldDeleteIfEmpty,protected boolean shouldDeleteIfExists,protected OutputState state,private boolean transactional