Our servlets send JSON (with "Content-Type: text/html" though, so that
the SubmitCompleteEvent is reliably fired...) and we then parse
e.getResults() on client-side.
We're using JSON for all our server responses so the FormPanel
integrates quite well with our other code based on RequestBuilder
(you'd have guess: we don't use GWT-RPC).
The issue you'll face with FormPanel (compared to RequestBuilder) is
that there's no "error handler" (no onError / onFailure) and you
cannot get the response status code either (as in
Response.getStatusCode() when using RequestBuilder). So your server
has to generate JSON (with content-type: text/html) to convey errors
too, and your client code has to inspect the returned JSON to
determine whether it's a success or failure.
Our servlets in case or error always return a JSON object (we call it
"status object") with the same properties ("statusCode", "message",
etc.) mimicking HTTP-level information, and we baked the handling of
the response in a common SubmitCompleteHandler wrapped around a
RequestCallback/AsyncCallback-like callback (it parses the JSON, looks
for "statusCode" and "message" properties; if they're present and
"statusCode >= 400", then it calls the callback.onError(statusObject),
otherwise it calls callback.onSuccess(parsedJsonObject)).