I'm trying to generate a PDF document using FOP. The pdf generation code is kept in a servlet and the xsl is in a specific folder in the WebContent folder.
How can I access this xsl file by giving a relative path? It works only if I give the complete path in the File object.
I need to generate the xml content dynamically. How can I give this dynamically generated xml as the source instead of a File object?
Please provide your suggestions.
To get the path you can just do:
String path = s.getServletContext().getRealPath("/WEB-INF/somedir/hdfeeh");
s is the class that implements HTTPServlet.You can also use this.getServletContext() if its your servlet class.
Then pass this as a parameter.
As far as using dynamically generated XML, the library you're using should support using an input stream, write your XML, convert it to a byte array, then wrap it in a ByteArrayInputStream and use this.
For a direct and independent container implementation, you can access the resourcewith the following method getResource() inside your servlet:
/start servlet/
public InputStream getResource(String resourcePath) {
ServletContext servletContext = getServletContext();
InputStream openStream = servletContext.getResourceAsStream( resourcePath );
return openStream;
}
public void testConsume() {
String path = "WEB-INF/teste.log";
InputStream openStream = getResource( path );
int c = -1;
byte[] bb = new byte[1024];
while ( -1 != ( c = openStream.read( bb ) ) ) {
/* consume stream */
}
openStream.close();
}
/end servlet/
I used the following method to read the file under web content
BufferedReader reader = new BufferedReader(new InputStreamReader(request.getSession().getServletContext().getResourceAsStream("/json/sampleJson.json")));
Now all the file content is available in the reader object.
Related
Hello im trying to do something like this:
private Byte[] getImage() throws IOException {
String imageUrl = ServletContext.class.getClassLoader()
.getResource("static/anImage.jpg")
.getFile();
Byte[] byteObject = new Byte[imageUrl.getBytes().length];
int i = 0;
for (Byte b : imageUrl.getBytes()){
byteObject[i++] = b;
}
return byteObject;
}
But it's wrong. So how to pick up a file from specific directory? Thanks.
ps.
I can do something like this:
File file = new File("image.jpg");
byte[] content = Files.readAllBytes(file.toPath());
But still its a path only from the main folder. Dont know how to program for the resources/images folder.
In Spring you can use Resources to achieve your goal:
Resource resource = new ClassPathResource("static/anImage.jpg");
byte[] bytes = resource.getInputStream().readAllBytes();
Don't reinvent the wheel and use e.g. Apache Commons for convert a File to byte array. Read more FileUtils.readFileToByteArray(File input)
The way you loading resources seems to be the proper one.
Ensure that the loaded file is in proper location (src/main/resources).
Do you have any particular error or stack trace which describes the issue.
I have a spring boot application and I am trying to merge two pdf files. The one I am getting as a byte array from another service and the one I have it locally in my resources file: /static/documents/my-file.pdf. This is the code of how I am getting byte array from my file from resources:
public static byte[] getMyPdfContentForLocale(final Locale locale) {
byte[] result = new byte[0];
try {
final File myFile = new ClassPathResource(TEMPLATES.get(locale)).getFile();
final Path filePath = Paths.get(myFile.getPath());
result = Files.readAllBytes(filePath);
} catch (IOException e) {
LOGGER.error(format("Failed to get document for local %s", locale), e);
}
return result;
}
I am getting the file and getting the byte array. Later I am trying to merge this two files with the following code:
PDFMergerUtility pdfMergerUtility = new PDFMergerUtility();
pdfMergerUtility.addSource(new ByteArrayInputStream(offerDocument));
pdfMergerUtility.addSource(new ByteArrayInputStream(merkblattDocument));
ByteArrayOutputStream os = new ByteArrayOutputStream();
pdfMergerUtility.setDestinationStream(os);
pdfMergerUtility.mergeDocuments(null);
os.toByteArray();
But unfortunately it throws an error:
throw new IOException("Page tree root must be a dictionary");
I have checked and it makes this validation before it throws it:
if (!(root.getDictionaryObject(COSName.PAGES) instanceof COSDictionary))
{
throw new IOException("Page tree root must be a dictionary");
}
And I really have no idea what does this mean and how to fix it.
The strangest thing is that I have created totally new project and tried the same code to merge two documents (the same documents) and it works!
Additionally what I have tried is:
Change the spring boot version if it is ok
Set the mergeDocuments method like this: pdfMergerUtility.mergeDocuments(setupMainMemoryOnly())
Set the mergeDocuments method like this: pdfMergerUtility.mergeDocuments(setupTempFileOnly())
Get the bytes with a different method not using the Files from java.nio:
And also executed this in a different thread
Merging files only locally stored (in resources)
Merging the file that I am getting from another service - this works btw and that is why I am sure he is ok
Can anyone help with this?
The issue as Tilman Hausherr said is in that resource filtering that you can find in your pom file. If you have a case where you are not allowed to modify this then this approach will help you:
final String path = new
ClassPathResource(TEMPLATES.get(locale)).getFile().getAbsolutePath();
final File file = new File(path);
final Path filePath = Paths.get(file.getPath());
result = Files.readAllBytes(filePath);
and then just pass the bytes to the pdfMergerUtility object (or even the whole file instead of the list of bytes).
I want to convert any file extension to .ttl (TURTLE) and I need to use Apache Jena, I am aware of how it can be accomplished using RDFJ4 but the output isn't as accurate as it is using Jena. I want to know how I can auto-detect the extension or rather file type if I am not aware of the extension when reading a file from a directory. This is my code when I hardcode the file-name, it works, I just need help in auto detecting the file type. My code is as follows:
public class Converter {
public static void main(String[] args) throws FileNotFoundException {
String fileName = "./abc.rdf";
Model model = ModelFactory.createDefaultModel();
//I know this is how it is done with RDF4J but I need to use Apache Jena.
/* RDFParser rdfParser = Rio.createParser(Rio.getWriterFormatForFileName(fileName).orElse(RDFFormat.RDFXML));
RDFWriter rdfWriter = Rio.createWriter(RDFFormat.TURTLE,
new FileOutputStream("./"+stripExtension(fileName)+".ttl"));*/
InputStream is = FileManager.get().open(fileName);
if (is != null) {
model.read(is, null, "RDF/XML");
model.write(new FileOutputStream("./converted.ttl"), "TURTLE");
} else {
System.err.println("cannot read " + fileName);
}
}
}
All help and advice will be highly appreciated.
There is functionality that handles reading from a file using the extension to determine the syntax:
RDFDataMgr.read(model, fileName);
It also handles compressed files e.g. "file.ttl.gz".
There is a registry of languages:
RDFLanguages.fileExtToLang(...)
RDFLanguages.filenameToLang(...)
For more control see RDFParser:
RDFParser.create().
source(FileName)
... many options including forcing the language ...
.parse(model);
https://jena.apache.org/documentation/io/rdf-input.html
I have the following file, which contains a binary representation of an .MSG file :
binaryMessage.txt
And I put it in my Eclipse workspace, in the following folder - src/main/resources/test :
I want to use the string which is within this text file , within the following JUnit code, so I tried the following way :
request.setContent("src/main/resources/test/binaryMessage");
mockMvc.perform(post(EmailController.PATH__METADATA_EXTRACTION_OPERATION)
.contentType(MediaType.APPLICATION_JSON)
.content(json(request)))
.andExpect(status().is2xxSuccessful());
}
But this doesn't work. Is there a way I can pass in the string the file directly without using IO code ?
You can't read a file without using IO code (or libraries that use IO code). That said, it's not that difficult to read the file into memory so you can send it.
To read a binary file into a byte[] you can use this method:
private byte[] readToByteArray(InputStream is) throws IOException {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = in.read(buffer)) != -1) {
baos.write(buffer, 0, len);
}
return baos.toByteArray();
} finally {
if (is != null) {
is.close();
}
}
}
Then you can do
request.setContent(readToByteArray(getClass().getResourceAsStream("test/binaryMessage")));
In addition to my comment on Samuel's answer, I just noticed that you depend on your concrete execution directory. I personally don't like that and normally use the class loader's functions to find resources.
Thus, to be independent of your working directory, you can use
getClass().getResource("/test/binaryMessage")
Convert this to URI and Path, then use Files.readAllBytes to fetch the contents:
Path resourcePath = Paths.get(getClass().getResource("/test/binaryMessage").toURI());
byte[] content = Files.readAllBytes(resourcePath);
... or even roll that into a single expression.
But to get back to your original question: no, this is I/O code, and you need it. But since the dawn of Java 7 (in 2011!) this does not need to be painful anymore.
I'm working on ASP.net with the MPXJ library. The .net version of MPXJ has been created using IKVM.
Currently, I have a big problem: After upload a file (Microsoft Project file - .mpp file) to server (I don't need to save it), I want to convert from HttpPostedFileBase to the IKVM version of java.io.InputStream and MPXJ will manipulate them, but I don't know a way to implement this.
My code:
public ActionResult Upload(HttpPostedFileBase files)
{
// Todo: Convert from HttpPostedFileBase to Java.Io.InputStream
ProjectReader reader = new MPPReader();
ProjectFile projectObj = reader.read(Java.Io.InputStream);
}
You need a wrapper to provide a conversion between the IKVM Java type java.io.InputStream and a .net Stream instance. As luck would have it, IKVM ships with one...
Using the wrapper, your example will now look like this:
public ActionResult Upload(HttpPostedFileBase files)
{
ProjectReader reader = new MPPReader();
ProjectFile projectObj = reader.read(new ikvm.io.InputStreamWrapper(files.InputStream));
}
If you don't want to use IKVM, you can implement as below:
public ActionResult Upload(HttpPostedFileBase files)
{
byte[] fileData = null;
using (var binaryReader = new BinaryReader(files.InputStream))
{
fileData = binaryReader.ReadBytes(files.ContentLength);
}
ProjectFile projectObj = reader.read(new ByteArrayInputStream(fileData));
}