How to display Excel, PDf files from Webservice on AEM pages - aem

I'm trying to do the following: The response of a webservice is an excel (a separate call for pdf) file. I need to show this file as a link on the aem-page, and whne users click the link, the browser opens (or downloads) the file.
Use case: On the customer page, there is a section with links to Order History (Excel file), Invoice(PDF file), Products catalog(Excel file). Clicking on each link, makes a call to webservice and fetches the respective file.
how to achieve this?

With help from Scott:
http://help-forums.adobe.com/content/adobeforums/en/experience-manager-forum/adobe-experience-manager.topic.html/forum__xhh5-objective_therespo.html
Here's my solution:
From the UI, submit the action to Sling Servlet
<form name="importFileForm" method="get" action="/services/getData">
<input type="submit" title="Submit" value="Submit" name="bttnAction">
</form>
Your Servlet class
public class TTIGetServlet extends SlingAllMethodsServlet {
#Override
protected void doGet(SlingHttpServletRequest request,SlingHttpServletResponse response) throws ServletException,IOException {
...
...
String serviceurl = <<< your webservice url>>>
HttpClient httpclient = HttpClients.custom().build();
generateFile(serviceurl, httpclient, request, response);
RequestDispatcher dispatcher = request.getRequestDispatcher("/content/ttii/en/importfiletest.html");
dispatcher.forward(request, response);
}
}
Generate File method that pops up the file download on browser
public static void generateFile(String serviceurl,
HttpClient httpclient,
SlingHttpServletRequest httpRequest,
SlingHttpServletResponse httpResponse) throws ClientProtocolException, IOException {
HttpResponse response;
HttpGet httpGet = new HttpGet(serviceURL);
// Makes the call to WebService
response = httpclient.execute(httpGet);
// CORE LOGIC
if (response!=null) {
ContentType contentType = ContentType.getOrDefault(response.getEntity());
String mimeType = contentType.getMimeType();
if (mimeType.equals(MIMETYPE_JSON)) {
// Out of context here...
} else {
// SHOW THE FILE
ServletOutputStream sos = httpResponse.getOutputStream();
httpResponse.setContentType("application/vnd.ms-excel");
httpResponse.setHeader("Content-Disposition", "attachment;filename=test.xls");
BufferedHttpEntity buf = new BufferedHttpEntity(response.getEntity());
InputStream istream = buf.getContent();
sos.write(FileHelper.writeFiles(istream));
sos.flush();
}
}
}

Related

How to display a Jasper report PDF Stream in a new tab post ajax request success

In the below code I am able to export the jasper report (.jasper) file is exported as an HTML or a PDF file into the local file system but am not able to show the report as a pdf in a new window/tab.
How do I do that?
Spring Controller class method handling jasper report pdf creation
#Controller
#RequestMapping("/MySearchCtrl")
MySearchCtrl {
#Autowired
ServletConext servletContext;
#RequestMapping(value="/loadJasperReport", method=RequestMethod.GET)
public void loadJaspeeReport(HttpServletResponse response, HttpServletRequest request){
String reportSrcFile = "/WEB-INF/MyReport.jasper";
try {
response.setContentType("application/pdf");
response.addHeader("Content-Disposition","attachment;inline=My_"Report.pdf");
List<MyReportBean> beanList = new ArrayList<MyReportBean>();
// add the beans to the beanList here
InputStream is = this.getClass().getClassLoader().getResourceAsStream(servletContext.getRealPath(reportSrcFile));
JasperReport jasperReport = (JasperReport)JRLoader.loadObjct(is);
JRBeanCollectionDataSource beanCollectionDataSource = new JRBeanCollectionDataSource(beanList);
Map<String,Object> parameters = new HashMap<String,Object>();
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport,parameters,beanCollectionDataSource);
JasperExportManager.exportReportToPdfStream(jasperPrint,response.getOutputStream()); // DOES NOT WORK. NO ERROR Either
JasperExportManager.exportReportToHtmlFile(jasperPrint,"C:\\Users\dipak\Deskop\report.html"); // DOES WORK
JasperExportManager.exportReportToPdfFile(jasperPrint,"C:\\Users\dipak\Deskop\report1.pdf"); //DOES WORK
} catch(Exception e){
e.printStackTrace();
}
}
}
My Javascript code calling the above Spring method
function generateJasperReport(){
$.ajax({
type:"GET",
async:false,
url:"/MySearch/SearchResulkts/MySearchCtrl/loadJasperReport",
data:{},
success:function(data){
// TODO data is the pdf stream exported by Jasperreports and i need to display it in a new tab
console.log(data);
},
})}
Js file changes
function generateJasperReport(){
window.open('/MySearch/SearchResults/MySearchCtrl/loadJasperReport/'+requestParameter,'_blank');
//_blank is to open in a new tab
}
Servlet Ctrl changes
#RequestMapping(value="/loadJasperReport/{requestParam}", method=RequestMethod.GET)
public void loadJaspeeReport(#PathVariable String requestParam, HttpServletResponse response, HttpServletRequest request){
// introduced #PathVariable and added requestParam to #RequestMapping
// remaining code remains same as in question
}

