Jersey:Returning a Response with a Map containing Image Files and JSON String values - image

I am using Jersey JAX-RS.
I want to return a Response with a Map containing Image Files and JSON String values.
Is this the right way to do this:
Map<String,Object> map = new HashMap........
GenericEntity entity = new GenericEntity<Map<String,Object>>(map) {};
return Response.ok(entity).build();
Or is this better.I plan to use JAX-RS with Jersey only.
JResponse.ok(map).build();
I am basing this on this article:
http://aruld.info/handling-generified-collections-in-jersey-jax-rs/
I am not sure what to specify for #Produces too(planning to leave it out).
TIA,
Vijay

You better produce a multipart response:
import static com.sun.jersey.multipart.MultiPartMediaTypes.MULTIPART_MIXED_TYPE;
import static javax.ws.rs.core.MediaType.APPLICATION_XML_TYPE
#GET
#Produces(MULTIPART_MIXED_TYPE)
public Response get()
{
FileDataSource image = ... (gets the image file)
String info = ... (gets the xml structured information)
MultiPart multiPart = new MultiPart().
bodyPart(new BodyPart(info, APPLICATION_XML_TYPE)).
bodyPart(new BodyPart(image, new MediaType("image", "png")));
return Response.ok(multiPart, MULTIPART_MIXED_TYPE).build();
}
This example was taken from there.

Related

Documenting possible values for Map in Swagger

