I have been trying to display a pdf report in a web browser using ServletOutputStream. So far, I am able to download the file but I cannot get it to display in the browser. Here is my code
private void initReport()
{
DBConnection connection = new DBConnection();
try {
jasperPrint = JasperFillManager.fillReport(getContext().getExternalContext().getRealPath("/WEB-INF/reports/testReport.jasper"), new HashMap(),connection.getConnection());
} catch (JRException ex) {
Logger.getLogger(ReportBacking.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void showPDF()
{
initReport();
try {
HttpServletResponse httpServletResponse;httpServletResponse = (HttpServletResponse) getContext().getExternalContext().getResponse();
httpServletResponse.setContentType("application/pdf");
httpServletResponse.addHeader("Content-disposition", "inline;filename=testReport.pdf");
ServletOutputStream servletOutputStream = httpServletResponse.getOutputStream();
JasperExportManager.exportReportToPdfStream(jasperPrint,servletOutputStream);
getContext().responseComplete();
getContext().renderResponse();
} catch (JRException | IOException ex) {
Logger.getLogger(CertificateApplicationAddBacking.class.getName()).log(Level.SEVERE, null, ex);
getContext().addMessage(null, new FacesMessage("Could not generate report"));
}
If I change the content-diposition to attachment. I am able to download the file.
Whether it downloads or displays in the browser is out of your control. Its a setting in the browser or in Acrobat, or a combination, which only the user can change (if they know how).
However, you could use a Flash/Silverlight app that let's you load a PDF into it, or find a way to use PDF.js by passing your PDF bytes from the server to PDF.js and having it render the PDF in the browser. Look at the examples page. Where they do:
PDFJS.getDocument('helloworld.pdf').then(function(pdf) {
// you can now use *pdf* here
});
You can change 'helloworld.pdf' to the URL of your servlet.
Related
I want to achieve microfrontend architecture using Apache Wicket but I cannot make it work.
add(new WebMarkupContainer("testFrame") {
#Override
protected void onComponentTag(ComponentTag tag) {
checkComponentTag(tag, "iframe");
super.onComponentTag(tag);
//Won't work like this if you want to send credentials.
//tag.put("src", "http://localhost:8089/httpBasicAuthenticated/url/page/");
}
#Override
public void onComponentTagBody(MarkupStream markupStream, ComponentTag openTag) {
Response response = getRequestCycle().getResponse();
final CredentialsProvider provider = new BasicCredentialsProvider();
String username = "user";
String password = "password";
final UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(username, password);
provider.setCredentials(AuthScope.ANY, credentials);
final HttpClient client = HttpClientBuilder.create().setDefaultCredentialsProvider(provider).build();
HttpResponse httpResponse = null;
String body = "";
try {
httpResponse = client.execute(new
HttpGet("http://localhost:8089/httpBasicAuthenticated/url/page/"));
body = IOUtils.toString(httpResponse.getEntity().getContent(), "UTF-8");
} catch (final IOException e) {
e.printStackTrace();
}
response.write(body);
}
});
Result from inspecting the element
I am trying out with an iframe but it's not rendering the page inside the iframe. Is there something wrong? How would I send the credentials on request of the page through iframe?
EDIT:
In this code, I'm trying to send the credentials automatically so that the authentication prompt doesn't show.
With basic authentication you need to render <iframe src="..."></iframe> and the browser will show you a dialog to enter the credentials.
If you construct the body at the server (i.e. in Wicket code) then you don't need an iframe, but a div.
i am writing my own image import for my product catalog. I want to read the images from the local filesystem and store them in the configured assets folder. The import is very simple for now. Its one controller in the admin project and i trigger it by calling an url.
It is creating the files along with the folder structure and the files seem to have the same filesize, but somehow they get messed up along the way and they are not readable as images anymore (picture viewers wont open them). Any ideas why its being messed up ?
here the code:
#Controller("blImageImportController")
#RequestMapping("/imageimport")
public class ImageImportController extends AdminAbstractController {
#Value("${image.import.folder.location}")
private String importFolderLocation;
#Resource(name = "blStaticAssetService")
protected StaticAssetService staticAssetService;
#Resource(name = "blStaticAssetStorageService")
protected StaticAssetStorageService staticAssetStorageService;
#RequestMapping(method = {RequestMethod.GET})
public String chooseMediaForMapKey(HttpServletRequest request,
HttpServletResponse response,
Model model
) throws Exception {
File imageImportFolder = new File(importFolderLocation);
if (imageImportFolder.isDirectory()) {
Arrays.stream(imageImportFolder.listFiles()).forEach(directory ->
{
if (directory.isDirectory()) {
Arrays.stream(directory.listFiles()).forEach(this::processFile);
}
});
}
return "";
}
private void processFile(File file) {
FileInputStream fis = null;
try {
HashMap properties = new HashMap();
properties.put("entityType", "product");
properties.put("entityId", file.getParentFile().getName());
fis = new FileInputStream(file);
StaticAsset staticAsset = this.staticAssetService.createStaticAsset(fis, file.getName(), file.length(), properties);
this.staticAssetStorageService.createStaticAssetStorage(fis, staticAsset);
fis.close();
} catch (Exception e) {
} finally {
try {
if (fis != null)
fis.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
There is a check in the StaticAssetService to try to detect this as an image (see https://github.com/BroadleafCommerce/BroadleafCommerce/blob/b55848f/admin/broadleaf-contentmanagement-module/src/main/java/org/broadleafcommerce/cms/file/service/StaticAssetServiceImpl.java#L217-L220). If it detected this correctly, you should get back an ImageStaticAssetImpl in the result to that call.
The flipside of this is the controller that actually reads the file (the StaticAssetViewController that renders a StaticAssetView). One of the things that the StaticAssetView does is set a response header for mimeType which the browser uses to render. This is set by this piece in the StaticAssetStorageService: https://github.com/BroadleafCommerce/BroadleafCommerce/blob/b55848f837f26022a620f0c2c143eed7902ba3f1/admin/broadleaf-contentmanagement-module/src/main/java/org/broadleafcommerce/cms/file/service/StaticAssetStorageServiceImpl.java#L213. I suspect that is the root of your problem.
Also just a note, sending those properties is not necessary when you are uploading the file yourself. That is mainly used in the admin when you are uploading an image for a specific entity (like a product or a category).
I have looked in so many places on a lead on how or if it is possible to view images uploaded to cloudinary, by a specific tag through Android studio app i am trying to build.
I was able to implement the upload option by user, with adding a tag to the images, and public id, also retrieving these information, but i cant find anything on how to view these images, for example i want the app to be able to view all images with a specific tag ( username ) to the user that uploaded the pictures, and could delete them ? and also view other images uploaded by other user with no other permission.
Is it possible and how !?
I ended up with this code, and i encountered a problem;
#Override
public void onClick(View v) {
new JsonTask().execute("http://res.cloudinary.com/cloudNAme/video/list/xxxxxxxxxxxxxxxxxxx.json");
// uploadExtract();
}
});
public class JsonTask extends AsyncTask<String ,String,String> {
#Override
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
return buffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
In the log i get the following;
03-28 12:36:14.726 20333-21459/net.we4x4.we4x4 W/System.err: java.io.FileNotFoundException: http://res.cloudinary.com/we4x4/video/list/3c42f867-8c3a-423b-89e8-3fb777ab76f8.json
i am not sure if my understanding is correct of the method or i am doing something wrong ? since in the Admin API Docs. or cloudinary the syntax for the HTML request and also in the suggested page by Nadav:
https://support.cloudinary.com/hc/en-us/articles/203189031-How-to-retrieve-a-list-of-all-resources-sharing-the-same-tag-
this should've returned a JSON ?
The following feature allows you to retrieve a JSON formatted list of resources that which share a common tag:
https://support.cloudinary.com/hc/en-us/articles/203189031-How-to-retrieve-a-list-of-all-resources-sharing-the-same-tag-
Note that image removal will coerce you to use server-side code (e.g. JAVA), since deleting via Cloudinary requires a signature that is based on your API_SECRET.
I am using PrimeFaces 5.1 and JSF 2.2
Following is my code: I am generating PDF file from TableModelDate method all works fine. But it is opening in my browser How can i download it without opening.
public void PDF() throws JRException, IOException {
HttpServletResponse httpServletResponse = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();
simpleReport();
httpServletResponse.addHeader("Content-disposition", "filename=report.pdf");
ServletOutputStream servletOutputStream = httpServletResponse.getOutputStream();
JasperExportManager.exportReportToPdfStream(jasperPrint,servletOutputStream);
FacesContext.getCurrentInstance().responseComplete();
}
public void simpleReport() {
TableModelData();
try {
String reportPath = FacesContext.getCurrentInstance().getExternalContext().getRealPath("/reports/");
JasperCompileManager.compileReportToFile(reportPath+"/Report.jrxml");
jasperPrint = JasperFillManager.fillReport(reportPath+"/Report.jasper", new HashMap(),new JRTableModelDataSource(tableModel));
} catch (JRException ex) {
ex.printStackTrace();
}
}
You are very close to it.
just add attachment; statement with the filename=xx.pdf
Like:
httpServletResponse.addHeader("Content-disposition", "attachment; filename=report.pdf");
It tells Http Servlet Responce that the file contains is attachment;
Extra:
Whenever browser opens PDF format it also shows saving option you can also save it after opening(loading) in browser
I am generating a PDF invoice with JR. On my local machine (linux ubuntu) works perfectly:
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
String templateAbsolutePath = ec.getRealPath(templateRelativePath);
JasperReport jasperReport;
try {
jasperReport = JasperCompileManager.compileReport(templateAbsolutePath);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, getParametriFattura(fattura), datasource );
JasperExportManager.exportReportToPdfStream(jasperPrint, ec.getResponseOutputStream());
} catch (JRException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
fc.responseComplete();
However, when I deployed my war to the staging server (linux ubuntu) it shows that:
I suppose it's a trivial problem, but where can I start from?
I deliberately omitted configurations, system details and so on... because I don't know what can be useful.
You need to explicitly tell the webbrowser that it's a PDF file, not a (X)HTML file.
ec.setResponseContentType("application/pdf");
Note: this needs to be set before any bit is written to the response body.