<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="XContentBuilder xContentBuilder = XContentFactory.contentBuilder(XContentType.JSON);
xContentBuilder.startObject();
xContentBuilder.rawField(&quot;foo&quot;, new BytesArray(&quot;{\&quot;test\&quot;:\&quot;value\&quot;}&quot;));
xContentBuilder.endObject();"><pre class="notranslate"><span class="pl-smi">XContentBuilder</span> <span class="pl-s1">xContentBuilder</span> = <span class="pl-smi">XContentFactory</span>.<span class="pl-en">contentBuilder</span>(<span class="pl-smi">XContentType</span>.<span class="pl-c1">JSON</span>);
<span class="pl-s1">xContentBuilder</span>.<span class="pl-en">startObject</span>();
<span class="pl-s1">xContentBuilder</span>.<span class="pl-en">rawField</span>(<span class="pl-s">"foo"</span>, <span class="pl-k">new</span> <span class="pl-smi">BytesArray</span>(<span class="pl-s">"{<span class="pl-s">\"</span>test<span class="pl-s">\"</span>:<span class="pl-s">\"</span>value<span class="pl-s">\"</span>}"</span>));
<span class="pl-s1">xContentBuilder</span>.<span class="pl-en">endObject</span>();</pre></div>
<p dir="auto">results in the following string:</p>
<div class="highlight highlight-source-json notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="{,&quot;foo&quot;:{&quot;test&quot;:&quot;value&quot;}}"><pre class="notranslate">{,<span class="pl-ent">"foo"</span>:{<span class="pl-ent">"test"</span>:<span class="pl-s"><span class="pl-pds">"</span>value<span class="pl-pds">"</span></span>}}</pre></div>
<p dir="auto">I often use the <code class="notranslate">XContentBuilder.rawField</code> method to append my own JSON objects or arrays to the builder. Nonetheless, I found something quite annoying: a comma is always prepend when adding a new raw field, whatever it is the first field or not. The JsonXContentGenerator.writeRawField methods [1] seems to confirm that.</p>
<p dir="auto">This leads to malformed JSONs, for instance:</p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="    @Test
    public void rawFieldBug() throws IOException {
        XContentBuilder factory = XContentFactory.jsonBuilder().startObject()
                .rawField(&quot;myfield&quot;, &quot;{}&quot;.getBytes())
                .endObject();
        String json = factory.string();
        Assert.assertEquals(&quot;{\&quot;myfield\&quot;:{}}&quot;, json);
        // returns &gt;{, &quot;myfield&quot; : {}}&lt; instead
    }"><pre class="notranslate">    <span class="pl-c1">@</span><span class="pl-c1">Test</span>
    <span class="pl-k">public</span> <span class="pl-smi">void</span> <span class="pl-s1">rawFieldBug</span>() <span class="pl-k">throws</span> <span class="pl-s1">IOException</span> {
        <span class="pl-smi">XContentBuilder</span> <span class="pl-s1">factory</span> = <span class="pl-smi">XContentFactory</span>.<span class="pl-en">jsonBuilder</span>().<span class="pl-en">startObject</span>()
                .<span class="pl-en">rawField</span>(<span class="pl-s">"myfield"</span>, <span class="pl-s">"{}"</span>.<span class="pl-en">getBytes</span>())
                .<span class="pl-en">endObject</span>();
        <span class="pl-smi">String</span> <span class="pl-s1">json</span> = <span class="pl-s1">factory</span>.<span class="pl-en">string</span>();
        <span class="pl-smi">Assert</span>.<span class="pl-en">assertEquals</span>(<span class="pl-s">"{<span class="pl-s">\"</span>myfield<span class="pl-s">\"</span>:{}}"</span>, <span class="pl-s1">json</span>);
        <span class="pl-c">// returns &gt;{, "myfield" : {}}&lt; instead</span>
    }</pre></div>
<p dir="auto">This bug was seen in the 0.90.RC2 elasticsearch version.</p>
<p dir="auto">PS: In addition, a <code class="notranslate">rawField(String fieldName, String content)</code> (with potentially validation) might be very nice for such use cases :)</p>
<p dir="auto">[1] Extracted form <code class="notranslate">org.elasticsearch.common.xcontent.json.JsonXContentGenerator</code></p>
<div class="highlight highlight-source-java notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="    @Override
    public void writeRawField(String fieldName, byte[] content, OutputStream bos) throws IOException {
        generator.writeRaw(&quot;, \&quot;&quot;); // &lt;= here?!
        generator.writeRaw(fieldName);
        generator.writeRaw(&quot;\&quot; : &quot;);
        flush();
        bos.write(content);
    }"><pre class="notranslate">    <span class="pl-c1">@</span><span class="pl-c1">Override</span>
    <span class="pl-k">public</span> <span class="pl-smi">void</span> <span class="pl-s1">writeRawField</span>(<span class="pl-smi">String</span> <span class="pl-s1">fieldName</span>, <span class="pl-smi">byte</span>[] <span class="pl-s1">content</span>, <span class="pl-smi">OutputStream</span> <span class="pl-s1">bos</span>) <span class="pl-k">throws</span> <span class="pl-s1">IOException</span> {
        <span class="pl-s1">generator</span>.<span class="pl-en">writeRaw</span>(<span class="pl-s">", <span class="pl-s">\"</span>"</span>); <span class="pl-c">// &lt;= here?!</span>
        <span class="pl-s1">generator</span>.<span class="pl-en">writeRaw</span>(<span class="pl-s1">fieldName</span>);
        <span class="pl-s1">generator</span>.<span class="pl-en">writeRaw</span>(<span class="pl-s">"<span class="pl-s">\"</span> : "</span>);
        <span class="pl-en">flush</span>();
        <span class="pl-s1">bos</span>.<span class="pl-en">write</span>(<span class="pl-s1">content</span>);
    }</pre></div>