Can't read a google static map via HtmlUnit - java

I am trying to read a static map from Google Maps on the following URL.
This works fine from my web browser, but when I try this from HtmlUnit I get an UnexpectedPage result. Does anyone know what this means?

According to the javadoc of UnexpectedPage, you're receiving an UnexpectedPage because server returns an unexpected content type. If you check the returned header in HtmlUnit you can see that it contains: Content-Type=image/png
Here's a little application that retrieves an image from an URL:
import java.awt.Image;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import com.gargoylesoftware.htmlunit.UnexpectedPage;
import com.gargoylesoftware.htmlunit.WebClient;
/** Small test application used to fetch a map. */
public class FetchMapSwingApp extends JFrame {
/** Serial Id. */
private static final long serialVersionUID = 1920071939468904323L;
/**
* Default constructor.
*/
public FetchMapSwingApp() {
// Make sure the application closes correctly
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
// The map where trying to read
String url = "http://maps.googleapis.com/maps/api/staticmap?center=55.690815,12.560678&zoom=15&size=400x500&sensor=false";
// Fetch the image
Image image = fetchMap(url);
// Add the image to the JFrame and resize the frame.
add(new JLabel(new ImageIcon(image)));
pack();
}
/**
* Fetch the image on the given URL.
*
* #param url
* the image location
* #return the fetched image
*/
private Image fetchMap(String url) {
Image image = null;
WebClient webClient = new WebClient();
webClient.setThrowExceptionOnScriptError(false);
try {
// The URL returns a png file!
UnexpectedPage page = webClient.getPage(url);
InputStream inputStream = page.getInputStream();
// Read the stream to an image
image = ImageIO.read(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
return image;
}
/**
* Start of the application.
*
* #param args
* the arguments to the main method
*/
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new FetchMapSwingApp().setVisible(true);
}
});
}
}

Related

Can't Get Image to Load From Another Package- Java

