Portal/portlets programming - portlet linking/page flow - java

I am writing my first portlet based application (for liferay, but the solution should be container agnostic) and I am wondering how people solve to provide links to the user that "lead" to different portlets (maybe on different "pages" in the portal).
While you can easily have different view modes inside your portlet, how can you link to another portlet and (maybe) also pass parameters along?
I am not talking about plain communication between portlets, it's the real pageflow that interests me.
Example:
You have page A with a portlet that displays a list of news items. Then you have page B that is in the way configured I'd like a single the news item to be shown (for example different portlets around it)
Is there a generic solution to link to page B and say to the news-Detail-Portlet that it should show item XYZ?
The quick and dirty solution would be to configure the target link via edit mode of the news-list-portlet. But this has several disadvantages:
- complex portlets may have several target URLs which leads to massive configuration efforts for the portal admin
- the urls may not follow a scheme that allows simple parameter injection
I have a solution in mind, but this would require massive efforts and maybe changes in the targeted portlets, which is not always possible if you use 3rd party portlets.
My solution would look like this: (draft!)
Portlets register at a central service with their portlet IDs and when a portlet wants to link to a portlet it can do a lookup based on a symbolic name. This would ease the pain for the admin, because it is possible to "auto discover" portlets. The service may also provide a UI to wire portlets based on source and target portlet.
The URL generation for portlets that can be changes may be solved via service call to the portlet that generates the URL as a whole with injected parameters and returns it.
For portlets that you can't change you have to append the parameters and hope that it works. :-/
Any suggestions? Are there simpler solutions? existing solutions?
Thanks!
Patrick

As far as I know Portlet Specification doesn't cover this. So there is no portable solution. For Liferay you can always use theirs custom tag library which aims exactly this issue. There is similar mechanism for Websphere Portal.
Something can be found here and here
Generally I would try to avoid this and use standard IPC mechanism(Public Render Parameters or Events)

For JSR 286 specification it is possible to use events for inter-portlet communication. For the older JSR 168 there isn't an endorsed way to do so. If you find a way that works for you, then use it.
There is an old book given away for free from Manning (registration required). You can find some ideas there.

Related

Spring MVC Portlet reuse in Websphere Portal

I have application in which there are several portlets created, simple java mvc portlet.
Is it possible to reuse the portlet in another application, without duplicating code?
What are the implications and what changes should be done?
Thank you.
If you have a portlet it can be deployed in many different ways. You can deploy the same portlet without code changes into multiple environments.
Once the portlet is deployed in an environment you can also:
Clone it, ie make a copy of it, which will allow you to change the portlet configuration without making two separate portlets.
Use the same portlet on different pages (multiple instances).
All of the above without doing any changes to the actual portlet. Now, keep in mind that it also all depends on the portlet. If the developers of the portlet have included many hard coded parameters, this may not be possible to do. I recommend that you keep the server/environment dependent parts in configurations rather than hard coded.

Expose Liferay functions to another web application

Here's my situation: I'm running a JBoss 7 in Domain Mode with several nodes. One node is in charge of my Liferay 6.2 another one runs several other web applications. Now I'd like to implement some kine of Single Sign On routine. So to use my web applications you have to go through liferay first. Authenticate agains liferay, then go one to one of the web applications.
So the question is whether there is a way to expose some of liferays methods to access the user store and check if the user, who's accessing a web application is the same as logged in on liferay. Developing some sort of bridge is fine with me. I'm thinking of a portlet which does all the interaction with liferay and exposes some methods like readUser(). Maybe I can do a jndi lookup for this portlet or a component embedded in this portlet to call readUser() from my other web applications. I think this sounds a bit like EJB stuff.
Using Liferays API, Services and LocalServices to read user information etc. shouldn't be that difficult (already played a little with that). I just don't know how to establish a communication between a web application and liferay.
If it's not working this way, I would settle for something else, maybe a webservice or an other way that makes sense but I'd like to try the EJB/JNDI approach first (except this makes completely no sense). Maybe someone can point me in the right direction.
Turning my applications into portlets is not really an option because these applicaions are quite large and already exsist for quite some time. So I'd like to leave them mostly unchanged - outside of auth stuff.
Thanks and regards
Sebastian
You can use a service builder and you expose your service as remote.
Several Options:
Just access Liferay's API methods from your applications. You can access the JSON API at http://www.example.com/api/jsonws.
There's also a SOAP interface (http://www.example.com/api/axis), that's typically available only from localhost (you can configure otherwise in portal-ext.properties)
You can encapsulate calls to those services by creating your own services. Use the tool of your choice or Liferay's servicebuilder. You can create empty entities and just refer to Liferay's own entities. Servicebuilder will generate JSON or SOAP WS if you let it. (what Slimen Belhajali mentioned)
As you specifically talk about the check for user identity, you might even want to think of a completely different solution and just look at single-sign-on (SSO) solutions. This way you'd sign in only once (to the SSO server) and automatically (implicitly) to your webapp as well as to Liferay. This works best if both access the same userstore, e.g. on LDAP.

