I have the Jersey JSON POJOMappingFeature turned on in my web.xml as follows to convert POJOs to/from JSON:
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
I have a method in one of the controllers which takes care of file upload. It takes multi-part form data, extracts the file input field from the form, converts it to an InputStream and saves the file to disk:
@POST
@Path("/upload")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces("application/json")
public FileMetaData uploadFiles(FormDataMultiPart formDataMultiPart) {
return new FileUploadHandler(SERVER_FILE_UPLOAD_LOCATION).upload(formDataMultiPart);
}
public FileMetaData upload(FormDataMultiPart formDataMultiPart) {
FormDataBodyPart formFile = formDataMultiPart.getField("files");
ContentDisposition contentDisposition = formFile.getContentDisposition();
return saveFile(formFile.getValueAs(InputStream.class), contentDisposition.getFileName(), formFile.getMediaType().toString());
}
This works well for all file formats except when i try to upload a JSON file, the formFile.getValueAs(InputStream.class) throws an error complaining that a String cannot be converted to InputStream. I assume this is because Jersey automatically converted the JSON file into a string object. So how can I prevent Jersey from doing that just for this method or controller? My requirement is such that I need to have the json file saved as a file itself.
I have tried searching a lot on this but all I end up with is documentation on how to enable POJOMapping but not to selectively disable it. Any help would be very highly appreciated!
UPDATE: My Custom MessageBodyReader looks like the follows:
public class JSONMessageBodyReader implements MessageBodyReader<Object> {
private static final Logger log = LoggerFactory.getLogger(JSONMessageBodyReader.class);
@Override
public boolean isReadable(Class<?> type, Type genericType,
Annotation[] annotations, MediaType mediaType) {
// return true;
return mediaType.isCompatible(MediaType.APPLICATION_JSON_TYPE)
|| mediaType.isCompatible(MediaType.APPLICATION_OCTET_STREAM_TYPE);
|| mediaType.isCompatible(MediaType.TEXT_HTML_TYPE);
}
@Override
public Object readFrom(Class<Object> type, Type genericType,
Annotation[] annotations, MediaType mediaType,
MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
throws IOException, WebApplicationException {
if (log.isTraceEnabled()) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] chunk = new byte[256];
int read = -1;
while ((read = entityStream.read(chunk)) != -1) {
baos.write(chunk, 0, read);
}
chunk = baos.toByteArray();
String entity = new String(chunk);
log.trace("the entity: " + entity);
return ObjectMapperFactory.getInstance().readValue(chunk, 0, chunk.length, type);
}
return ObjectMapperFactory.getInstance().readValue(entityStream, type);
}
}