smartgwt spring servlet and uploading files

I've seen this question here before, but none of the solutions work for me.
I have a SmartGWT app with Spring MVC. This all works great, and I have working RESTful web-services.
I have a form to upload not only the file, but also some meta data as well.
There is an associated DataSource with this form:
private final String DEFAULT_FILE_UPLOAD_SERVICE_PATH = "upload";
private final String TARGET = "uploadTarget";
public FileUploadForm()
{
setEncoding(Encoding.MULTIPART);
setMethod(FormMethod.POST);
setAutoFetchData(false);
setDataSource(fileUploadDS);
setTitleOrientation(TitleOrientation.TOP);
setNumCols(1);
setColWidths("*");
uploadFileIdItem.setRequired(true);
uploadFileIdItem.setDefaultValue(0);
uploadFileIdItem.setVisible(false);
uploadFileIdItem.setShowTitle(false);
// ==========================================================================
fileUploadTypeSelectItem.setShowTitle(false);
fileUploadTypeSelectItem.setName(Constants.FILE_UPLOAD_UPLOADTYPE);
fileUploadTypeSelectItem.setPickListWidth(TEXT_SIZE);
fileUploadTypeSelectItem.setTitle(Constants.TITLE_FILE_UPLOAD_UPLOADTYPE);
fileUploadTypeSelectItem.setOptionDataSource(fileUploadTypeDS);
fileUploadTypeSelectItem.setRequired(true);
fileUploadTypeSelectItem.setDisplayField(Constants.FILE_UPLOAD_UPLOADTYPE_NAME);
fileUploadTypeSelectItem.setValueField(Constants.FILE_UPLOAD_UPLOADTYPE_ID);
fileUploadTypeSelectItem.setDataPath("fileUploadType/fileUploadTypeId");
// ==========================================================================
setAction(GWT.getHostPageBaseURL() + "rest/" + DEFAULT_FILE_UPLOAD_SERVICE_PATH);
ButtonItem uploadButton = new ButtonItem("Upload");
uploadButton.addClickHandler(new com.smartgwt.client.widgets.form.fields.events.ClickHandler()
{
#Override
public void onClick(com.smartgwt.client.widgets.form.fields.events.ClickEvent event)
{
submitForm();
}
});
FileItem uploadItem = new FileItem(Constants.FILENAME);
uploadItem.setTitle(Constants.FILENAME);
setFields(uploadFileIdItem, fileUploadTypeSelectItem, uploadItem, uploadButton);
}
So, I don't know if I need to use:
setAction(GWT.getHostPageBaseURL() + "rest/" + DEFAULT_FILE_UPLOAD_SERVICE_PATH);
or
setAction(GWT.getHostPageBaseURL() + DEFAULT_FILE_UPLOAD_SERVICE_PATH);
or
setAction(GWT.getHostPageBaseURL() + DEFAULT_FILE_UPLOAD_SERVICE_PATH);
None of these seem to work, I submit my data to upload the filename, and I constantly get the HTTP 404 error.
I did not define anything extra special in the web.xml file for servlets.
Instead, the springmvc-servlet contains:
<context:component-scan base-package="com.myself.products.app.server.controller" />
And the servlet is actually defined like:
#SuppressWarnings("serial")
#Controller
#RequestMapping("/upload")
public class FileUploadServlet extends HttpServlet
{
private final Logger logger = LoggerFactory.getLogger(FileUploadServlet.class);
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
this.process(request, response);
}
#Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
this.process(request, response);
}
private void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
// check that we have a file upload request
if (ServletFileUpload.isMultipartContent(request))
{
processFiles(request, response);
}
}
private File tmpDir;
private static final String DESTINATION_DIR_PATH = "/files/upload";
private File destinationDir;
public void init(ServletConfig config) throws ServletException
{
super.init(config);
tmpDir = new File(((File) getServletContext().getAttribute("javax.servlet.context.tempdir")).toString());
if (!tmpDir.isDirectory())
{
throw new ServletException(tmpDir.toString() + " is not a directory");
}
logger.debug("tmpDir: " + tmpDir.toString());
String realPath = getServletContext().getRealPath(DESTINATION_DIR_PATH);
destinationDir = new File(realPath);
if (!destinationDir.isDirectory())
{
throw new ServletException(DESTINATION_DIR_PATH + " is not a directory");
}
}
private void processFiles(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException
{
// create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
// set the size threshold, above which content will be stored on disk
factory.setSizeThreshold(1 * 1024 * 1024); // 1 MB
// set the temporary directory (this is where files that exceed the threshold will be stored)
factory.setRepository(tmpDir);
// create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
try
{
// parse the request
List<?> items = upload.parseRequest(request);
// process the uploaded items
Iterator<?> itr = items.iterator();
while (itr.hasNext())
{
FileItem item = (FileItem) itr.next();
// write the uploaded file to the application's file staging area
File file = new File(destinationDir, item.getName());
item.write(file);
}
}
catch (FileUploadException e)
{
logger.error("Error encountered while parsing the request", e);
}
catch (Exception e)
{
logger.error("Error encountered while uploading file", e);
}
}
You've seen this code before along this web-site, and several others.
I'd like to submit the file, AND data if possible, but if not, then how can I submit the form, and then metadata for it?
Any help would be much appreciated.
Simple File Upload GWT Example:
Available here:
http://www.gwtproject.org/javadoc/latest/com/google/gwt/user/client/ui/FileUpload.html
For sending Metadata along with request, need to set the hidden field to panel:
import com.google.gwt.user.client.ui.Hidden;
Hidden hidden = new Hidden();
hidden.setName("json");
hidden.setVisible(false);
hidden.setValue("simpleMetadata:testData");
panel.add(hidden);
I will suggest you to seperate saving metadata from uploding a file and have 2 forms. This is what I'm doing and it is working for me:
uploadForm.setAction(GWT.getHostPageBaseURL() + "importServiceName");
uploadForm.setEncoding(Encoding.MULTIPART);
uploadForm.setTarget(TARGET);
uploadForm.setMethod(FormMethod.POST);
fileItem = new UploadItem("file");
fileItem.setTitle("File");
fileItem.setWidth(300);
NamedFrame frame = new NamedFrame(TARGET);
frame.setWidth("1");
frame.setHeight("1");
frame.setVisible(false);
uploadForm.setItems(fileItem);
I'm using NamedFrame to be able to fetch servlet response in gwt code, but this is different story. I'm defining servler manually in web.xml

GWT RequestBuilder Post Response return 0 StatusCode

I have created a very simple servlet that uses HTTP Post method. I have tested it on my local Apache Tomcat server using a simple HTML form that works. I want to integrate it with my GWT app. I am able to call it using FormPanel - in that case it downloads content and there is a flicker in my browser window.
I know I need to use RequestBuilder to access it. But my response.getStatusCode() in my overloaded public void onResponseReceived(Request request, Response response) method always return status as 0 and response.getText() return null
String url = "http://localhost:8080/servlets/servlet/ShapeColor";
builder = new RequestBuilder(RequestBuilder.POST, URL.encode(url));
try {
String json = getJSONString();
//builder.setTimeoutMillis(10000);
builder.setHeader("Access-Control-Allow-Origin", "*");
builder.setHeader("Content-type", "application/x-www-form-urlencoded");
builder.sendRequest(json, new RequestCallback() {
#Override
public void onError(Request request, Throwable exception) {
Window.alert("Couldn't retrieve JSON");
}
#Override
public void onResponseReceived(Request request, Response response) {
if (200 == response.getStatusCode()) {
System.out.println("res:"+response.getText());
} else {
System.out.println("err: " + response.getStatusCode()+","+response.getText());
}
}
});
//Request response = builder.send();
} catch (RequestException e) {
// TODO Auto-generated catch block
}
I have tried many thing including changing my servlet following CORS reference ( https://code.google.com/p/gwtquery/wiki/Ajax#CORS_%28Cross_Origin_Resource_Sharing%29 )
It always works on browser using my test.html, but not from my App. Although, onResponseReceived method always gets called
Thanks
KKM
Have you checked if your call in the app violates the Same-origin policy (http://en.wikipedia.org/wiki/Same-origin_policy) in some way? The GWT RequestBuilder uses XMLHttpRequest internally, so it does fall under the SOP.
Does your GWT app run inside the same domain (server + port) as the servlet? Does it use the same protocol (https or http)?

Read form file and send its contents to the clinet in GWT

I need to read form TXT file on the server side and send its contents to the client side to print in a label or any thing, i need to know where i place the TXT file is it on the server package or in WAR and how to code it?? thanks
It doens't really matter where you place the file. It must be on the server and a php script must be able to open the file. You can ready the text file the following way with php.
Then make a http request with GWT to that file.
Read the file:
<?php
// get contents of a file into a string
$filename = "/usr/local/something.txt";
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
fclose($handle);
echo $contents;
?>
Make http request:
public class GetExample implements EntryPoint {
public static final int STATUS_CODE_OK = 200;
public static void doGet(String url) {
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, url);
try {
Request response = builder.sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable exception) {
// Code omitted for clarity
}
public void onResponseReceived(Request request, Response response) {
String content = response.getText();
}
});
} catch (RequestException e) {
// Code omitted for clarity
}
}
public void onModuleLoad() {
doGet("/");
}
}