I am working on a Java Project. I have my images in my "resources" package and all my UI classes in my "UIPackage". I am using a JFrame form to design my window and put an image into a JLabel through the properties tab in the window editor. However, this does not scale the image so to get around this, I wrote code to grab an image from the resources package, scale it, and then display it in the JLabel. However, my attempts to grab an image file return null. The especially frustrating part is if I copy (not editing the generated code) what the form does when I add an image to the JLabel through the properties tab, it still doesn't work. What am I doing wrong here?
Project Navigator
import java.awt.Image;
import javax.swing.ImageIcon;
import javax.imageio.ImageIO;
import java.io.IOException;
import java.awt.image.BufferedImage;
/**
*
* #author Admin
*/
public class LandingPage extends javax.swing.JFrame {
/**
* Creates new form LandingPage
*/
public LandingPage() {
initComponents();
//this works
sideArtLabel.setIcon(new ImageIcon(new ImageIcon("C:\\Users\\Admin\\Documents\\NetBeansProjects\\HowtoFeedYourDragon\\src\\main\\java\\resources\\2561-bearded-dragon-lawler.jpg").getImage().getScaledInstance(sideArtLabel.getWidth(), sideArtLabel.getHeight(),Image.SCALE_SMOOTH)));
//path is null
System.out.println("jpg 1 " + getClass().getResource("/resources/2561-bearded-dragon-lawler.jpg"));
//sideArtLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/resources/2561-bearded-dragon-lawler.jpg")));
//but this doesn't. path is null
try
{
System.out.println("jpg 2 " + getClass().getResource("/resources/01.jpg"));
BufferedImage sideArtImg = ImageIO.read(getClass().getResource("/resources/01.jpg"));
ImageIcon sideArtIcon = new ImageIcon(sideArtImg);
sideArtLabel.setIcon(sideArtIcon);
}
catch(IOException e)
{
e.printStackTrace();
}
}

How to generate pdf of html page in java

I have to generate pdf of HTML page. I have written a method for this but it generates an error. Please guide me where I'm wrong. Thank You!
public void htmlToPdf(
String htmlPath,
File pdfFile
) throws IOException, DocumentException {
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(
document,
new FileOutputStream(pdfFile)
);
document.open();
XMLWorkerHelper.getInstance().parseXHtml(
writer,
document,
new FileInputStream(htmlPath),
Charset.forName("UTF-8")
);
document.close();
}
Error :
Cannot resolve method 'parseXHtml(com.lowagie.text.pdf.PdfWriter, com.lowagie.text.Document, java.io.FileInputStream, java.nio.charset.Charset)'
So you want to generate PDFs from HTML with Java? (check EDIT 2020 at the bottom)
Here is the procedure I am using with flying-saucer.
Format your HTML with CSS 2.1
Write the process to generate a PDF
Create the PDF generator interface
Use a custom object to wrap images with attributes for further formatting
Implements your interface with your PDF parameters and images
1. Format your HTML with CSS 2.1
Example can be a JSP with ELs, any other template (you will be able to get the
generated HTML with parameters with an internal POST request), or just static
HTML.
You cannot use proportionnal values like em, rem, vh, vw or complex
CSS like animations.
You can use <style> </style> tag or inline style= attribute
Here is an example of a JSP in my webapp.
<!DOCTYPE html>
<%# page session="false"
language="java"
contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"
isELIgnored="false" %>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<META CHARSET="UTF-8" />
<title>My PDF</title>
<style>
/* you can add reset css too */
/* stylesheet */
body { font-family: sans-serif; }
.someCSSClass {}
.anotherCSSClass {}
</style>
</head>
<body>
<div class="someCSSClass">
<p class="anotherCSSClass" style="line-height:16px;">
${ param.aParameter }
</p>
2. Write the process to generate a PDF with an interface
Why using an interface? Because in the case you need to generate additional
PDFs from different models you will not have to write the same logic to
generate each PDFs.
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.xhtmlrenderer.pdf.ITextRenderer;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfImage;
import com.itextpdf.text.pdf.PdfIndirectObject;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import main.java.bean.ImagePDF;
import main.java.interface.PDFInterface;
import main.java.bean.Constants;
/**
* PDFGenerator
* Class to generate PDF (can implement Servlet).
*/
public class PDFGenerator {
private static final String TMP_DIR = System.getProperty("java.io.tmpdir");
/*
* May not be a GET, can be simple method call for local application or
* whatever you need
*/
#Override
protected void goGet(
HttpServletRequest request,
HttpServletResponse response
) throws IOException {
PDFInterface pdfImplementation = null;
/*
* instance your PDF Model implementation according to this
* parameter (for example)
*/
int pdfModel = Integer.parseInt(
request.getParameter("requestedPDFModel")
);
switch (pdfModel) {
case Constants.PDF_MODEL_1:
pdfImplementation = new PDFImplementationOne();
/*
* You could get the image reference from GET request too,
* or from database or from constants
*/
pdfImplementation.addImage(
"image1.png",
120,
50,
"image_name1",
request
);
break;
case Constants.PDF_MODEL_2:
pdfImplementation = new PDFImplementationTwo();
pdfImplementation.addImage(
"image2.png",
350,
70,
"image_name2",
request
);
break;
default :
System.out.println("Cannot find an implementation for the requested PDF.");
return null;
}
String html = null;
/*
Get the HTML from an URL : if your implementation returns null
then you can for example decide to get the HTML from a file in your implementation
*/
if (pdfImplementation.getUrl(request) != null) {
// Send POST request to generate the HTML from a template (JSP, JSF, Thymeleaf, ...)
URLConnection connection = new URL(
pdfImplementation.getUrl(request)
+pdfImplementation.getEncodedQueryString()
).openConnection();
connection.setDoOutput(true); // POST : remove this to do a GET
connection.setRequestProperty("Accept-Charset", "UTF-8");
connection.setRequestProperty(
"Content-Type",
"application/x-www-form-urlencoded;charset=UTF-8"
);
try (OutputStream output = connection.getOutputStream()) {
output.write(
pdfImplementation
.getEncodedQueryString()
.getBytes(StandardCharsets.UTF_8)
);
}
// Open an input stream on the response
BufferedReader in = new BufferedReader(
new InputStreamReader(connection.getInputStream())
);
StringBuilder sb = new StringBuilder();
// A line in our generated HTML
String inputLine;
// Read all HTML lines and concatenate
while ((inputLine = in.readLine()) != null) {
sb.append(inputLine);
}
html = sb.toString();
in.close();
}
// Get the HTML from a File
else {
html = String.join(
"",
Files.readAllLines(pdfImplementation.getHTMLFile().toPath())
);
}
// Create a temp file to make the PDF
File tempPDFFile = new File(
TMP_DIR + pdfImplementation.getGeneratedPDFFileName()
);
if (!tempPDFFile.exists()) { tempPDFFile.createNewFile(); }
FileOutputStream fos = new FileOutputStream(tempPDFFile);
// Output the HTML to the temp PDF file
new ITextRenderer() {{
setDocumentFromString(html);
layout();
createPDF(fos);
}};
fos.close();
// Create your final PDF file
File pdf = new File(pdfImplementation.getPDFFilename());
// Add images if needed
addImageToPDF(pdfImplementation, tempPDFFile, pdf);
// Write in response if you need servlet implementation
writePDFContentToResponse(pdf, response);
}
/**
* writePDFContentToResponse
* #param pdf : the final PDF file
* #param response : a HTTPServletResponse to write PDF file bytes
* #throws IOException
*/
void writePDFContentToResponse(
File pdf,
HttpServletResponse response
) throws IOException {
InputStream fis = new FileInputStream(pdf);
String mimeType = getServlet().getServletContext()
.getMimeType(pdf.getAbsolutePath());
response.setContentType(
mimeType != null ? mimeType : "application/octet-stream"
);
response.setContentLength((int) pdf.length());
response.setHeader(
"Content-Disposition",
"attachment; filename="+pdf.getName()+".pdf"
);
ServletOutputStream os = response.getOutputStream();
byte[] bufferData = new byte[1024];
int read = 0;
while((read = fis.read(bufferData)) != -1) {
os.write(bufferData, 0, read);
}
os.flush();
os.close();
fis.close();
response.flushBuffer();
Files.delete(pdf.toPath());
}
/**
* addImageToPDF
*
* #param pdfImplementation : the pdfImplementation to get the array of
* custom image objects ImagePDF.
* #param tempPDFFile : the temp PDF file with already HTML content
* converted.
* #param pdf : the final PDF file which will have images stamped.
* #throws DocumentException
* #throws IOException
*/
void addImageToPDF(
PDFInterface pdfImplementation,
File tempPDFFile,
File pdf
) throws DocumentException, IOException {
PdfReader reader = new PdfReader(new FileInputStream(tempPDFFile));
PdfStamper stamper = new PdfStamper(
reader,
new FileOutputStream(pdf)
);
for (ImagePDF img: pdfImplementation.getImages()) {
Image image = img.getImage();
image.scalePercent(img.getScale());
PdfImage stream = new PdfImage(image, "", null);
stream.put(
new PdfName("ITXT_SpecialId"),
new PdfName("123456789")
);
PdfIndirectObject ref = stamper.getWriter().addToBody(stream);
image.setDirectReference(ref.getIndirectReference());
image.setAbsolutePosition(
img.getWidthPosition(),
img.getHeightPosition()
);
PdfContentByte over = stamper.getOverContent(1);
over.addImage(image);
}
stamper.close();
reader.close();
}
}
 3. Create the PDF generator interface
import java.io.File;
import java.io.IOException;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import com.itextpdf.text.BadElementException;
/**
* PDFInterface
* Interface to define the behavior a PDF model has to implement.
*/
public interface PDFInterface {
/**
* getUrl
* #param request the HTTPServletRequest to fetch parameters for the PDF
* #return the URL target to make a HTTP POST request to get the generated
* HTML (for example if you are making a HTTP POST on a JSP to generate
* HTML dynamically.
*/
String getUrl(HttpServletRequest request);
/**
* getHTMLFile
* #return return the HTML file from the local storage to be read to get
* the HTML.
*/
File getHTMLFile();
/**
* setParametres
* #param object : an object or a list of objects to be encoded to the
* query String to generate the PDF.
*/
void setParametres(Candidat candidat);
String getEncodedQueryString();
/**
* getImages
* #return a custom ImagePDF object with needed attributes to add an image
* after the PDF has been generated has the HTML cannot be read to get
* image during the generation of the PDF.
*/
List<ImagePDF> getImages();
/**
* addImage
* #param url : the URL to get the image
* #param x : the X position
* #param y : the Y position
* #param name : the name of the image
* #param request : the HTTPServletRequest to generate the relative link
* to fetch the image.
* #param scale : the scale of the image
* #throws BadElementException
* #throws IOException
*/
void addImage(
String url,
float x,
float y,
String name,
HttpServletRequest request,
float scale
) throws BadElementException, IOException;
/**
* getPDFFilename
* #return : the name of the PDF file to be generated
*/
String getPDFFilename();
}
4. The ImagePDF object (in case you need to add image to your PDF)
import java.io.IOException;
import com.itextpdf.text.BadElementException;
import com.itextpdf.text.Image;
/**
* ImagePDF
* Class for a custom ImagePDF object to fit needs to stamp an image on a
* generated PDF (URI to get the image, scale, positions x y ...).
*/
public class ImagePDF implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private Image image;
private float widthPosition;
private float heightPosition;
private String name;
private Float scale;
/**
* ImagePDF
* #param urlImage : the URL to fetch the image
* #param heightPosition : the y position on the PDF canvas
* #param widthPosition : the x position on the PDF canvas
* #param name : the name of the image
* #param scale : the scale of the image on the PDF canvas
* #throws BadElementException
* #throws IOException
*/
public ImagePDF(
String urlImage,
float widthPosition,
float heightPosition,
String name,
Float scale
) throws BadElementException, IOException {
this.image = Image.getInstance(urlImage);
this.heightPosition = heightPosition;
this.widthPosition = widthPosition;
this.name = name;
this.scale = scale;
}
// Getters and setters ...
 5. Implements your interface for your PDF parameters
(used in example above)
/**
* PDFImplementationOne
* The PDFImplementation to generate a specific PDF.
*/
public class PDFImplementationOne implements PDFInterface {
private static final String PARAM_1 = "param1";
private static final String PARAM_2 = "param2";
private Map<String, String> parameters;
private List<ImagePDF> images;
/**
* PDFImplementationOne
* You can pass service to add information retreival from DB or objects to
* pass to parameters in the constructor if needed.
*/
public PDFImplementationOne (CustomObject aParameter) {
this.parameters = new HashMap<>();
this.images = new ArrayList<>();
// in case you need parameters, passed in constructor
setParametres(aParameter);
}
/* (non-Javadoc)
* #see main.java.interface.PDFInterface#getUrl()
*/
#Override
public String getUrl(HttpServletRequest request) {
/*
* This is an example in case your generate your HTML from JSP with
* parameters, if it is from static file then return null
*/
StringBuilder sb = new StringBuilder("http://");
sb.append(request.getServerName());
sb.append((request.getServerName().startsWith("127.0.0")?":8080":""));
sb.append("/MyApp/urlToJSP");
return sb.toString();
}
/*
* (non-Javadoc)
* #see main.java.interface.PDFInterface#addImage(
* java.lang.String,
* float,
* float,
* java.lang.String,
* javax.servlet.http.HttpServletRequest,
* float scale
* )
*/
#Override
public void addImage(
String fileName,
float x,
float y,
String name,
HttpServletRequest request
) {
/*
* Here I get the image from a ressource server but you can read the
* image from local storage as well
*/
StringBuilder url = new StringBuilder("http://");
url.append(request.getServerName());
url.append(request.getServerName().startsWith("127.0.0")?":8080":"");
url.append("/MyApp/img/");
url.append(fileName);
try {
ImagePDF image = new ImagePDF(url.toString(), x, y, name, scale);
images.add(image);
}
catch (BadElementException | IOException e) {
System.out.println(Cannot set image for PDF "+url.toString());
}
}
/* (non-Javadoc)
* #see main.java.interface.PDFInterface#getImages()
*/
#Override
public List<ImagePDF> getImages() {
return this.images;
}
/* (non-Javadoc)
* #see main.java.interface.PDFInterface#setParameters(
* CustomObject customObject
* )
*/
#Override
public void setParametres(CustomObject customObject) {
parametres.put(PARAM_1, customObject.getAttribute().toString());
// may have other parameters ...
}
/* (non-Javadoc)
* #see model.bean.ResultatsEcritsPDF#getEncodedQueryString()
*/
#Override
public String getEncodedQueryString() {
/*
* Create the queryString to do further HTTP POST or GET to fetch the
* generated HTML with parameters
*/
StringBuilder queryStringBuilder = new StringBuilder("?");
parameters.entrySet().stream().forEach(e -> {
queryStringBuilder.append(e.getKey());
queryStringBuilder.append("=");
try {
queryStringBuilder.append(
URLEncoder.encode(
e.getValue() == null
? ""
: e.getValue(),
StandardCharsets.UTF_8.name()
)
);
}
catch (UnsupportedEncodingException e1) {
queryStringBuilder.append("");
}
queryStringBuilder.append("&");
});
// Remove the last &
return queryStringBuilder.toString().substring(
0,
queryStringBuilder.toString().length()-1
);
}
/* (non-Javadoc)
* #see model.bean.PDFInterface#getHTMLFile()
*/
#Override
public File getHTMLFile() {
return new File("/path/to/myHTMLFile.html");
}
/* (non-Javadoc)
* #see model.bean.PDFInterface#getPDFFilename()
*/
#Override
public String getPDFFilename() {
return "myPDF.pdf";
}
}
Tell me if it needs some clarification.
EDIT 2020
Things are much simpler now with the improvement of libraries and calling HTTP server itself to generate the dynamic HTML content is not enough simpler and requires additional network configuration in some case.
Here is the new process :
Make a HTML template with CSS2.1 (with <style> tag or inline style=") and include template expressions (EL-style or whatever)
Fetch HTML template as String
Replace template expressions "${ }" in HTML
Replace images in HTML like <img src="image.png" /> by encoded base64 images
Make the PDF file
Write it to response or whatever
Here is the project structure I am using (for example) :
main
|--java
|--bean
|--PdfConverter.java
|--resources
|--pdf
|--template.html
|--img
|--image.png
Dependencies :
<dependency>
<groupId>com.github.librepdf</groupId>
<artifactId>openpdf</artifactId>
<version>1.3.20</version>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-core</artifactId>
<version>9.1.20</version>
</dependency>
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>flying-saucer-pdf-openpdf</artifactId>
<version>9.1.20</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
<version>1.9</version>
</dependency>
HTML template (with images) :
<html>
<head>
<style>
body {
font-family:sans-serif;
font-size:14px;
margin: 0 auto;
padding: 0;
}
h1 {
text-align:center;
font-size:21px;
text-transform:capitalize;
}
</style>
</head>
<body>
<h1>some title</h1>
<p>Some paragraph : ${ foo }</p>
<!-- you can style images with CSS! -->
<img src="image.png" style="width:50px;height:50px" />
</body>
</html>
PdfConverter :
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.Map;
import java.util.Scanner;
import javax.servlet.ServletContext;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.text.StringSubstitutor;
import org.apache.poi.util.IOUtils;
import org.springframework.http.MediaType;
import org.xhtmlrenderer.pdf.ITextRenderer;
/**
* PdfConverter
* Extends this to implement additional to make the map to replace template
* expressions.
* #author user
* #since 28 juil. 2020
*/
public class PdfConverter {
/**
* Temp directory.
*/
private static final String TMP_DIR =
System.getProperty("java.io.tmpdir") + "/";
/**
* Directory to HTML templates (dedicated to PDF generation).
*/
private static final String PDF_DIR =
"pdf/";
/**
* Directory to the image folders (dedicated to PDF generation).
*/
private static final String PDF_IMG_DIR =
"pdf/img/";
/**
* Prefixes for templates expressions.
*/
private static final String PREFIX_TEMPLATE = "${ ";
/**
* Suffixes for template expressions.
*/
private static final String SUFFIX_TEMPLATE = " }";
/**
* Generated PDF file.
*/
private File generatedPDF;
/**
* PDF file name.
*/
private String pdfName;
/**
* PdfConverter
* #param m map key, value to replace, to replace expressions in HTML
* template.
* #param s ServletContext to get resources from context path.
* #param fileName desired name of the generated PDF.
* #param template name of the HTML template to make the PDF.
* #throws IOExceptio
*/
public PdfConverter(
Map<String, String> m,
ServletContext s,
String fileName,
String template
) throws IOException {
// Set PDF filename
setPdfName(fileName);
// Fetch HTML template
#SuppressWarnings("resource")
String html = new Scanner(
s.getResourceAsStream(PDF_DIR+ template),
StandardCharsets.UTF_8.toString()
).useDelimiter("\\A").next();
/*
* Replace template expressions "${ }" in HTML
*/
StringSubstitutor sub = new StringSubstitutor(
m,
PREFIX_TEMPLATE,
SUFFIX_TEMPLATE
);
String resolvedString = sub.replace(html);
/*
* Replace images like <img src="image.png" /> by
* <img src=\"data:image/png;base64," + base64Image
*/
String[] imgs = StringUtils.substringsBetween(
resolvedString,
"<img src=\"", "\""
);
for (String s1 : imgs) {
String mime = Files.probeContentType(Paths.get(PDF_IMG_DIR + s1));
resolvedString = resolvedString.replace(
s1,
"data:" + mime + ";base64,"
+ Base64.getEncoder().encodeToString(
IOUtils.toByteArray(
s.getResourceAsStream(PDF_IMG_DIR + s1)
)
)
);
}
// Make the PDF file
FileOutputStream fos = new FileOutputStream(TMP_DIR+getPdfName());
ITextRenderer it = new ITextRenderer();
it.setDocumentFromString(resolvedString);
it.layout();
it.createPDF(fos);
fos.close();
// Set the PDF generated file to this PdfConverter instance
setGeneratedPDF(new File(TMP_DIR+getPdfName()));
}
/**
* getGeneratedPDF
*
* #return the generatedPDF
*/
public File getGeneratedPDF() {
return generatedPDF;
}
/**
* setGeneratedPDF
*
* #param generatedPDF the generatedPDF to set
*/
public void setGeneratedPDF(File generatedPDF) {
this.generatedPDF = generatedPDF;
}
/**
* getPdfName
*
* #return the pdfName
*/
public String getPdfName() {
return pdfName;
}
/**
* setPdfName
*
* #param pdfName the pdfName to set
*/
public void setPdfName(String pdfName) {
this.pdfName = pdfName;
}
/**
* writePdfToResponse
* Write the PDF file into the response and delete it from temp directory
* afterwards.
* #param response
* #throws IOException
*/
public void writePdfToResponse(
HttpServletResponse response
) throws IOException {
try (
FileInputStream fis =
new FileInputStream(getGeneratedPDF())
) {
response.setContentType(MediaType.APPLICATION_PDF_VALUE);
response.setHeader(
"Content-Disposition",
"inline; filename=" + getPdfName()
);
response.addHeader(
"Content-Length",
Long.toString(getGeneratedPDF().length())
);
ServletOutputStream servletOutputStream =
response.getOutputStream();
int read = 0;
byte[] bytes = new byte[1024];
while ((read = fis.read(bytes)) != -1) {
servletOutputStream.write(bytes, 0, read);
}
response.flushBuffer();
}
catch (IOException ioe) {
response.setContentType(MediaType.TEXT_PLAIN_VALUE);
response.getWriter().print("Cannot render PDF file.");
response.flushBuffer();
}
finally {
// Delete generated PDF after writing it to the response
getGeneratedPDF().delete();
}
}
}
And how to use it in servlet (Spring MVC example) :
/**
* downloadPDF
*
* #param response
* #param foo
* #throws IOException
*/
#PostMapping("/downloadPDF")
public void downloadPDF(
HttpServletRequest request,
HttpServletResponse response,
String foo
) throws IOException {
Map<String, String> m = new HashMap<>();
m.put("foo", "my_foo_value");
PdfConverter pdfConverter = new PdfConverter(
m,
request.getServletContext(),
"my_pdf",
"template"
);
pdfConverter.writePdfToResponse(response);
}

Cannot redirect with the Vaadin navigator

I've a very strange behavior, I think I have two issues, I put them together on the same post because they can be linked :
my code is :
VaadinSession.getCurrent().setAttribute("user", user);
System.out.println("User :"+ user);
getUI().getNavigator().navigateTo(HomePageView.HOMEPAGE);
1. First issue
I'm on the login page, I can see my user information, but I cannot navigate to the homepage.
I don't have any error !
If I delete the line with the vaadinSession, the navigator is working...
2. Second Issue
I tried to debug my code but I received a "source not found", to fix that, I follow Eclipse java debugging: source not found. But, seems to working for me.
What I did :
I recreated a new workspace without success.
I edited the source lookup path and I have my java project in it
In the preferences -> java -> installed JREs -> I've the 1.8.0 JDK
right click on the project -> maven -> download sources
right click on the project -> maven -> disable maven nature and after Configure -> project to maven
EDIT : SOLUTION for the issue 2 :
I was so blocked... I know it's an eclipse issue (configuration or something like that). I changed for IntelliJ. This IDE show me sources without problem.
INFO
I'm using Vaadin and REST web services (with the javax.ws.rs.client.ClientBuilder).
When I use SYSOUT, I have the good information. I received the information from the homepage (instead of the view seems to keep the login view).
Any hint will be very useful !
EDIT : Full LoginView class
package com.test.project.View;
import com.test.project.model.User;
import com.test.project.restclient.RestClient;
import com.vaadin.annotations.Title;
import com.vaadin.data.Binder;
import com.vaadin.data.validator.EmailValidator;
import com.vaadin.icons.VaadinIcons;
import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
import com.vaadin.server.VaadinSession;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
/**
* Login View. The user should enter his email address. Extends {#link CustomComponent} and implements {#link View}
*
* #author Bob
*/
#Title("Sign Up")
public class LoginView extends CustomComponent implements
View {
private static final long serialVersionUID = 1L;
public static final String LOGIN = "";
private VerticalLayout vLayout = new VerticalLayout();
private static final String SIGNUP_LABEL = "Sign Up";
private static final String EMAIL_CAPTION = "Type your email here :";
private static final String SIGNIN_LABEL = "Sign In";
private TextField email;
private static final String TOKEN_ATTRIBUTE_LABEL = "token";
private final Binder<User> binder = new Binder<>();
private User user;
private Button loginButton;
/**
* Login view Constructor
*/
public LoginView() {
createLoginPanel();
addListener();
}
/**
* Add Listener concern by the Login View Fields
*/
private void addListener() {
loginButton.addClickListener(e -> {
RestClient rc = new RestClient();
user = rc.getUserInfo(email.getValue());
VaadinSession.getCurrent().setAttribute(TOKEN_ATTRIBUTE_LABEL, user.getToken());
System.out.println();
getUI().getNavigator().navigateTo(HomePageView.HOMEPAGE);
});
}
/**
* Create the login panel with the email field and the login button
*/
private void createLoginPanel() {
final VerticalLayout layout = new VerticalLayout();
layout.setSizeFull();
Panel panel = new Panel(SIGNUP_LABEL);
panel.setHeight(200, Unit.PIXELS);
panel.setWidth(300, Unit.PIXELS);
email = new TextField();
email.setCaption(EMAIL_CAPTION);
email.setHeight(30, Unit.PIXELS);
email.setWidth(275, Unit.PIXELS);
binder.forField(email).withValidator(new EmailValidator("This doesn't look like a valid email address")).bind(User::getEmail, User::setEmail);
loginButton = new Button(SIGNIN_LABEL);
loginButton.setIcon(VaadinIcons.SIGN_IN);
layout.addComponents(email, loginButton);
layout.setComponentAlignment(loginButton, Alignment.BOTTOM_RIGHT);
panel.setContent(layout);
vLayout.addComponent(panel);
vLayout.setSizeFull();
vLayout.setComponentAlignment(panel, Alignment.MIDDLE_CENTER);
setCompositionRoot(vLayout);
}
/* (non-Javadoc)
* #see com.vaadin.navigator.View#enter(com.vaadin.navigator.ViewChangeListener.ViewChangeEvent)
*/
#Override
public void enter(ViewChangeEvent event) {
email.focus();
}
}
Rest client class :
package com.test.project.restclient;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.Entity;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.glassfish.jersey.client.ClientConfig;
import org.json.simple.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.gson.Gson;
import com.test.project.model.User;
/**
* Class contain the Rest Client which allow to use and call the rest web services.
*
* #author Bob
*/
public class RestClient {
private static final String EMAIL_LABEL = "email";
private static final Logger LOG = LoggerFactory.getLogger(RestClient.class);
private Client client;
public RestClient() {
client = ClientBuilder.newClient(new ClientConfig());
}
/**
* Get the user information from the user email
*
* #param email
* #return user
*/
#SuppressWarnings("unchecked")
#POST
#Path("http://IpAddress:8080/api/authentication/")
public User getUserInfo(String email) {
JSONObject obj = new JSONObject();
obj.put(EMAIL_LABEL, email);
WebTarget webtarget = client.target("http://IpAddress:8080/api/authentication/");
Response response = webtarget.request().accept(MediaType.APPLICATION_JSON).post(Entity.entity(obj, MediaType.APPLICATION_JSON));
String answer = response.readEntity(String.class);
LOG.info("User information are :" + answer);
Gson g = new Gson();
User user = g.fromJson(answer, User.class);
return user;
}
}
Home Page View :
package com.test.project.View;
import com.test.project.model.Action;
import com.test.project.restclient.RestClient;
import com.vaadin.data.Binder;
import com.vaadin.icons.VaadinIcons;
import com.vaadin.navigator.View;
import com.vaadin.navigator.ViewChangeListener.ViewChangeEvent;
import com.vaadin.server.VaadinSession;
import com.vaadin.ui.Button;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.MenuBar;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
/**
* Home page view.
*
* #author Bob
*/
public class HomePageView extends CustomComponent implements
View {
private static final long serialVersionUID = 1L;
public static final String HOMEPAGE = "home";
private final VerticalLayout layout;
private static final String TOKEN_ATTRIBUTE_LABEL = "token";
/**
* Home page View constructor
*/
public HomePageView() {
layout = new VerticalLayout();
layout.setSizeFull();
String CURRENT_USER_TOKEN = (String) VaadinSession.getCurrent().getAttribute(TOKEN_ATTRIBUTE_LABEL);
System.out.println("Current user token : " + CURRENT_USER_TOKEN);
createMenu();
setCompositionRoot(layout);
}
/**
* Create a Vertical Menu with the Home page and Actions page
*/
private void createMenu() {
MenuBar barmenu = new MenuBar();
barmenu.addItem("Homepage", VaadinIcons.HOME, null);
barmenu.addItem("Actions", VaadinIcons.TABLE, null);
layout.addComponent(barmenu);
}
/* (non-Javadoc)
* #see com.vaadin.navigator.View#enter(com.vaadin.navigator.ViewChangeListener.ViewChangeEvent)
*/
#Override
public void enter(ViewChangeEvent event) {
}
}
Ok, I found the solution/workarround for the issues :
For the first issue : "token" seems to be a reserved word, "tokenEmployee" seems to be better and it's working perfectly...
For the second issue : I still don't know why it's not working in Eclipse, I've the source but in debug mode, I'm not able to see them. I changed for IntelliJ. I was not able to find any thing about reserved words for the Vaadin Session. If someone find a link or something, I'm very interested !
Too much time trying to fix it..
A bit thanks to #jay who tried to help me!

How to load Apache Ignite Cache when reading from a text file

I created a file helloworld.txt. Now I'm reading from the file and then I want to load the contents of the file into the cache, and whenever the cache is updated, it should write to the file as well.
This is my code so far:
Please tell me what to do to load the cache and then write from the cache to the file, as the instructions are not clear from Apache Ignite documentation.
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.IgniteDataStreamer;
import org.apache.ignite.IgniteException;
import org.apache.ignite.Ignition;
import org.apache.ignite.examples.ExampleNodeStartup;
import org.apache.ignite.examples.ExamplesUtils;
public class FileRead {
/** Cache name. */
private static final String CACHE_NAME = "FileCache";
/** Heap size required to run this example. */
public static final int MIN_MEMORY = 512 * 1024 * 1024;
/**
* Executes example.
*
* #param args Command line arguments, none required.
* #throws IgniteException If example execution failed.
*/
public static void main(String[] args) throws IgniteException {
ExamplesUtils.checkMinMemory(MIN_MEMORY);
try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) {
System.out.println();
try (IgniteCache<Integer, String> cache = ignite.getOrCreateCache(CACHE_NAME)) {
long start = System.currentTimeMillis();
try (IgniteDataStreamer<Integer, String> stmr = ignite.dataStreamer(CACHE_NAME)) {
// Configure loader.
stmr.perNodeBufferSize(1024);
stmr.perNodeParallelOperations(8);
///FileReads();
try {
BufferedReader in = new BufferedReader
(new FileReader("/Users/akritibahal/Desktop/helloworld.txt"));
String str;
int i=0;
while ((str = in.readLine()) != null) {
System.out.println(str);
stmr.addData(i,str);
i++;
}
System.out.println("Loaded " + i + " keys.");
}
catch (IOException e) {
}
}
}
}
}
}
For information on how to load the cache from a persistence store please refer to this page: https://apacheignite.readme.io/docs/data-loading
You have two options:
Start a client node, create IgniteDataStreamer and use it to load the data. Simply call addData() for each line in the file.
Implement CacheStore.loadCache() method, provide the implementation in the cache configuration and call IgniteCache.loadCache().
Second approach will require to have the file on all server nodes, by there will be no communication between nodes, so most likely it will be faster.

Programmatically downloading a file using Selenium in Java

I was looking for a Chrome Extension which can intercept the download whenever we click on a PDF link or on a link that spawns a PDF at server end programmatically. One way of doing it was Selenium Browser Profiling, I found this particular code. I want Selenium to download the PDF file and rename it according to the strings i pass from the JAVA program.
How can i use this code to download code and hook it up it with my program. It should trigger this whenever i execute a command like this:-
**driver.findElement(By.xpath("//a[contains(#href,\"/bbtobs/bbtolbext/statements/savepdf?type=current&AccountIndex=0\")]")).click();**
CODE-
package com.lazerycode.selenium.filedownloader;
import org.apache.commons.io.FileUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.params.ClientPNames;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.log4j.Logger;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Set;
public class FileDownloader {
private static final Logger LOG = Logger.getLogger(FileDownloader.class);
private WebDriver driver;
private String localDownloadPath = System.getProperty("java.io.tmpdir");
private boolean followRedirects = true;
private boolean mimicWebDriverCookieState = true;
private int httpStatusOfLastDownloadAttempt = 0;
public FileDownloader(WebDriver driverObject) {
this.driver = driverObject;
}
/**
* Specify if the FileDownloader class should follow redirects when trying to download a file
*
* #param value
*/
public void followRedirectsWhenDownloading(boolean value) {
this.followRedirects = value;
}
/**
* Get the current location that files will be downloaded to.
*
* #return The filepath that the file will be downloaded to.
*/
public String localDownloadPath() {
return this.localDownloadPath;
}
/**
* Set the path that files will be downloaded to.
*
* #param filePath The filepath that the file will be downloaded to.
*/
public void localDownloadPath(String filePath) {
this.localDownloadPath = filePath;
}
/**
* Download the file specified in the href attribute of a WebElement
*
* #param element
* #return
* #throws Exception
*/
public String downloadFile(WebElement element) throws Exception {
return downloader(element, "href");
}
/**
* Download the image specified in the src attribute of a WebElement
*
* #param element
* #return
* #throws Exception
*/
public String downloadImage(WebElement element) throws Exception {
return downloader(element, "src");
}
/**
* Gets the HTTP status code of the last download file attempt
*
* #return
*/
public int getHTTPStatusOfLastDownloadAttempt() {
return this.httpStatusOfLastDownloadAttempt;
}
/**
* Mimic the cookie state of WebDriver (Defaults to true)
* This will enable you to access files that are only available when logged in.
* If set to false the connection will be made as an anonymouse user
*
* #param value
*/
public void mimicWebDriverCookieState(boolean value) {
this.mimicWebDriverCookieState = value;
}
/**
* Load in all the cookies WebDriver currently knows about so that we can mimic the browser cookie state
*
* #param seleniumCookieSet
* #return
*/
private BasicCookieStore mimicCookieState(Set seleniumCookieSet) {
BasicCookieStore mimicWebDriverCookieStore = new BasicCookieStore();
for (Cookie seleniumCookie : seleniumCookieSet) {
BasicClientCookie duplicateCookie = new BasicClientCookie(seleniumCookie.getName(), seleniumCookie.getValue());
duplicateCookie.setDomain(seleniumCookie.getDomain());
duplicateCookie.setSecure(seleniumCookie.isSecure());
duplicateCookie.setExpiryDate(seleniumCookie.getExpiry());
duplicateCookie.setPath(seleniumCookie.getPath());
mimicWebDriverCookieStore.addCookie(duplicateCookie);
}
return mimicWebDriverCookieStore;
}
/**
* Perform the file/image download.
*
* #param element
* #param attribute
* #return
* #throws IOException
* #throws NullPointerException
*/
private String downloader(WebElement element, String attribute) throws IOException, NullPointerException, URISyntaxException {
String fileToDownloadLocation = element.getAttribute(attribute);
if (fileToDownloadLocation.trim().equals("")) throw new NullPointerException("The element you have specified does not link to anything!");
URL fileToDownload = new URL(fileToDownloadLocation);
File downloadedFile = new File(this.localDownloadPath + fileToDownload.getFile().replaceFirst("/|\\\\", ""));
if (downloadedFile.canWrite() == false) downloadedFile.setWritable(true);
HttpClient client = new DefaultHttpClient();
BasicHttpContext localContext = new BasicHttpContext();
LOG.info("Mimic WebDriver cookie state: " + this.mimicWebDriverCookieState);
if (this.mimicWebDriverCookieState) {
localContext.setAttribute(ClientContext.COOKIE_STORE, mimicCookieState(this.driver.manage().getCookies()));
}
HttpGet httpget = new HttpGet(fileToDownload.toURI());
HttpParams httpRequestParameters = httpget.getParams();
httpRequestParameters.setParameter(ClientPNames.HANDLE_REDIRECTS, this.followRedirects);
httpget.setParams(httpRequestParameters);
LOG.info("Sending GET request for: " + httpget.getURI());
HttpResponse response = client.execute(httpget, localContext);
this.httpStatusOfLastDownloadAttempt = response.getStatusLine().getStatusCode();
LOG.info("HTTP GET request status: " + this.httpStatusOfLastDownloadAttempt);
LOG.info("Downloading file: " + downloadedFile.getName());
FileUtils.copyInputStreamToFile(response.getEntity().getContent(), downloadedFile);
response.getEntity().getContent().close();
String downloadedFileAbsolutePath = downloadedFile.getAbsolutePath();
LOG.info("File downloaded to '" + downloadedFileAbsolutePath + "'");
return downloadedFileAbsolutePath;
}
}
String s = driver.findElement(By.cssSelector("#navbtm img")).getAttribute("src");
URL url = new URL(s);
System.out.println(url);
BufferedImage bufImgOne = ImageIO.read(url);
ImageIO.write(bufImgOne, "png", new File("test.png"));
I have found an excellent article about it. Tried, and works perfectly:
http://ardesco.lazerycode.com/index.php/2012/07/how-to-download-files-with-selenium-and-why-you-shouldnt/
UPDATE:
Better solution is to get the image from the browser itself:
https://groups.google.com/forum/#!msg/selenium-users/8atiPIh39OY/Gp9_KEXnpRUJ

Categories