can we get filename from byteArrayResource? - java

It's about uploading xlsx file. Initially im getting xlsx file as javax.servlet.http.Part and trying to convert as ByteArrayResource Since i need to pass via RestTemplate.
new ByteArrayResource(IOUtils.toByteArray(input.getFile().getInputStream())
Here input.getFile() is javax.servlet.http.Part
As im converting here into ByteArrayResource and sending back to another Layer for business logic, can i get filename from ByteArrayResource ?
Anyhow we can get filename from Part, I want to know is that possible to get filename from ByteArrayResource or ByteArray ?

This is late but if anyone is still looking for an answer.
ByteArrayResource doesn't have any filename by default. See the super class method AbstractResource.getFileName(), it returns null. So until you set the name explicitly while creating ByteArrayResource, it will remain null.
You can achieve this like
ByteArrayResource resource = new ByteArrayResource(bytearray) {
#Override
public String getFilename() {
return "somename";
};
}
Now how to use the actual file name instead of "somename". If you're using Spring, you can define a method in your controller accepting Multipart as an argument.
public ResponseEntity<byte[]> handleFileOperation(Multipart file) {}
Once you get the MultipartFile instance, you can use it the way you want.

You'll probably need to use FileNameAwareByteArrayResource as outlined in Spring-boot MultipartFile issue with ByteArrayResource.
You'll be able to get the filename from it then.

Related

How can we pass header information to a JsonDataSource?

We are using REST endpoint as datasource for jasper reports, but everywhere using REST point its mandatory to create an adapter with rest url and header info and use that as datasource.
We don't want to use adapter, instead we want to use directly the constructor
public JsonDataSource(String location, String selectExpression) throws JRException
as a dataset expression so we formed expression as follow.
new net.sf.jasperreports.engine.data.JsonDataSource("http://vagrant.ptcnet.ptc.com:2280/Windchill/trustedAuth/servlet/odata/D...","value")
However this particular endpoint expects some header information from requestor ("Accept", "application/json") else it throws bad exception as error
Is there any way we can pass header info here?
You need to use the constructor where you pass a InputStream
public JsonDataSource​(java.io.InputStream jsonStream,java.lang.String selectExpression)
The easiest way to provide the input stream is probably to create a method within your java project that execute the request and returns the result in for example a ByteArrayInputStream
If you need to do it directly within the report (jrxml) you need to do it in 1 expression (jrxml do not support multi-line code). In this case you could the apache HttpClients that already is included as dependency of the jasper report project.
It could be something like this
new net.sf.jasperreports.engine.data.JsonDataSource(
org.apache.http.impl.client.HttpClients.createDefault().execute(
org.apache.http.client.methods.RequestBuilder.
get().
setUri("http://vagrant.ptcnet.ptc.com:2280/Windchill/trustedAuth/servlet/odata/D...").
setHeader("Accept", "application/json").
build()
)
.getEntity()
.getContent()
,""
)
The getContent() will return the InputStream and jasper reports will close this stream when it is done. However both the client and the execute response are theoretically Closable which means that normally you should call close() to free up resource, hence I'm not sure that it is enough to close only the InputStream, you may risk leaking of resource. This is why I initially suggested to create a method within the/a java project where this can be handled appropriately.

How to serve same static .html file for all dynamic urls using Play framework and Java?

I am trying to serve a static html file let's call it index.html for all dynamic urls like /tachyon/someId. This someId is generated dynamically. I have tried multiple ways to do this but all failed. This is what all I have tried.
Tried adding controllers.Assets.at(path="/public", file="index.html") for GET url /tachyon/*someId. This failed saying missing parameter someId.
Tried rendering index.html through render. This also failed since index.html is not a scala.html template.
Tried returning routes.Assets.at("index.html") through controller. This also failed since I want to return Result but the return type for the method is different.
Tried returning ok(routes.Assets.at("index.html") through controller. This also failed saying not a valid Call for ok.
It would be better if there is a way to do this through controller and returning Result from method in task helper class to task since I am returning Promise<Result> from method in task class.
I think you can use Twirl to generate the page. Since you want a static html, you can ignore the parameter in the body.
so in routes, add:
GET /tachyon/*someId somecontroller.index(someId)
in the controller's index function, you can return
Ok(views.html.somepage(someId))
And you create a somepage.scala.html Twirl function in views folder, but do not use someId in the body.
I got it working. Not sure if it is the correct solution or not. I rendered the index.html by converting it to a byte array and then using ok to render using ByteArrayInputStream. Something like this.
File file = Play.getFile("path to the file", Play.current());
byte[] byteArray = IOUtils.toByteArray(new FileInputStream(file));
return ok(new ByteArrayInputStream(byteArray)).as("text/html");
Let me know if there is any better way to do this without using scala templating.
Thanks

How can I work with a .csv file using Java Spring Resttample?

I have a small problem concerning using a .csv file with the Resttemplate from java spring.
It looks somehow like:
URL url = URL url = new URL("http://data.wien.gv.at/daten/geo?service=WFS&version=1.0.0&request=GetFeature&typeName=ogdwien:GEONAMENSVERZOGD&outputFormat=CSV");
RestTemplate restTemplate = new RestTemplate();
Late on I want to use the getForObject() Method by the restTemplate, but I down't know how to proceed since I can't find matching paramteres anywehere on the internet.
Thank you for your help!
First, you'll need a CSV parsing library such as SuperCSV or OpenCSV.
Second you can add a HttpMessageConverter to Spring to convert csv input to java objects.
http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/http/converter/HttpMessageConverter.html
Having that set up, you'll be able to getForObject and get java objects directly.

Jersey Post request - How to perform a file upload with an unknown number of additional parameters?

I asked something like this previously, but upon re-reading my original post, it was not easy to understand what I was really asking. I have the following situation. We have (or at least I'm trying to get working) a custom file upload procedure that will take in the file, a set number of 'known' metadata values (and they will always be there), as well as potentially an unknown number of additional metadata values. The service that exists currently uses the Jersey framework (1.16)
I currently have both client and server code that handles dealing with the file upload portion and the known metadata values (server code below)
#POST
#Path("asset/{obfuscatedValue0}/")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public UUID uploadBlob(#PathParam("obfuscatedValue0") Integer obfuscatedValue0,
#FormDataParam("obfuscatedValue1") String obfuscatedValue1,
#FormDataParam("obfuscatedValue2") String obfuscatedValue2,
#FormDataParam("obfuscatedValue3") String obfuscatedValue3,
#FormDataParam("obfuscatedValue4") String obfuscatedValue4,
#FormDataParam("obfuscatedValue5") String obfuscatedValue5,
#FormDataParam("file") InputStream uploadedInputStream) {
.....
}
...and excerpt of client code:
Builder requestBuilder = _storageService
.path("asset")
.path(obfuscatedValue0.toString())
.type(MediaType.MULTIPART_FORM_DATA)
.accept(MediaType.APPLICATION_JSON);
FormDataMultiPart part = new FormDataMultiPart()
.field("file", is, MediaType.TEXT_PLAIN_TYPE) // 'is' is an inputstream from earlier in code.
.field("obfuscatedValue1", obfuscatedValue1)
.field("obfuscatedValue2", obfuscatedValue2)
.field("obfuscatedValue3", obfuscatedValue3)
.field("obfuscatedValue4", obfuscatedValue4)
.field("obfuscatedValue5", obfuscatedValue5);
storedAsset = requestBuilder.post(UUID.class, part);
However, I need to pass a map of additional parameters that will have an unknown number of values/names. From what I've seen, there is no easy way to do this using the FormDataParam annotation like my previous example.
Based upon various internet searches related to Jersey file uploads, I've attempted to convert it to use MultivaluedMap with the content type set to "application/x-www-form-urlencoded" so it resembles this:
#POST
#Path("asset/{value}/")
#Consumes("application/x-www-form-urlencoded")
public UUID uploadBlob(#PathParam(value), MultivaluedMap<String,String> formParams) {
....
}
It's my understanding that MultivaluedMap is intended to obtain a general map of form parameters (and as such, cannot play nicely together in the same method bearing #FormDataParam annotations.) If I can pass all this information from the Client inside some sort of map, I think I can figure out how to handle parsing the map to grab and 'doMagic()' on the data to get what I want done; I don't think I'll have a problem there.
What I AM fairly confused about is how to format the request client-side code when using this second method within the jersey framework. Can anyone provide some guidance for the situation, or some suggestions on how to proceed? I'm considering trying the solution proposed here and developing a custom xml adapter to deal with this situation, and sending xml instead of multipart-form-data but I'm still confused how this would interact with the InputStream value that will need to be passed. It appears the examples with MultivaluedMap that I've seen only deal with String data.

spring file download using ResponseBody

Hello i'm trying create an application allowing me host any kind of file.
In order to do it i'm exececuting following magic:
#RequestMapping(value = "/files/{file_name}", method = RequestMethod.GET)
#ResponseBody
public FileSystemResource
getFile(
#PathVariable("file_name") String fileName) {
System.out.println(fileName);
String filePath = "./files/";
return new FileSystemResource(new File(filePath+fileName));
}
But this approach brings three unwanted problems:
Some random data is beeing appended to the file
The file gets opened in the browser window instead of beeing
downloaded - i've tried to hack this using something like
produces = "application/octet-stream"
but it only resulted in 406 error.
The test.txt is beeing truncated into test, i found a walkaround in providing the app with test.txt/ as fileName but it looks a bit messy.
As stated on spring manual
As with #RequestBody, Spring converts the returned object to a
response body by using an HttpMessageConverter
I think your problem is spring doesn't come with a HttpMessageConverter than can process FileSystemResource.
A list of builtin HttpMessageConverter is available here. I suggest you try converting your response into byte array somehow, maybe it will pick ByteArrayHttpMessageConverter instead and help solve your issue
I used code like this to return image
#RequestMapping(value = "/image/{id}", method = RequestMethod.GET)
public String getImage(... HttpServletResponse response) {
response.setContentType(image/png);
(response.getOutputStream()).write(imageByteArray);
}
I think you have to define proper mime type and send your data to response.

Categories