I have a JAX-RS method which takes a Map to facilitate a partial update.
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
#Path("/{id}/edit")
public Response edit(HashMap<String, Object> data)
I can't use Patch, long story.
I need to document what parameters are possible for client to send up so they can see them in swagger UI. One way to do this is to use #ApiImplicitParam
#ApiImplicitParams({
#ApiImplicitParam(name = "payload", value = "payload", required = true, dataType = "com.me.PartialUpdatePerson", paramType = "body"),
})
This is a nice work around. PartialUpdatePerson is a class which contains the various parameters allowed to be sent up.
The problem is in the swagger UI, it still shows me the body with the map. Sample value is:
{
"additionalProp1": {},
"additionalProp2": {},
"additionalProp3": {}
}
as well as the payload.
Is there anyway, I can tell swagger, not to show this? i.e. to ignore the HashMap data from a doc perspective? I am not using Spring so #ApiIgnore is not possible.
Thanks
public Response edit(#ApiParam(hidden = true) HashMap<String, Object> data)

How to mock a multipart file upload when using Spring and Apache File Upload

The project I'm working on needs to support large file uploads and know the time taken during their upload.
To handle the large files I'm using the streaming API of Apache FileUpload, this also allows me to measure the time taken for the complete stream to be saved.
The problem I'm having is that I cannot seem to be able to utilise MockMvc in an Integration Test on this controller. I know that the controller works as I've successfully uploaded files using postman.
Simplified Controller Code:
#PostMapping("/upload")
public String handleUpload(HttpServletRequest request) throws Exception {
ServletFileUpload upload = new ServletFileUpload();
FileItemIterator iterStream = upload.getItemIterator(request);
while (iterStream.hasNext()) {
FileItemStream item = iterStream.next();
String name = item.getFieldName();
InputStream stream = item.openStream();
if (!item.isFormField()) {
// Process the InputStream
} else {
String formFieldValue = Streams.asString(stream);
}
}
}
Simplified Test Code:
private fun uploadFile(tfr: TestFileContainer) {
val mockFile = MockMultipartFile("file", tfr.getData()) // .getData*() returns a ByteArray
val receiveFileRequest = MockMvcRequestBuilders.multipart("/upload")
.file(mockFile)
.contentType(MediaType.MULTIPART_FORM_DATA)
val result = mockMvc.perform(receiveFileRequest)
.andExpect(status().isCreated)
.andExpect(header().exists(LOCATION))
.andReturn(
}
This is the error I'm currently getting
org.apache.tomcat.util.http.fileupload.FileUploadException: the
request was rejected because no multipart boundary was found
Can anyone help?
The MockMultipartFile approach won't work as Spring does work behind the scenes and simply passes the file around.
Ended up using RestTemplate instead as it actually constructs requests.

Spring Multipart File with #RequestBody

I am trying to upload data from an app to a spring backend service.
Things to upload are a DataModel containing data of the object to create and several images linked to the data.
Therefore I am using this method signature:
#RequestMapping(method = RequestMethod.POST)
#ResponseBody
public Survey createSurvey(#RequestBody SurveyPostHelper helper, #RequestParam(value="file", required = true) MultipartFile[] images)
I tried to play with the annotations, but either I get a blank images array or my helper is empty.
How would you solve this?
Thanks in advance.
I found out, that this method signature could do the job:
#ResponseBody
public Survey createSurvey(#RequestPart(required=true) SurveyPostHelper helper, #RequestPart(value="file", required = true) final MultipartFile[] images)
Important in my case was to set the MimeType in the client app. The files MimeType should be image/jpg and the SurveyPostHelpers to application/json to allow Spring to parse the json and bind it to my Object.
see an example of the client code working for me images is the list of files I want to save
var formData = new FormData();
for (var i = 0; i < images.length ; i++) {
formData.append('images', images[i]);
}
formData.append('adData', new Blob([JSON.stringify(adData)], {
type: "application/json"
}));

Globally formatting .net Web Api response

I have a Web Api service that retrieves data from another service, which returns Json. I don't want to do anything to the response, I just want to return it directly to the client.
Since the response is a string, if I simply return the response, it contains escape characters and messy formatting. If I convert the response in to an object, the WebApi will use Json.Net to automatically format the response correctly.
public IHttpActionResult GetServices()
{
var data = _dataService.Get(); //retrieves data from a service
var result = JsonConvert.DeserializeObject(data); //convert to object
return Ok(result);
}
What I would like is to either A: Be able to return the exact string response from the service, without any of the escape characters and with the proper formatting, or B: Set a global settings that will automatically Deserialize the response so that the Web Api can handle it the way I am doing it already.
On Startup I am setting some values that describe how formatting should be handled, but apparently these aren't correct for what im trying to do.
HttpConfiguration configuration = new HttpConfiguration();
var settings = configuration.Formatters.JsonFormatter.SerializerSettings;
settings.Formatting = Formatting.Indented;
settings.ContractResolver = new DefaultContractResolver();
Do I need to create a custom ContractResolver or something? Is there one that already handles this for me?
Thanks
If you want to just pass through the json (Option A), you can do this
public IHttpActionResult GetServices() {
var json = _dataService.Get(); //retrieves data from a service
HttpContent content = new System.Net.Http.StringContent(json, Encoding.UTF8, "application/json");
var response = Request.CreateResponse(HttpStatusCode.OK);
response.Content = content;
return ResponseMessage(response);
}

How do I pass the result from httpget to SAX parser

I'm want to make a request to google API and pass the resulting XML to SAX parser here are both codes...
First the request:
HttpClient hclient = new DefaultHttpClient();
HttpGet get = new HttpGet("http://www.google.com/ig/api?weather=Cardiff");
HttpResponse hrep = hclient.execute(get);
HttpEntity httpEntity = hrep.getEntity();
Then the parser:
SAXParserFactory saxpf = SAXParserFactory.newInstance();
SAXParser saxp = saxpf.newSAXParser();
XMLReader xr = saxp.getXMLReader();
ExHandler myHandler = new ExHandler();
xr.setContentHandler(myHandler);
xr.parse();
Is this the right way to do this and how do I connect both codes.
Thanks in advance
The SAXParser object can take in an input stream and the handler. So something like:
SAXParser saxParser = factory.newSAXParser();
XMLParser parser = new XMLParser();
saxParser.parse(httpEntity.getContent(),parser);
The getContent() method returns and input stream from the HttpRequest, and the XMLParser object is just a class I created (supposedly) that contains the definition of how to parse the XML.
EDIT*
You really should read the entire API for SAXParser, it has several overloaded methods:
void parse(InputSource is, DefaultHandler dh)
Parse the content given InputSource as XML using the specified DefaultHandler.
void parse(InputSource is, HandlerBase hb)
Parse the content given InputSource as XML using the specified HandlerBase.
void parse(InputStream is, DefaultHandler dh)
Parse the content of the given InputStream instance as XML using the specified DefaultHandler.
void parse(InputStream is, DefaultHandler dh, String systemId)
Parse the content of the given InputStream instance as XML using the specified DefaultHandler.
void parse(InputStream is, HandlerBase hb)
Parse the content of the given InputStream instance as XML using the specified HandlerBase.
void parse(InputStream is, HandlerBase hb, String systemId)
Parse the content of the given InputStream instance as XML using the specified HandlerBase.
Some of the methods take an InputSource, some take an InputStream, as I stated earlier.

Resources