At present, I encounter a problem of converting large HTML files to pdf - itext

At present, I encounter a problem of converting large HTML files to pdf. It takes more than 10 seconds to convert them. Can I optimize the performance?
This is my code.
public static void htmlToPDF(String htmlUrl, String destUrl, String fontUrl) {
OutputStream os = null;
try {
String url;
url = new File(htmlUrl).toURI().toURL().toString();
os = new FileOutputStream(destUrl);
ITextRenderer renderer = new ITextRenderer();
renderer.setDocument(url);
ITextFontResolver fontResolver = renderer.getFontResolver();
fontResolver.addFont(fontUrl, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
renderer.layout();
renderer.createPDF(os);
renderer.finishPDF();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
I find that layout takes a lot of time. Is there a good way to optimize this?

Related

What is strict mode policy violation in Android

public static void write(byte[] aInput, String aOutputFileName, String dirName) {
(new File(dirName)).mkdir();
try {
OutputStream output = null;
try {
output = new BufferedOutputStream(new FileOutputStream(dirName + "/" + aOutputFileName));
output.write(aInput);
} finally {
output.close();
}
} catch (FileNotFoundException ex) {
System.out.println("File not found.");
} catch (IOException ex) {
System.out.println(ex);
}
}
The code above is from a library i'm using and it is supposed to create an output file and write a byte array to it. I checked logcat and saw the Strict Mode Policy violation Write.toDisk. I understand what it is supposed to be for my questions are: (1) Does Strict mode prevent you from doing disk reads and write on the main thread? (2) Does that mean that the file or folder were not actually created? (3) How then would I go about creating a folder or file within my App that doesn't trigger this? (4) What is the recommended way to handle disk read / write off the main ui thread, a real world example would be appreciated
Thanks in Advance
(1) It turns out that Strict mode doesn't actually prevent you from making writes to the disk it just gives a warning. From Android Developer "StrictMode is a developer tool which detects things you might be doing by accident and brings them to your attention so you can fix them". https://developer.android.com/reference/android/os/StrictMode
(2) The files were actually being created it's just that I was just not familiar with writing and reading from disk
(3) There are numerous ways to go about creating files (i) first you get a hold of a file directory to write the file to:
context.getFilesDir()
(ii) then you get an outputstream writer (iii) then you write out the data with the writer
public void makeFile(String filename){
//Create temp file for filename
FileOutputStream fos = null;
try {
fos = new FileOutputStream(new File(filename));
fos.write(filename.getBytes());//Write the contents of the file to app folder
fos.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
(iv) finally you close the outputstream writer
(4) The recommended way is to use either an AsyncTask or some other background running class like FutureTask or to use Threads or Runnable:
public class DownloadFileThread implements Runnable{
public void run(){
//your code here
}
}

How to choose the encode of a file created by SmbFileOutputStream?

I am using a method to create a file in a specific path in a shared folder inside my local net.
public static void stringToArquivoTextoRemoto(String path, String fileName, String content, NtlmPasswordAuthentication auth) {
String absolutePath = path + File.separator + fileName;
try {
jcifs.Config.setProperty("jcifs.smb.client.disablePlainTextPasswords", "false");
SmbFile smbFile = new SmbFile(absolutePath, auth);
SmbFileOutputStream smbFileOutputStream = new SmbFileOutputStream(smbFile);
smbFileOutputStream.write(content.getBytes());
smbFileOutputStream.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (SmbException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Now, I am trying to change the encode from "UTF-8" to "ISO-8859-1".
I already tried to put:
jcifs.Config.setProperty( "jcifs.encoding", "ISO-8859-1" );
But it didn't work.
I found a lot of information about how to change the encode using the FileOutputStream, but I found nothing about this using SmbFileOutputStream.
What do I need to do to choose the encode of a file created by SmbFileOutputStream?
This will solve the issue:
package fileWriting;
import java.io.IOException;
import jcifs.smb.NtlmPasswordAuthentication;
import jcifs.smb.SmbFile;
import jcifs.smb.SmbFileOutputStream;
public class testWriting {
public static void main(String[] args) throws IOException {
String user = "domain;username:password";
NtlmPasswordAuthentication auth = new NtlmPasswordAuthentication(user);
String path = "smb://shared/Projects/test.txt";
SmbFile sFile = new SmbFile(path, auth);
try (SmbFileOutputStream sfos = new SmbFileOutputStream(sFile)) {
String v = "Test for file writing!";
byte[] utf = v.getBytes("UTF-8");
byte[] latin1 = new String(utf, "UTF-8").getBytes("ISO-8859-1");
sfos.write(latin1,0,latin1.length );
}
}
}

Dynamic file loading in jetty

As per our implementation we are dynamically creating some image files in the server side and sharing the URLs.
But we are unable to retrieve the image resources using the URLs if the file is created while the JETTY is running.
However we can retrieve it if we stop the jetty and start it again.
I would like to know if there is any configuration which will enable us to retrieve the resources without the jetty being stopped?
Is it necessary to persist the dynamic images? If not, you can just stream the dynamic image like this:
public void sendImage(RenderedImage image, String mimeType, String imageIOType, HttpServletResponse response)
{
if(image != null)
{
OutputStream output = null;
try
{
output = response.getOutputStream();
response.setContentType(mimeType);
ImageIO.write(image, imageIOType, output);
}
catch (IOException e)
{
e.printStackTrace();
}
if(output != null)
{
try
{
output.flush();
output.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
HTH

GWT displaying image specified from servlet

I use a servlet to access a folder outside the web container to load some graphics to web application by using GWT. I use the following snippet in servlet to test the idea:
String s = null;
File inputFile = new File("C:\\Documents and Settings\\User\\My Documents\\My Pictures\\megan-fox.jpg");
FileInputStream fin = null;
try {
fin = new FileInputStream(inputFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
byte c[] = new byte[(int) inputFile.length()];
try {
fin.read(c);
} catch (IOException e) {
e.printStackTrace();
}
try {
fin.close();
} catch (IOException e1) {
e1.printStackTrace();
}
String imgFolderPath = getServletContext().getRealPath("/")+"img";
File imgFolder = new File(imgFolderPath);
imgFolder.mkdir();
File newImage = new File("megan-fox.jpg");
FileOutputStream fout = null;
try {
fout = new FileOutputStream(newImage);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
fout.write(c);
} catch (IOException e) {
e.printStackTrace();
}
try {
fout.close();
} catch (IOException e) {
e.printStackTrace();
}
boolean success = newImage.renameTo(new File(imgFolderPath, newImage.getName()));
The code in servlet reads the image file from the specified folder in hard disk, creates a new folder called 'img' in war folder and copies to it the jpg file. Then it returns to the client the path to the image (for now hardcoded as) '/img/megan-fox.jpg'.
The client then uses the Image class in GWT with the returned path-string to display the image, like in the following snippet:
public void onSuccess(String result) {
String myImage = result;
image = new Image(myImage);
RootPanel.get().add(image);
closeButton.setFocus(true);
}
I need to know if there is a way to achieve the same result without using the 'intermediate' step of creating a folder in the web container root (optional) and copying the file there in order to access it with Image GWT class and display it?
updated: The original servlet class.
public class GreetingServiceImpl extends RemoteServiceServlet implements
GreetingService {
// This method is called by the servlet container to process a GET request.
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// Get the absolute path of the image
ServletContext sc = getServletContext();
// i want to load the image in the specified folder (outside the web container)
String filename = sc.getRealPath("C:\\Documents and Settings\\User\\My Documents\\My Pictures\\megan-fox.jpg");
// Get the MIME type of the image
String mimeType = sc.getMimeType(filename);
if (mimeType == null) {
sc.log("Could not get MIME type of "+filename);
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
return;
}
// Set content type
resp.setContentType(mimeType);
// Set content size
File file = new File(filename);
resp.setContentLength((int)file.length());
// Open the file and output streams
FileInputStream in = new FileInputStream(file);
OutputStream out = resp.getOutputStream();
// Copy the contents of the file to the output stream
byte[] buf = new byte[1024];
int count = 0;
while ((count = in.read(buf)) >= 0) {
out.write(buf, 0, count);
}
in.close();
out.close();
}
// This is the method that is called from the client using GWT-RPC
public String greetServer(String input) throws IllegalArgumentException {
HttpServletRequest req = this.getThreadLocalRequest();
HttpServletResponse res = this.getThreadLocalResponse();
try {
doGet(req, res);
} catch (IOException e) {
e.printStackTrace();
}
// actually i dont know what that means but i thought i would have to returned something like the image's url?
return res.encodeURL("/img/image0.png");
}
}
I logically misused the method that was proposed to solve my problem. What is the correct way?
Sure, just have your servlet serve the image directly:
Set the Content-Type header to image/jpeg.
Write out image file contents to servlet response writer.
Here is an example.

How can I marshal Objects from a Socket without closing it? (JAXB Marshaling from Inputstream via Socket)

I have tried in many different ways to send my xml document over a socket connection between a server and a client without closing the socket after sending (keep the outputstream open, for sending another document). I have found several sites who claimed that it should work, so I tried it in all the ways they sugested, but I did not found a way which works.
(that describes the same what I would like to do: http://jaxb.java.net/guide/Designing_a_client_server_protocol_in_XML.html)
The follwing code works perfectly if I am closing the socket after sending (#code marsh.marshal(element, xsw);), but it stucks on unmarshaling on the server side, if I try to keep the socket open.
Client Side....
public void sendMessage(String message){
JAXBContext jaxbContext;
try {
jaxbContext = JAXBContext.newInstance("cdl.wizard.library");
Marshaller marsh = jaxbContext.createMarshaller();
marsh.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marsh.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, "http://www.example.org/WizardShema WizardsSchema.xsd");
ObjectFactory of = new ObjectFactory();
// the Dataset is the root element of the xml document
Dataset set = new Dataset("CONN01", "CONTR", "MCL01#localhost", "SV01#localhost:32000");
CommandSet cmdSet = new CommandSet();
Command cmd = new Command();
cmd.setFunctionName("RegisterAs");
Param p = new Param();
p.setString("RemoteClient");
cmd.addParameter(p);
cmdSet.addCommand(cmd);
set.setInstruction(cmdSet);
// creates a valid xml dataset, with startDocument, startElement...
JAXBElement<Dataset> element = of.createData(set);
XMLStreamWriter xsw = XMLOutputFactory.newInstance().createXMLStreamWriter(mOOS);
marsh.marshal(element, xsw);
xsw.flush();
} catch (JAXBException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (XMLStreamException e) {
e.printStackTrace();
} catch (FactoryConfigurationError e) {
e.printStackTrace();
}
SERVER Side....
private void handleMessage() {
JAXBContext jaxbContext;
try {
jaxbContext = JAXBContext.newInstance("cdl.wizard.library") ;
Unmarshaller um = jaxbContext.createUnmarshaller();
XMLInputFactory xmlif = XMLInputFactory.newInstance();
// XMLEventReader xmlr = xmlif.createXMLEventReader(mOIS);
XMLStreamReader xmlr = xmlif.createXMLStreamReader(mOIS, "UTF8");
// move to the root element and check its name.
xmlr.nextTag();
System.out.println("TagName:" + xmlr.getLocalName());
xmlr.require(START_ELEMENT, null, "Data");
JAXBElement<Dataset> obj = um.unmarshal(xmlr, Dataset.class);
Dataset set = obj.getValue();
System.out.println("ID:"+ set.getID());
} catch (JAXBException e) {
e.printStackTrace();
} catch (XMLStreamException e) {
e.printStackTrace();
} catch (FactoryConfigurationError e) {
e.printStackTrace();
}
}