If I have a set of HTML building blocks that are used by many different components, can I use a Java class for that ? Currently I use JSP, but it seems a bit difficult.
For eg: com.mydomain.view.Table.java
and from a JSP I create an object of it, like this :
Table tb = new Table(data);
String html = tb.getHtml();
So is this okay ? good ? better ? or best ?
if not, what is the standard way to achieve this ?
PS: The Table class here has nothing to do with html <table> tag. What that class does is create a tabular structure of data. It may or may not use a html <table>.
Certainly there is no standard way.
So is this okay ? good ? better ? or best ?
The answer depends on the goal of the software you are making.
One important factor to consider is "eventual efficiency".
Looking only at the Table class, it looks good. Constructor clearly states it's dependency on 'data'. getHtml() method, in my opinion, is where it should be.
If you have other views (Swing, Android, ...), you end up with having additional getSwing() or getAndroid() methods. Anyway that's OK, if the Table class is a generic intermediate layer between the real model and the view.
Another possibility is to pass the model or the Table to the JSP view layer, and let the view layer decide how to transform it to HTML. For example by using a taglib (which eventually may call getHtml as well). If you pass the Table, the view gets generic somehow as well (because it can't really decide on how the data is rendered).
With html building blocks, one solution is using jQuery load that returns html.
The combination of Spring MVC with Apache Tiles view is best suited for this.
$("elementId").load("${context}/rest_url_returning_html_building_block");
Related
I'm rather unexperienced in GWT, and I have large codebase with working project in this technology. My task refers to assigning id's to html elements witch will be used in automatic testing. We can't use some dynamically assigned id's because in automatic test we have to specify exact values of id's. My way for now was to use method ensureDebug(id), written by hand in code for specific elements.
I think that doing it this way mean that code will be more spaghetti-like, with mixed ensureDebug(id) methods usages there and here. I was thinking if there is any way of doing it that will be more manageable and cleaner than current. Is is maybe possible to use AOP? (I have never used AOP, so I don't know if it is any good idea, or possible in GWT) Or maybe other way than using ensureDebug?
You also can set the IDs for HTML elements like
element.setId("myId");
But this is as much spaghetti like as your approach adding the IDs in the code.
Another possibility would be to use an UiBinder and set the id there. With this approach you have all your ui elements of one view, which should have an id, at one place. With bootstrap for example it would look like this:
<b:TextBox ui:field="searchTextBox" b:id="search-text-box"/>
Like this you can access the field in your view-class via searchTextBox and the id search-text-boxis added to the HTML element (which you could also use for styling etc.)
We have faced same issue for our project while adding test automation. As per my knowledge unfortunately GWT doesn't support anything like AOP yet. So we have to follow any of the spaghetti-like approach only from one mentioned above by #mxlse or the one you are already following.
Based on my experience I can recommend you to create separate constant/property at client or server end. Use this file to save all your id's which you can share latter on with test team as well.
Basic problem
I've come across a bit of a problem while writing my own custom JSP tags to "wrap" the spring MVC form tags. I've wrapped other tags successfully but come unstuck with the select and options tags, this throws an IlleagalStateException. I've debugged the spring code and found that the options tag looks for an ancestor select tag. I'm doing this with tag files so the spring select tag is actually in a different tag file. I guess that's why it doesn't find it.
So the questions is what can I do to get round this?
Possible solutions
I've tried looking for solutions but all I've found is other people having the same problem but no solution posted. I did ponder writing my own select and options tags without using the spring tags but I don't really want to have to replicate the binding that it gives you for free. I don't mind changing to use Java classes rather than tag files but I found previously that the output won't be evaluated as a JSP so you can't output another JSP tag.
Reasons for doing this
Having thought about this for a week since first asking the question I am now clearer on what I want to achieve.
To simplify the markup needed in my JSP's
Factoring out common code (e.g. form:errors after an input or getting a translation from spring:message)
To encapsulate look and feel (CSS goes a long way but often you need to change the markup too)
To be able to build enhanced components that extend the functionallity of the spring tags (e.g. render a multi-select as a picklist or display readonly inputs as text labels)
I'll be interested to hear what people think.
Thanks
Firstly, I'm not sure what you mean by wanting control over styling. I thought you could pass-in class and id attributes to Spring tags and they were copied through (? - although I might be getting confused with Grail tags, as I've been writing Grails apps lately). Edit: plus you can style Spring generated tags by referencing an outer element. E.g. surround your form elements with a div and then style the form elements like: #myDiv input { color: red; }.
From my experience (10+ years webapp dev), its not worth the extra effort to try and future proof your app. When you choose a framework like Spring MVC you are getting a lot of stuff for free, that you would normally have to write yourself. The cost of this free stuff is a certain amount of lock-in (as you said). Spring is pretty good when it comes to this aspect - you can use as little or as much as you want and its usually pretty straight forward to engineer it out if needs be in the future.
So my take is: use the Spring tags "as is". The likelihood of you needing to remove the Spring aspect in the future is very small. As such its a worthwhile risk to "put off" if/until that scenario arrises. You have likely already spent as much time and code trying to engineer your future-proof solution as you would've spent removing the Spring tags - that it outweighs any benefit it might have provided. And add to that - you've written that code and you and/or someone else will have to maintain that code now - versus letting the Spring developers maintain the code for you.
Lastly, if you really don't want to have this lock-in and want full control over styling, then write your form elements by hand.
<select name="foo_select">
<option value="">-- select a foo type --</option>
<c:forEach var="foo" items="${fooGroups}">
<option value="${foo}">${foo}</option>
</c:forEach>
</select>
I've thought about this for a good week now and this is the shortlist:
Give up and directly use the spring tags in my JSP's
Don't use the spring tags at all and replicate their logic in my own tags
Possibly write a tag class that extends or makes use of the spring tag class
Expand the scope of my tags to wrap both the select and options tags
Given the reasons for wanting to do this (which I have now clarified in the question), I've decided to go for the last option. I wasn't keen on this originally because I thought I might end up with hundreds of parameters but it's actually not too bad. The tag files are designed for wrapping common bits of markup so this is what they're for. I've also wrapped my own tag further so there is a picklist tag which outputs my custom select tag and then writes the JS needed to initialise it.
I think this is the best of the possible solutions I've come across based on what I wanted to achieve. This is what I'm going with but I'd still be interested to hear of other peoples solutions if they think they have something better.
I have a web-app in Java, Spring, Struts 2 and Hibernate, that servers multiple clients. Each client with multiple users. To create a personal feel for each client, i would like to customize the header for each client.
I'm using sitemesh as decorator, and am looking for tips or examples or someone who can point me in the right direction as to how to acomplish this in the best practice.
What would you think? Should i just code it direct in the header.jsp? Extracting the info about the logged in user and from that create a custom header by code? Or is there a more clever solution out there?
Thanks!
Update:
To further clearify what i want:
Different properties-files for each client is not an option. We are looking at potentionally hundreds of clients. It needs to be database-driven. But thats the easy part. There is no problem storing the information in db and extracting it when needed.
What im trying to figure out is if there is some sort of standard way of doing this. Some sort of filter or Action that is run before the sitemesh decorator that will provide the decorator with the correct info?
Struts2 provides application scope, for variables which are global to the application.
Load all the customer specific strings into #application scope (I would use spring to do this when the application starts up). From there referencing the strings would be pretty obvious: #application.greeting I don't like the idea of using an interceptor because there is nothing to intercept. I would say for what you are doing application scope is the perfect place. If it is a single client system I can see no reason why anything would be stored in application scope.
Aside: Tiles uses a different template paradigm than site mesh, and they have slightly different purposes. As such the two can be complimentary. Tiles relying on XML definitions can have it's definitions stored in a DB and is definitely less computationally intensive, however where there is interplay between different UI components... or disparate elements appearing on the page you need to use sitemesh. So for basic template needs tiles does everything and is quite easy to understand but say you wanted to make add a certain widget in the middle of the page which relies on JS which needs to be added to the header it would be tricky to do this in Tiles (although the obvious solution is to just roll the JS functionality into one JS file for all possible uses in a particular part of the site).
Asside 2: By using a view technology such as velocity or freemarker in conjunction with tiles it is conceivable to move the entire view layer into a database. I just thought I would mention that as for some maintenance issues that could be extremely beneficial.
Sitemesh makes it's decisions about what decoration to use based upon the requested URL string, so unless you have a reference to the client in every url - either as part of the main url string or as a known parameter, then Sitemesh out of the box is not going to help.
This leaves a few possibilities to achieve what you want;
1) Write a filter that runs before Sitemesh that adds, for example, "&clientId="xx" to every incoming request.
2) Dive into the source code for Sitemesh & look for where Sitemesh finally makes it's decision about which decorators to use and override it. I've never tried this so I don't know how practical this might be.
3) Make the style sheet definition in your jsp pages an OGNL expression and provide that information in a base action class that all your actions extend. In this way you end up with (potentially) a different CSS file for each client and you provide your customisation via CSS.
Hope that this helps.
Consider a simple POJO Java Object:
class MyObj {
String a, b;
Integer c;
}
My application executes a Struts action and sets a Collection of these on the Http Request:
request.setAttribute("myObjects", getCollectionOfMyObj());
The action then forwards to a JSP page, and this is where my questions centres:
What is the simplest way I can
bind this collection into a grid,
such that is renders a table with
three columns (a, b, c) and one row
per object in the passed collection.
A key characteristic I require,
is that I can add a new field to the
Java object and it requires no (or
minimal) changes to the UI code,
i.e. the object is being
introspected and displayed so that I don't have D-R-Y
violations in the UI?
How can I make the grid
editable, so that any changes to a
row are reflected back into a new (or the existing)
Collection of Java objects in the
request for use by other Actions
(e.g. to persist the changes)?
Many thanks in advance for your help, please let me know if you need further clarification.
Arun
If you need to display only your data without editing it I recommend using displaytag, its a custom tag that is used to render tabulated data, and its highly customizable.
However, If you want to edit your data, I advise you to move to some javascript solutions, dhtmlxgrid is one good option, there are many many other solutions in javascript that you could use, however here you will be working with XML data and AJAX, this would be easier to you, and it will make your table more dynamic to changes. After mastering your chosen javascript-solution that best fits you, you could wrap it into a custom tag and generalize it ;-).
There are tons of different ways you can achieve the above. But since you are already using Struts I would recommend stick to Struts UI Tags . It will make things little bit easy to start with
Say, You have an application which lists down users in your application. Ideally, if you were writing code to achieve this in Java, irrespective of what your UI layer is, I would think that you would write code which retrieves result set from the database and maps it to your application object. So, in this scenario, you are looking at your ORM / Data layer doing its thing and creating a list of "User" objects.
Let's assume that your User object looks as follows:
public class User {
private String userName;
private int userid;
}
You can now use this list of "User" objects, in any UI. (Swing / Webapp).
Now, imagine a scenario, where you have to list down the userName and a count of say, departments or whatever and this is a very specific screen in a webapp. So you are looking a object structure like this:
public class UserViewBean {
private String userName;
private int countDepartments;
}
The easiest way of doing this is writing SQL for retrieving department count along with user name in one query. If I you to write such a query, where would you have this query? In your jsp? But, if you were doing this in a MVC framework, would you move this query to your data layer, get the result set, convert it to UserViewBean and send it to your jsp in request scope? If you write queries directly into jsps/if you are making use of connections directly in JSP, isn't that a bad practice?
I know, some of you might say, 'hey, you got your object composition wrong! if department is linked to user, you would want to create a list of departments in your User object' - Yes, I agree. But, think of this scenario - Say, I don't need this department count information anywhere else in my application other than this one screen. Are you saying that whereever I load my User object from the database, I would have to load a list of dependency objects, even if I won't be using them? How long will your object graph get with all the relational integrity? Yes, I do know that you have ORMs for this very reason, so that you get benefits of lazy loading and stuff, but I dont have the privilage to use one.
The bottom line question here is:
Would you write sqls in to your JSP if it serves just one screen? OR
Would you compose an anemic object
that caters to your view and make
your business layer return this
object for this screen - just to make
it look a bit OOish? OR
irrespective of what your screen
demands, would you compose your
objects such that an object graph
is loaded and you would get the
size of that list?
What is the best practice here?
I would never put SQL in a JSP. I would use Spring MVC or Struts controllers, or servlets to contain all of that type of logic. It allows for better error handling among other things (you can forward to error pages when queries fail).
If you really must do this, use the JSTL SQL tags.
Personally, I take a simple pragmatic approach. If I was writing screen that just displays a list of users with their deparment count, so that the entire code is maybe a page, and I don't expect this code to be used on any other screen, I'd probably just throw it all in the JSP. Yes, I know there are all the MVC purists who will say, "business logic should never go in a JSP". But aside from a dogmatic rule, why not? What would it hurt in a case like this?
If I found that I had two screens, maybe one where I had to simply display the list and another where I had to do some additional processing on the list, then I would certainly pull the common code out into a class that was called from both places.
I believe that the criteria should be: What produces the most maintainable code? What is shortest and easiest to understand? What produces the least linkages between modules? etc.
I adamantly refuse to accept the principle: "In some cases this approach leads to problems, therefore never use it." If sometimes it leads to problems, then don't use it in the cases where it leads to problems. Or worse, "Somebody wrote it in a book, therefore it cannot be questioned." Sure, there are some rules that are valid 99.99% of the time, so it gets to be pointless to check if this particular case is an exception. But there are lots of rules that are good 51% of the time and people leap from "mostly" to "always".
Would you write sqls in to your JSP if it serves just one screen?
In a prototype, just as a quick hack - maybe. In any other situation, not to mention a production environment - NEVER.
Use a proper MVC framework to separate business logic from presentation.
I am not even sure that JSP should be used, but for trivial applications. If you really have to use them, use MVC pattern or encapsulate your logic in a JavaBean.
Have a look at JPA which allow you to do object manipulations which then is persisted in the database
I wouldn't put SQL in a jsp for fear of forgetting it in future maintenance. Think of the poor guy maintaining your code-- poor guy = you in 10 months or whenever the database is restructured-- and at least put all SQL in the same general region.