views:

551

answers:

2

We have a Struts 2 web application that's used by pretty much every employee to manage and configure jobs for our server farm. We're working on a plan to make a dashboard for customers, so they can see their own jobs, and a very simple display of its status ("in process", "ready for proofing", "finished", etc). All of the pages the customers can see will have much less information than the employees' views, and there will be no way to edit or change anything. But in the end, they're essentially two separate views of the same information: one very simple, one more complex and controllable.

The naive way to do this, is to have if/elses in every single jsp:

<s:if test="user.role == 'customer'">
    <!-- TODO - Display simple customer view -->
</s:if>
<s:else>
    <!-- TODO - Display complex employee view -->
</s:else>

Is there a simpler way to do this? Can I create two separate directories of jsps, one named "customer" and one named "employee" (or default or something) and then have Struts key off of a property in my action to decide which directory to check?

Or is there another way that I can do this?

+1  A: 

I would suggest managing this inside your controller. Add a new view for the customer, and check the user's role in your controller and display the appropriate view. This will leave your existing view's untouched, and adds the ability to have truly custom views for your customers.

Rich Kroll
For every action, duplicate all of the result definitions? This is a big application, with maybe 50 actions. That's a lot of extra stuff in the struts.xml, and that makes me think it would be harder to maintain with all the duplication.
Plutor
+1 i think this is a good solution, but I think you should check out http://www.stripesframework.org. It's like struts without the xml.
ScArcher2
If each action is reusing the same views, then yes, that would be alot of code duplication in the xml; you could instead create one new action, and have it called from within your controller instead of returning a new custom response. If each action needs a unique view, then this duplication makes sense and is needed.
Rich Kroll
+1  A: 

It's not exactly clear from the question if the two views are completely different, or if the customers have something extra, or if the employees have something extra. If one role has something extra, just put the common parts in one file and the uncommon parts in their own files and use includes or tiles (or something similar) to combine JSPs to make a page.

If the two views are completely different, they should be separate JSPs, in which case the action can forward to the appropriate view based on the role, as suggested by Rich Kroll.

As for your comment asking about duplicating the result definitions, when you have two separate mutually-exclusive features, you need two code paths. The best you can do is factor out the commonality into shared code files.

One way you can simplify your action code, if this pattern is something you do a lot, is to pick the ActionForward that best matches your desired forward name.

So, if normally you would do

return mapping.findForward("success");

You can do something like this

ActionForward defaultMapping = mapping.findForward("success");
ActionForward roleMapping = mapping.findForward(user.getRole() + "_success");
if (roleMapping != null) {
  return roleMapping ;
} else {
  return defaultMapping;
}

Put that in a method in your base class and then your actions don't need to know what view they are going to. Then your struts-config can be something like this:

<action path="/home" class="HomeAction">
  <forward name="success" path="home.jsp"/>
</action>
<action path="/viewOrder" class="ViewOrderAction">
  <forward name="customer_success" path="customer_order.jsp"/>
  <forward name="employee_success" path="employee_order.jsp"/>
</action>

In this case you are not dynamically looking up the jsps by name to determine whether or not they exist, but at least you can keep the action code simple.

Mr. Shiny and New
I've edited the question to make it clearer that in almost all of the cases, these are just two different views of the same data.
Plutor
Two different views of the same data, but the implementation of those views seems very different. I would go with two forward entries for each action in this case.
Mr. Shiny and New
This is nice, but is there any way to do this search in Struts 2? There's no equivalent method in the ActionMapping object anymore.
Plutor
Sadly we are stuck on Struts 1 here. I don't know Struts 2.
Mr. Shiny and New