Custom web MVC for a legacy Java EE project

I am in the middle of creating my own custom MVC web framework for a project. This project has very old code base where one JSP page directly submits a form to another JSP whereas the paths are also hardcoded. Now it is a big project and putting Struts or JSF will take considerable amount of time.
So my suggestion is to build a small custom MVC framework and convert many existing page flows into it and also encourage them to develop newer applications using this new MVC frameworks.
I would like to review this with all of you whether it makes sense or we should directly go to the standard MVC frameworks.
My idea
1. Create one front controller servlet which will have URL pattern like /*.sm
2. This servlet reads one config file and creates a map whose key is requestedURI and value is the class name of the command bean.
3. upon intercepting any action request it reads the parameter map (request.getParameterMap()). This servlet refers the already built map, understand whose command bean is to be invoked? Creates an instance of this command bean.
4. pass the parameter map to this command bean and calls execute method.
5. if any exception is found, front controller servlet forwards the request to one global error page
6. if everything is fine, it then forwards the request to the expected URI (by removong .sm and replace it with .jsp)
Do you think I am missing anything here? I know I can make it more fancy by providing error page per request page in the config file or so but those can be done later as well.
I think that you will end up reinventing the wheel rolling your own MVC framework. I know that it is tempting to make your own, since you won't have to get used to a new API but instead create your own and you can more easily adapt it to your specific usecases. But since it seems to be a very long lived application you will have to consider the fact, that your own framework (which may now be state of the art) will be legacy in a couple of years, too.
And that's where adapting one of the popular frameworks comes in handy. The creators of a new framework usually want others to move, too, so they will (or should) offer easy integration or migration options away from the frameworks they think they are doing better (Spring is a good example since it e.g. seamlessly integrates with existing Struts applications and you can gradually move your application without putting the old one into trash). Additionally most current frameworks are very versatile (which can sometimes be a problem since they need more time to get into it) and can be adapted to almost all usecases.
So I would recommend to review the existing solutions carefully (you can learn a lot from their design decisions and errors, too) and only start making your own if none of them matches your requirements.

Viewing the contents of Session, Application and Request Bean

It would make a lot of sense to be able to monitor the contents of Session, Application and Request Bean while developing a JSF app but as far as I know, I should explicitly add watch points for the parameters I'm interested in.
Is there an easier way to see these values as I navigate through my apps the pages?
You can do it as a cross cutting concern using some Filter of your own, or some of the AOP techniques provided by the framework. The idea is to log all these information on every request. It can be console, why not.
IMO, monitoring the content of request might not be a very useful idea, though.
If you want to see what is being added to and removed from these scopes, have a look at ServletContextAttributeListener, ServletRequestAttributeListener and HttpSessionAttributeListener. You can define instances of these classes using your web.xml.
As Vinegar says, if you want to monitor arbitrary classes, you could use AOP. You could also think about using the debugger programmatically.

Modular web apps

I've been looking into OSGi recently and think it looks like a really good idea for modular Java apps.
However, I was wondering how OSGi would work in a web application, where you don't just have code to worry about - also HTML, images, CSS, that sort of thing.
At work we're building an application which has multiple 'tabs', each tab being one part of the app. I think this could really benefit from taking an OSGi approach - however I'm really not sure what would be the best way to handle all the usual web app resources.
I'm not sure whether it makes any difference, but we're using JSF and IceFaces (which adds another layer of problems because you have navigation rules and you have to specify all faces config files in your web.xml... doh!)
Edit: according to this thread, faces-config.xml files can be loaded up from JAR files - so it is actually possible to have multiple faces-config.xml files included without modifying web.xml, provided you split up into JAR files.
Any suggestions would be greatly appreciated :-)
You are very right in thinking there are synergies here, we have a modular web app where the app itself is assembled automatically from independent components (OSGi bundles) where each bundle contributes its own pages, resources, css and optionally javascript.
We don't use JSF (Spring MVC here) so I can't comment on the added complexity of that framework in an OSGi context.
Most frameworks or approaches out there still adhere to the "old" way of thinking: one WAR file representing your webapp and then many OSGi bundles and services but almost none concern themselves with the modularisation of the GUI itself.
Prerequisites for a Design
With OSGi the first question to solve is: what is your deployment scenario and who is the primary container? What I mean is that you can deploy your application on an OSGi runtime and use its infrastructure for everything. Alternatively, you can embed an OSGi runtime in a traditional app server and then you will need to re-use some infrastructure, specifically you want to use the AppServer's servlet engine.
Our design is currently based on OSGi as the container and we use the HTTPService offered by OSGi as our servlet container. We are looking into providing some sort of transparent bridge between an external servlet container and the OSGi HTTPService but that work is ongoing.
Architectural Sketch of a Spring MVC + OSGi modular webapp
So the goal is not to just serve a web application over OSGi but to also apply OSGi's component model to the web UI itself, to make it composable, re-usable, dynamic.
These are the components in the system:
1 central bundle that takes care of bridging Spring MVC with OSGi, specifically it uses code by Bernd Kolb to allow you to register the Spring DispatcherServlet with OSGi as a servlet.
1 custom URL Mapper that is injected into the DispatcherServlet and that provides the mapping of incoming HTTP requests to the correct controller.
1 central Sitemesh based decorator JSP that defines the global layout of the site, as well as the central CSS and Javascript libraries that we want to offer as defaults.
Each bundle that wants to contribute pages to our web UI has to publish 1 or more Controllers as OSGi Services and make sure to register its own servlet and its own resources (CSS, JSP, images, etc) with the OSGi HTTPService. The registering is done with the HTTPService and the key methods are:
httpService.registerResources()
and
httpService.registerServlet()
When a web ui contributing bundle activates and publishes its controllers, they are automatically picked up by our central web ui bundle and the aforementioned custom URL Mapper gathers these Controller services and keeps an up to date map of URLs to Controller instances.
Then when an HTTP request comes in for a certain URL, it finds the associated controller and dispatches the request there.
The Controller does its business and then returns any data that should be rendered and the name of the view (a JSP in our case). This JSP is located in the Controller's bundle and can be accessed and rendered by the central web ui bundle exactly because we went and registered the resource location with the HTTPService. Our central view resolver then merges this JSP with our central Sitemesh decorator and spits out the resulting HTML to the client.
In know this is rather high level but without providing the complete implementation it's hard to fully explain.
Our key learning point for this was to look at what Bernd Kolb did with his example JPetstore conversion to OSGi and to use that information to design our own architecture.
IMHO there is currently way too much hype and focus on getting OSGi somehow embedded in traditional Java EE based apps and very little thought being put into actually making use of OSGi idioms and its excellent component model to really allow the design of componentized web applications.
Check out SpringSource dm Server - an application server built entirely in terms of OSGi and supporting modular web applications. It is available in free, open source, and commercial versions.
You can start by deploying a standard WAR file and then gradually break your application into OSGi modules, or 'bundles' in OSGi-speak. As you might expect of SpringSource, the server has excellent support for the Spring framework and related Spring portfolio products.
Disclaimer: I work on this product.
Be aware of the Spring DM server licensing.
We've been using Restlet with OSGi to good effect with an embedded Http service (under the covers it's actually Jetty, but tomcat is available too).
Restlet has zero to minimal XML configuration needs, and any configuration we do is in the BundleActivator (registering new services).
When building up the page, we just process the relevant service implementations to generate the output, decorator style. New bundles getting plugged in will add new page decorations/widgets the next time its rendered.
REST gives us nice clean and meaningful URLs, multiple representations of the same data, and seems an extensible metaphor (few verbs, many nouns).
A bonus feature for us was the extensive support for caching, specifically the ETag.
SpringSource seems to be working on an interesting modular web framework built on top of OSGi called SpringSource Slices. More information can be found in the following blog posts:
Modular Web Applications with SpringSource Slices
Pluggable styling with SpringSource Slices
Slices Menu Bar Screencast
Have a look at RAP! http://www.eclipse.org/rap/
Take a look at http://www.ztemplates.org which is simple and easy to learn. This one allows you to put all related templates, javascript and css into one jar and use it transparently. Means you even have not to care about declaring the needed javascript in your page when using a provided component, as the framework does it for you.
Interesting set of posts. I have a web application which is customized on a per customer basis. Each customer gets a core set of components and additional components depending on what they have signed up for. For each release we have to 'assemble' the correct set of services and apply the correct menu config (we use struts menu) based on the customer, which is tedious to say the least. Basically its the same code base but we simply customize navigation to expose or hide certain pages. This is obviously not ideal and we would like to leverage OSGi to componentize services. While I can see how this is done for service APIs and sort of understand how resources like CSS and java script and controllers (we use Spring MVC) could also be bundled, how would you go about dealing with 'cross cutting' concerns like page navigation and general work flow especially in the scenario where you want to dynamically deploy a new service and need to add navigation to that service. There may also be other 'cross cutting' concerns like services that span other of other services.
Thanks,
Declan.

Categories

Resources