How to post data and redirect to another page using GWT?

When I press a button I post some data to server and there redirect to another page.
I used RequestBuilder but it is waiting the response, and of course get it. And nothing happens, same page stays. I see RequestBuidler shouldn't be used here... What should I use to post data and be able to redirect?
In Spring
#RequestMapping(method=RequestMethod.POST, value="/ddd")
public ModelAndView processOrder(#RequestBody String orderInString, HttpSession session) throws Exception{
...
return new ModelAndView(new RedirectView("abc"));
}
In GWT
public void postData(final String data, final String url) {
RequestBuilder builder = new RequestBuilder(RequestBuilder.POST, url);
try {
builder.sendRequest(data, new RequestCallback() {
public void onError(Request request, Throwable exception) {
...
}
public void onResponseReceived(Request request,
Response response) {
if (200 == response.getStatusCode()) {
..
} else {
..
}
}
});
} catch (RequestException e) {
...
}
return;
}
FormPanel form = new FormPanel("_self");
form.setMethod(FormPanel.METHOD_GET);
Hidden params0 = new Hidden("param1", "value1");
Hidden params1 = new Hidden("param1", "value2");
Hidden params2 = new Hidden("param2", "value3");
FlowPanel panel = new FlowPanel();
panel.add(params0);
panel.add(params1);
panel.add(params2);
form.add(panel);
form.setAction(GWT.getModuleBaseURL() + "../MyServlet");
RootPanel.get().add(form);
form.submit();
Thats it. The code adds FormPanel and sends form.
Add more specifications, code, this is blur.
Since you are using Spring-mvc, you should be having something like this
private static final String newPage = "index2"; //this is resolved with view resolver
#RequestMapping(params = "action=button")
protected String getALPLicense(final RenderRequest request,
final RenderResponse response, final Model model) throws Exception {
try{
}catch{
}
return newPage; //this is your new redirected page
}