Get html output from a jcr node in CQ5 - aem

I wanted to know if there is a way to get the rendered HTML output of a Page node in CQ5 without hitting the actual url. I have the Page node and I want to get the rendered HTML output of that Page node programmatically in java and store it in a string without hitting the page URL.
Any help is appreciated, thanks in advance!

Node itself it's just a data. Sling framework responsible for rendering this data. It use a bunch of rules to determine how this data should be rendered.Sling Script Resolution Cheet Sheet As Sling is web framework it renders data via http requests.
To emulate this request in CQ/AEM I suggest to use com.day.cq.contentsync.handler.util.RequestResponseFactory service
import org.apache.sling.engine.SlingRequestProcessor;
import com.day.cq.contentsync.handler.util.RequestResponseFactory;
#Reference
private RequestResponseFactory requestResponseFactory;
#Reference
private SlingRequestProcessor requestProcessor;
public String doStuff(){
HttpServletRequest request = requestResponseFactory.createRequest("GET", "/path/to/your/node.html");
request.setAttribute(WCMMode.REQUEST_ATTRIBUTE_NAME, WCMMode.DISABLED);
ByteArrayOutputStream out = new ByteArrayOutputStream();
HttpServletResponse response = requestResponseFactory.createResponse(out);
requestProcessor.processRequest(request, response, resourceResolver);
return out.toString(response.getCharacterEncoding());
}
Hope it helps.

You can access node by providing a correct view. As you need rendered html view, use .html with your node to get rendered html. So your node path will be
/content/path/to/page/jcr:content/par/node_name.html
Now to read html programmatically, you can make an http request to above path from your path, and save response as string.

Related

AEM servlet for a component that is not under /content?

My goal is to create a token whenever a page is rendered that contains a component called someTeaser. This someTeaser component renders in the template after the content and before the footer and is not editable. It is configured fixed in the template structure.
The problem appears when I want to create a servlet for someTeaser. This component is not in the Content Repository crxde.
#SlingServletResourceTypes(
resourceTypes = {Constants.ResourceTypes.SOME_TEASER},
selectors = {"token"},
extensions = Constants.Extensions.JSON
)
The resource for this component is /conf/xx/settings/wcm/templates/someTemplate/structure/jcr:content/root/main/container/someTeaser. This resource cannot be resolved in publish. It is not under content but rather under conf.
Request URL: https://publish_server/conf/xxx/settings/wcm/templates/someTemplate/structure/jcr:content/root/main/...
Request Method: GET
Status Code: 404 Not Found
An alternative solution would be to use define resourceTypes = {Constants.ResourceTypes.PAGE} in the servlet but then every page will be checked for the selector token.
Can someone suggest an alternative solution for the task?
I was able to request the token for the container that is avaliable in the JCR repository.
String containerPath = PathBuilder.with(currentPage.getPath())
.slash(AemConstants.JCR_CONTENT)
.slash("root/main/container")
.build();
and resolve the container url nicely using resourceResolver.map(path).

How can I avoid that my URL changes when I upload a file using servlets in GWT?

I have the option to upload a file in my webapp, and I already have it done, but there is a problem: the browser redirects me to "base_url" + the url-pattern defined in the web.xml file after the upload is done. I know that should be normal because I'm defining it in the <url-pattern> tag. However, I want that my webapp stays in the current url, how can I achieve this?
<servlet-name>uploadServlet</servlet-name>
<servlet-class>com.premium.server.FileUploadServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>uploadServlet</servlet-name>
<url-pattern>/Project/upload</url-pattern>
</servlet-mapping>
Note: I've already tried this <url-pattern>/</url-pattern> and this <url-pattern>/*</url-pattern> but didn't work.
private static final String UPLOAD_ACTION_URL = GWT.getModuleBaseURL() + "upload";
public void onModuleLoad() {
final DynamicForm form = new DynamicForm();
form.setAction(UPLOAD_ACTION_URL);
form.setEncoding(Encoding.MULTIPART);
form.setMethod(FormMethod.POST);
SubmitItem submit = new SubmitItem("a", "Submit");
submit.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
form.submitForm();
}
});
UploadItem upload = new UploadItem();
upload.setName("uploadFormElement");
form.setFields(upload, submit);
VLayout panel = new VLayout();
panel.addMember(form);
RootPanel.get().add(form);
According to SmartGWT's documentation, this is the expected behavior:
Upload without the Smart GWT Server
If it is acceptable that the application will do a full-page reload after the upload completes, you can simply:
set encoding to "multipart"
include an UploadItem to get a basic HTML upload control
set action to a URL where you have deployed server-side code to handle the upload
call DynamicForm.submitForm to cause the form to be submitted
This cause the DynamicForm component to submit to the form.action URL like an ordinary HTML element. Many online tutorials are available which explain how to handle HTML form file upload in various server-side technologies.
Note that when you submitForm(), the only values that will be sent to your actionURL are values for which actual FormItems exist. This differs from saveData(), in which the entire set of form values are always sent. To handle submitting extra values, use HiddenItems.
For further details, see the UploadItem docs.
— Source: http://www.smartclient.com/smartgwtee-latest/javadoc/com/smartgwt/client/docs/Upload.html
What you're probably looking for is what they call background upload:
Background upload without the Smart GWT Server
Achieving background file upload without using the Smart GWT server is also possible although considerably more advanced. In addition to the steps above, create a hidden <iframe> element in the page, and use target to target the form submission at this IFRAME. In order receive a callback notification when the upload completes, after processing the file upload, your server should output HTML content for the IFRAME that includes a <SCRIPT> block which will navigate out of the IFRAME (generally via the JavaScript global "top") and call a global method you have declared as a callback.
— Source: http://www.smartclient.com/smartgwtee-latest/javadoc/com/smartgwt/client/docs/Upload.html
Note: the FormPanel widget from GWT proper defaults to background upload.

