ZK multiple webapps in a single project - java

Background:
I programmed 2 ZK web applications (ZK653CE) with netbeans 8.1 both are moduls for a single task.
Now I want to access application B from within application A both projects are on the same Tomcat 8 webserver.
Why I want to do this:
Application A has a user login and presents data to the user. Application B allows anybody to create a pattern for displaying data. I want a user to start application B and create a pattern (Press save close app). This pattern shall be send back to application A that then changes the display behaviour of the data to the new pattern. I do not want to mix those 2 applications together, because I want them to stay independent.
What I already figured out while searching this topic:
It is not possible to directly access an external webapp from within a zk project
It would be possible to use a shared ressource concept from tomcat (but I don't want that because I want this to run on different webservers like glasfish and others)
The real question:
Is there a way to have both apps independent (if yes please explain or show an example) or do I have to merge them?

I had much time to try differnt things I'll show the 2 best solutions I came a cross:
Using Cookies
One can use Cookies to store data at the client and use the server to access it. It's commonly used for sessionmanagement or other parts that control the content for the current user.
To access Cookies one would use this code in a ZK Class (Controller or Viewmodel):
HttpServletRequest req = (HttpServletRequest) Executions.getCurrent().getNativeRequest();
Cookie[] cookies = req.getCookies();
This will load all cookies of the current session. The HttpServletRequest class can be found in the java docs for more information (it represents the raw client http request). One can then iterrate through the array and look for a Cookie
HttpServletResponse resp = (HttpServletResponse) Executions.getCurrent().getNativeResponse();
for(Cookie c : cookies) {
if(c.getName().equals(COOKIE_MODE)) {
externalAccess = Boolean.parseBoolean(c.getValue());
c.setMaxAge(0);
c.setValue(null);
c.setPath(NAMESPACE);
resp.addCookie(c);
}
}
externalAccess stores if the modul was loaded from an external modul. This external module would have to create that Cookie first of course. The set parameters are used to delete the Cookie setting the age to 0 means its expiered one also sets the value and if a path was used to create it one must also set the path because it must be known where the old Cookie was placed. The cookie must be added to a HTTP Response for the client (from the server) so that the client replaces its old Cookie.
To create a cookie one would use this:
Cookie cookie = new Cookie(COOKIE_NAME, COOKIE_VALUE);
cookie.setPath(NAMESPACE);
HttpServletResponse resp = (HttpServletResponse) Executions.getCurrent().getNativeResponse();
resp.addCookie(cookie);
This is very similar to the for loop before.
Approach
Just add a parameter to the URL (commonly used to provide parameters):
If one hase a webserver on localhost its address is probably this:
http://localhost:8080/
a modul is loaded to / or if a subfolder is specified /modul
if one has a .zul in /modul named index.zul
one can access it by using http://localhost:8080/modul/index.zul
if one want's to add a parameter it would be done like this:
http://localhost:8080/modul/index.zul?externalAccess=1
one can then access this in the viewmodel or controller of index.zul (i used MVVM) with the following code:
String external = Executions.getCurrent().getParameter("externalAccess");
One can then cast the parameter to ones liking.
To create a redirect that uses the URL above one can use this:
Executions.sendRedirect("http://localhost:8080/modul/index.zul?externalAccess=1");
one can get the URL to ones server and the current application like this:
Server:
String server = Executions.getCurrent().getScheme() + "://" + Executions.getCurrent().getServerName() + ":" + Executions.getCurrent().getServerPort();
For the path to the application starting with "/":
Executions.getCurrent().getContextPath() + Executions.getCurrent().getDesktop().getRequestPath();
One could also use a config file that has the URLs stored (on webserver) but i won't cover that here

Related

How to create cookies in AEM in Java in ViewHelper?

I have a requirement that I have to create a cookie on server side when page loads. In our AEM project I have a LocatorViewESBOfficeHelper.java file which is mapped to the JSP of the component (Say locateOffice). When page loads first time onGetData method of LocatorViewESBOfficeHelper.java is called.
In this method I want to create cookie using following code but I am unable to create it. When I use same create cookie code in a servlet and call it through ajax call, it successfully create cookie.
One possible reason could be when page is fully loaded, the response object could not have cookies. But I am unable to understand how to manage it.
You might have several problems.
Edit-Mode
You will not see session cookies in the editor, because your page is inside an iframe. Just do "View as published" (?wcmmode=disabled) to get your page directly in the browser window.
Wrong response object
The mapping LocatorViewESBOfficeHelper.java to the component sounds like someone tried to do some magic. Maybe your service doesn't get the real response object, but more a response wrapper. And the output of your service is somehow validated and written to the real response. In such cases, the http headers are often ignored.
Just create your own real AEM component, were the content is written by a SlingSafeMethodsServlet (registered via the resource type). If this works, you know where to go.
The following servlet does work good for me:
#Component(
service = Servlet.class,
property = {
SLING_SERVLET_RESOURCE_TYPES + "=/apps/myproject/components/cookie-test",
SLING_SERVLET_METHODS + "=GET",
SLING_SERVLET_EXTENSIONS + "=html"
})
public class CookieTestServlet extends SlingSafeMethodsServlet {
#Override
protected void doGet(#Nonnull SlingHttpServletRequest request, #Nonnull SlingHttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("<h2>Cookie Test</h2>");
Cookie cookie = new Cookie("alex", "this-is-a-test-" + (System.currentTimeMillis() % 10000));
response.addCookie(cookie);
}
}
Response buffer already flushed
The HttpServletResponse is more like a buffered Writer or OutputStream. You can only add http headers (or cookies) as long as the response output buffer was not flushed yet.
To verify this, either use the test component on a smaller page or simply increase in the OSGi configs the buffer to something real high (e.g. 1MB - but on your local instance only). Therefore go to the web console / OSGi / Configuration / Apache Felix Jetty Based Http Service / Response buffer size
(http://localhost:4502/system/console/configMgr/org.apache.felix.http)
I don't recommend to change it in production. So you should find another way to be early in the content generation. As most extreme workaround you could use a Sling request filter.
Opt-Out-Filter
If your project uses the Adobe Granite Opt-Out Service, then you might have to whitelist your cookie in the OSGi configuration. By default this service should not do anything.
Try Other Alternatives
As alternative I would propose:
Use a Sling Filter
Create the Cookie front-end with JavaScript
I hope one of my ideas might point you in the right direction.
Alex

AngularJs: Can not read cookies sent from server

I've browsed a bunch of questions that are similar to mine, but none of the solutions I have tried seem to work.
I have a Jersey2.0 REST service that adds a cookie to the response and returns it to an Angularjs front end application. I already have the setup done correctly (Access-Control-Allow-Credentials=true, no wildcard in Access-Control-Allow-Origin, etc..).
I do it by adding a "SET-COOKIE" header on the response like so:
MultivaluedMap<String, Object> headers = responseContext.getHeaders();
headers.add("SET-COOKIE", new NewCookie(cookieName, cookieValue);
This works, and I can see the cookie being returned in the response of that particular REST service call to that particular REST endpoint. What I mean is, on the Chrome developer console under the Network tab, I can click on the request that is supposed to return the cookie, and in both the 'Cookies' and 'Headers' tabs, I can see the cookie being returned in the response. In fact, when I make another request to the endpoint, that same cookie is now sent in the request and I can capture it on the Jersey server.
Great. The issue is that the cookie is not showing up on the 'Resources' tab. If I click on the 'Resources' tab, then along the left select the 'Cookies' dropdown and then select localhost, the cookie I'm trying to send in the response is not there. I'm assuming this is also why when I try to get the cookie in my AngularJs application via $cookies.get('cookieId'); using ngCookies, I get undefined.
Also, just in case someone mentions it in an answer/comments, I'm pretty sure the problem here is not HttpOnly. My JSESSIONID cookie gets returned, and I can see it in the 'Resources' tab with the Http field checked indicating HttpOnly.
I thought maybe because I'm in a corporate environment, they don't let me add cookies, but I'm able to do this on the Angular front end via $Cookies.put('cookieId', 'cookieValue'); and it shows on the 'Resources' tab just fine.
Any help as to why my cookies are not being added from the server?
After digging through a few more stackoverflow questions relating to my original one, I found out through this stackoverflow question that cookies that are created on one domain cannot be accessed on another domain using Javascript.
I will have to come up with a workaround for this, but my original question has been answered so marking this as answered.
For your case it is easy to solve if you just set the path of the cookie,
e.g.
Cookie myCookie = new Cookie("Name_of_cookie", "String_value_of_cookie")
myCookie.setPath("/the domain Js is using ")
Or just leave it as / for the main domain that most probably Js is deployed.

how to rewrite the url in java web application?

On Form Submit my url changes from
localhost:8080/Workflow/admin/GetReports?fname=Form1
to
localhost:8080/Workflow/admin/EditReport
Form action is EditReport(Servlet Name).
Now on EditReport i perform the databse operations and forward the request to the GetReports?fname=Formname Servlet using Request Dispatcher.So that i am on the same page which is the first one (1) i started from.
Now Everything works fine on the .jsp page But the url remains unchanged that is the second one (2).
So how to rewrite the url i.e. from admin/EditReport to /admin/GetReports?fname=Form1
Are you using dispatcher.forward because you are setting some Attributes in
the Request?
If not, then you don't need to use Forward. Instead of that, use response.sendRedirect("url for GetReports?fname=Form1")
But If you are setting some Attributes in the request, then I am wondering if your workflow is a correct one because URLs like this "Workflow/admin/GetReports?fname=Form1" should Not be arrived upon after doing some processing. They should be simple HTTP GET requests only.

Handling the http cookie from GWT module

I have a small confusion about Cookies, whenever the user is logging in we create cookies and adding to the response header.
Cookie cookie = new Cookie("sessionId", "232hghjghghgh"); // http cookie.
cookie.setVersion(1);
cookie.setPath("/");
cookie.setMaxAge(1000);
response.addCookie(cookie);
I think the above will be setting into the browser cache and we can get it from the browser cookies.
In our GWT module we already have an existing implementation like
Cookies.getCookie("sessionId"); // Cookies are from GWT
We are able to get the cookie using above line without using anywhere Cookies.setCookie() method.
Is that because of above line response.addCookie(cookie).
Could any body tell me, is my assumption correct?
Yes. Your first example is using a javax.servlet.http.Cookie, and this happens on the server side. The latter is purely GWT (i.e. client side) and returns java.lang.String (i.e. the String value of the cookie). But of course both are conceptually the same and setting one on the server will make the other show up on the client.

Manage Session when broswer has disable cookies

I wants to know that How can i Manage Session if the client browser has disabled cookie feature..
If I wants to implement it in simple JSP - Servlet, then how can I do that ?
Thanks in advance...
Without cookies, you have two options. The first is passing a sessionId through Urls. This requires a lot of work on the server because every url you send back must have a sessionId appended to it (usually in the form of a query string parameter). For example:
/path/to/page
becomes
/path/to/page?sessionid=ASDFG-ASDFG-ASDFG-ASDFG-ASDFG
The other option you have would be to combine what information you have via http into a "unique" key and create your own session bucket. By combining the Http UserAgent, RemoteIp and RemoteXfip you can get close to uniquely identifying a user, but there is no guarantees that this key is 100% unique.
In the JSP side, you can use JSTL's <c:url> for this.
link
Easy as that. It will automagically append the jsessionid when cookies are disabled.
In the Servlet side you need HttpServletResponse#encodeURL() or -usually the preferred one inside Servlets- HttpServletResponse#encodeRedirectURL() for this.
response.sendRedirect(response.encodeRedirectURL("page.jsp"));
url rewriting
http://www.developertutorials.com/tutorials/java/implement-session-tracking-050611/page5.html
Each URL must be encoded using response.encodeURL("page.jsp")
This will add the Session ID onto the end of each URL so cookies do not have to be enabled.
Note that you will have to do this manually for every single URL in order for it to work.
See this link for more info.

Categories