GWT:How to generate pdf save/open window?

I am using GWT2.4 version in my application.In this I application I have created Form using GWT control (like textbox,textaera).
I have also created preview of form.In that preview I have button of pdf generation.
Now I want to create behavior to deal with pdf link same as browsers(Mozilla/chrome).
For example in Mozilla on click of pdf link it asks for either save or open in a pop up window.
While debugging I found a jar name iText which can be used to create pdf, I want to implement browsers behavior in this also.
Please help me out.
Thanks in advance.
Read file contents into byte array.
Then do request for servlet or service, for eg. this way:
Window.Location.replace("rest/downloadPdf");
That Service should return Response with the right content type:
#Path("downloadPdf")
#GET
#Produces({"application/pdf"})
#Consumes(MediaType.TEXT_PLAIN)
public Response downloadPdf() throws Exception {
byte[] bytes = getYourPDFContents();
return Response
.ok(bytes, MediaType.APPLICATION_OCTET_STREAM)
.header("Content-Disposition", "attachment; filename=\"yourFile.pdf\"")
.build();
}
Browser will then show save as dialog.
That's example of Service, you must include Jersey library into your project to be able to use method like I've wrote above .

GWT and Panda Video Converter

I'm writing GWT application where I need to upload video file and encode that video into different video formats. I've decided to use Panda Video Converter. I was able to run panda on my EC2 instance (using their image) and I can upload video from Panda's test pages but now I'm trying to make same thing with my own application in GWT.
The question that I have is: How do I get Video id and how do I post my video to the server. What URL do I need to use for that? I tried to read their documentation but have no clue where to start. This is my fist time working with webservices and url, probably that's why I don't how it works.
Disclaimer: I have no idea how the Panda Video Converter works, this is just an example of using RequestBuilder to make GET and POST requests to a server.
The steps to accomplish this seem to be roughly:
Send a POST to hq.pandastream.com/videos.(yaml|xml) with your account ID as a parameter.
Receive a response including the ID of the new video you've created (a placeholder)
Display a form to the user based on the ID. The form is retrieved by sending a GET to upload.pandastream.com/videos/[id]/form
Submitting this form uploads the video, whose information can be retrieved by sending a GET to GET hq.pandastream.com/videos/id.(yaml|xml)
Since the only elements of this process are POST and GET requests, you can use the RequestBuilder to make these requests for you in GWT.
We'll go through step by step.
Send a POST to hq.pandastream.com/videos.xml with your account ID as a parameter.
RequestBuilder rb = new RequestBuilder(RequestBuilder.POST, "http://hq.pandastream.com/videos.xml");
rb.sendRequest("account_key=foo", new RequestCallback() {
protected void onResponseReceived(Request request, Response, response) {
// parse XML to get "id" element
}
// onError() ...
});
Now that you have the ID, you can make another request to get the upload form HTML.
rb = new RequestBuilder(RequestBuilder.GET, "http://upload.pandastream.com/videos/" + id + "/form");
rb.sendRequest(null, new RequestCallback() {
protected void onResponseReceived(Request request, Response, response) {
// this may not work, and it may be a bad idea to inject third-party HTML
// straight into your page. You might also want to open a popup window
// instead of injecting the HTML directly.
someWidget.setHTML(response.getText());
}
// onError() ...
});
With that form, the user uploads the video, etc.
Now, to get info about the video, it's -- you guessed it -- another RequestBuilder call.
rb = new RequestBuilder(RequestBuilder.GET, "http://hq.pandastream.com/videos/" + id + ".xml");
rb.sendRequest(null, new RequestCallback() {
protected void onResponseReceived(Request request, Response, response) {
// parse response XML to get info you want
}
// onError() ...
});
Another disclaimer: This is a very rough outline of what appears to be the process of uploading a video, based on the docs you linked. This just serves as a basic example of using RequestBuilder to make GET/POST calls.
I just wanted to see if you had worked this out. If you need some more help with the open source version feel free to ask on the Google Groups list we have: http://groups.google.com/group/pandastream
You might also be interested in trying out the hosted version we launched publicly last week: http://pandastream.com/
In my opinion, U2Any Video Converter is also a good choice for us because it is practical and professional yet easy to use. It can handle all the problem of converting video/audio formats. Hope my info can help you.

How to stay in same page when executing a Server request in a portlet

I am calling a webpage from a portlet. The webpage is a form for user to enter data and has a button which submits the user data into Database.
But the Button also redirects the portlet site to the webpage through the proxy Gateway.
How to stay in the same portlet page while having the Form data submitted to the database?
You could use AJAX
Just adding to the AJAX answer..
A standard JSR 286 portlet supports such asynchronous action through serveResource method in the portlet class, which you'll need to override.
In the java file,
public void serveResource(ResourceRequest request, ResourceResponse response)
throws PortletException, IOException {
//Write or invoke your database code here...
}
Also, in the html <form> tag you will need to set <portlet:resourceURL> in the action attribute.
Hope this helps, even though I am assuming by portlet you mean Java portlets and not something else