Use JSP as implementation language for components/modules?

K

Kai Grossjohann

It seems that the traditional way to make a component to be used by
another JSP-based webapp is to make it a taglib. Then the taglib can
be packaged as a *.jar file and it's easy to use it.

But taglibs are implemented in Java. And if my tag generates a lot of
HTML output it's not so practical to do all that in Java, I would much
rather use JSP as the implementation language.

So is there a way to package some collection of JSP files as a
component that's easy to use by other people to build their own
webapp?

What perhaps makes matters worse is the fact that the JSP files I've
got make use of JavaScript and CSS. So what I would like to do is not
to just package the JSP files as a reusable component, but also
include the JavaScript and CSS files that belong to that component.

I'm going to make several components that cooperate with each other.
These components communicate via the HTTP session. So I think it's
not workable to make each component be a separate webapp. But maybe
there is a way to communicate between webapps that I'm not aware of,
yet. (The objects in the HTTP session have a well-defined interface
that belongs to the interface spec for the component(s), so users of
the component are expected to invoke methods on the objects in the
session, too.)

Any suggestions?

Kai

PS: I apologize if this is the wrong group -- Google Groups didn't
find a better group when I entered "JSP" as the search term...
 
M

Mladen Adamovic

If you don't want to use tags, I don't see another way to build reusable
components except instead of JSP making Servlet. At the first look servlets
are harder to write than JSP, but at the second try - big servlets may be
more reusable and more readable then JSP. I discover that today.

But, I didn't understand what you are REALLY trying to do, I mean what
problem to avoid -- I don't see any problem, and I read you message 3 times
to try to be sure...

P.S. This is apropriate goup for JSP question, anyway.
 
K

Kai Grossjohann

Mladen Adamovic said:
If you don't want to use tags, I don't see another way to build reusable
components except instead of JSP making Servlet. At the first look servlets
are harder to write than JSP, but at the second try - big servlets may be
more reusable and more readable then JSP. I discover that today.

But, I didn't understand what you are REALLY trying to do, I mean what
problem to avoid -- I don't see any problem, and I read you message 3 times
to try to be sure...

Let's say I build a database querying application. I will have query
forms for the user to fill out, then there will be a result list to
display, and maybe I also want to show a single result item in more
detail. It's fairly obvious that "query form", "result list" and
"result item" are components that could be reused. (For example,
somebody could display a query form, and if the result list has just
one item, directly show it instead of the result list. That would be
another way to integrate the components.)

Now one possible interface for the query form component would be that
I make a tag, and users of the component can integrate it into their
website like this:

...some HTML/JSP code goes here...
<kai:queryform id="4711" .../>
...more HTML/JSP code here...

This would be very convenient for the user. However, that way I can't
use JSP to implement the <kai:queryform .../> element. For example,
suppose that a query form is a list of fields, and each field has a
name. Then one way to implement that using JSP is like this:

<jsp:useBean id="qf" .../>
<dl>
<c:forEach var="field" items="${qf.fields}">
<dd><c:eek:ut value="${field.name}"/></dd>
<dt><c:eek:ut value="${field.someHTMLCode}"/></dt>
</c:forEach>
</dl>

The above would be some part of the internal implementation of the
query form component, and I would like it quite a bit because it is
easy to see how to change the HTML code such that it generates, say, a
table instead.

But if I go for making a taglib, then I can't use JSP for implementing
it, and thus I can't use the above clean JSP code.

Does this explain why I think that JSP is a nice implementation
language for my components?

Now, instead, I have decided that I create a JSP file that can display
a query form. For some obscure reasons we have decided that frames
are the right interface for our application, so every user of our
components will also have to use frames. So the idea is that usage of
the query form component works by making a frameset and linking to the
query form from there:

<frameset ...>
...
<frame src="QueryForm.jsp?some=parameter&another=parameter" ...>
...
</frameset>

So, now we have QueryForm.jsp (and some util files) that implement a
query form component, and then we have ResultList.jsp (and some util
files) that implement a result list component. The two components
communicate via the HTTP session. (After the user submits a query,
you (as a user of the components) are supposed to create a resultlist
object in the session, before invoking ResultList.jsp. That file then
fetches the result list from the session and displays it.)

My understanding is that I can't package QueryForm.jsp (with util
files) as a webapp and ResultList.jsp (with util files) as another
webapp, because two webapps don't share a session, and thus the
resultlist object couldn't be transferred from one to the other.

Does this make things clearer?

Kai
 
M

Mladen Adamovic

Kai Grossjohann said:
My understanding is that I can't package QueryForm.jsp (with util
files) as a webapp and ResultList.jsp (with util files) as another
webapp, because two webapps don't share a session, and thus the
resultlist object couldn't be transferred from one to the other.

What do you lose if you package it together (to share session)?
 
S

Sudsy

Kai Grossjohann wrote:
...some HTML/JSP code goes here...
<kai:queryform id="4711" .../>
...more HTML/JSP code here...

This would be very convenient for the user. However, that way I can't
use JSP to implement the <kai:queryform .../> element. For example,
suppose that a query form is a list of fields, and each field has a
name. Then one way to implement that using JSP is like this:

<jsp:useBean id="qf" .../>
<dl>
<c:forEach var="field" items="${qf.fields}">
<dd><c:eek:ut value="${field.name}"/></dd>
<dt><c:eek:ut value="${field.someHTMLCode}"/></dt>
</c:forEach>
</dl>

The above would be some part of the internal implementation of the
query form component, and I would like it quite a bit because it is
easy to see how to change the HTML code such that it generates, say, a
table instead.

But if I go for making a taglib, then I can't use JSP for implementing
it, and thus I can't use the above clean JSP code.

Why not? It apears that you need to do some more reading about taglibs,
particularly the javax.servlet.jsp.tagext.TagExtraInfo class. I highly
recommend "Advanced JavaServer Pages" by David M. Geary (ISBN:
0-13-030704-1).
Tags CAN create scripting variables which can be accessed in the tag
body. How do you think JSTL does it? That's just a collection of tags
after all.
 
K

Kai Grossjohann

Sudsy said:
Why not? It apears that you need to do some more reading about taglibs,
particularly the javax.servlet.jsp.tagext.TagExtraInfo class. I highly
recommend "Advanced JavaServer Pages" by David M. Geary (ISBN:
0-13-030704-1).
Tags CAN create scripting variables which can be accessed in the tag
body. How do you think JSTL does it? That's just a collection of tags
after all.

There is a misunderstanding. We're talking (well, at least I am :)
about the following two alternatives:

(1) Users of the query form component write <kai:query-form id="4711"
.../> in their JSP files.

(2) Users of the query form component set up a frameset and use
QueryForm.jsp?id=4711... as the URL of one of the frames.

In the second alternative, it is obvious that JSP can be used to
implement the component -- after all, the component is a JSP file.

In the first alternative, it seems to me that the implementation of
the component is more or less equivalent to writing the doEnd method
in the appropriate class.

AFAIK, JSP cannot be used to implement the doEnd method...

Does this make it clearer? (Maybe the misunderstanding is on my
side. Please help this stupid poster to understand.)

Kai
 
K

Kai Grossjohann

Mladen Adamovic said:
What do you lose if you package it together (to share session)?

Well, even if I have five components and package them all in one
webapp, what about the users of the components? Presumably, the users
of the components would wish to access the same objects in the
session.

(For example, an application writer might wish to use my query form
component but slightly modify the query before it is processed. In
that case, the query form component and the application writer's file
would need to share a session.)

Is it true that two different webapps do not share a session?

Kai
 
B

Ben_

Is it true that two different webapps do not share a session?
Yes:

JavaT Servlet Specification - Version 2.3
SRV.7.3 Session Scope
HttpSession objects must be scoped at the application (or servlet context)
level.
The underlying mechanism, such as the cookie used to establish the session,
can be
the same for different contexts, but the object referenced, including the
attributes in
that object, must never be shared between contexts by the container.
To illustrate this requirement with an example: if a servlet uses the
RequestDispatcher to call a servlet in another web application, any sessions
created for and visible to the callee servlet must be different from those
visible to
the calling servlet.
 
K

Kai Grossjohann

Ben_ said:

Ah, thanks a lot. Some day I will read all those specs, I'm sure...

So, this brings us back to square one: is it possible to use JSP as an
implementation language for components or modules? And if so, how
does one go about the packaging?

One idea that I had was to pack each component into a zip file, where
the JSP files are located in a directory that's named like Java
package names. This means that people unpacking that zip file will
not have any conflicts.

Then use of the component works by unpacking the zip file into your
webapp.

I guess this works, but it seems like an extremely low-tech way of
doing things, so I was hoping there is a better solution.

Kai
 
S

Sudsy

Kai said:
There is a misunderstanding. We're talking (well, at least I am :)
about the following two alternatives:

(1) Users of the query form component write <kai:query-form id="4711"
.../> in their JSP files.

(2) Users of the query form component set up a frameset and use
QueryForm.jsp?id=4711... as the URL of one of the frames.

In the second alternative, it is obvious that JSP can be used to
implement the component -- after all, the component is a JSP file.

In the first alternative, it seems to me that the implementation of
the component is more or less equivalent to writing the doEnd method
in the appropriate class.

AFAIK, JSP cannot be used to implement the doEnd method...

Does this make it clearer? (Maybe the misunderstanding is on my
side. Please help this stupid poster to understand.)

I think we need to take a step back and put things into prespective.
First off, the whole idea of JSPs is to have something which is
essentially HTML but with additional tags. They weren't intended
to be containers for scriptlets. They're compiled down to servlets
under the covers anyway so you could approach the problem from the
opposite direction and write servlets which pump out HTML code.
Neither approach is very clean, IMHO.
Why should HTML contain Java code? Conversely, why should Java
code contain HTML? They're in different problem realms and there
should be a clear line of demarcation between them. Most developers
like the model-view-controller architecture once they've had a
chance to use it. The model contains and serves up the data in a
format which isn't tied to a particular output device. It's up to
the view to handle presentation. Whether you use XSLT or custom
tags with HTML (JSPs) to handle the presentation is up to you.
Perhaps I'm just confused by your use of terminology...
 
K

Kai Grossjohann

Sudsy said:
I think we need to take a step back and put things into prespective.
First off, the whole idea of JSPs is to have something which is
essentially HTML but with additional tags. They weren't intended
to be containers for scriptlets. They're compiled down to servlets
under the covers anyway so you could approach the problem from the
opposite direction and write servlets which pump out HTML code.
Neither approach is very clean, IMHO.
Why should HTML contain Java code? Conversely, why should Java
code contain HTML? They're in different problem realms and there
should be a clear line of demarcation between them.

I agree. Please note that the example I gave didn't contain Java
code, it was just an application of JSTL (plus a bean, but I guess
that using beans from JSP is okay).

By saying I want to "use JSP as an implementation language" I did NOT
Most developers
like the model-view-controller architecture once they've had a
chance to use it. The model contains and serves up the data in a
format which isn't tied to a particular output device. It's up to
the view to handle presentation. Whether you use XSLT or custom
tags with HTML (JSPs) to handle the presentation is up to you.
Perhaps I'm just confused by your use of terminology...

Maybe the confusing part is that I'm trying to make available *views*
as a component. Is it a bad thing to do? IMVHO it makes a lot of
sense -- lots of gooey frameworks contain view components.

The views I'm making available are quite specialized, though. So
there is a view that's specialized on displaying our idiosyncratic
variant of query forms, and there is another view that's specialized
on displaying our idiosyncratic variant of result lists, and so forth.
In theory, it would be a good idea to make the views more general
such that they depend less on the underlying model. But I believe
that one should start the journey on generalization with the first
step. And that first step is that somebody else can use my component
to visualize the idiosyncratic query form, before I generalize this
component such that it can visualize other query forms, too. And then
comes the step to generalize it such that it can visualize other forms
that aren't query forms.

Perhaps another piece of information (that I originally thought
irrelevant to our discussion) is that I'm trying to make a Windows-app
look-alike in the Web. (This entails its own problem, since the
powers that be don't grok the web. I'm trying to teach them...) And
the Windows app also comprises components. There is a "control" (I
think that's the right term for these things in the Windows world)
that you can drag and drop onto a "form" and then you set some
parameters and -- lo! -- you have a new Windows app that can display a
query form.

Now the idea is that the Web app is similarly comprised of components
that you can drag--oops. But the powers that be realize that
drag-and-drop is not so easy in the web world ;-) I think this idea
of providing components that others can use is a good idea.

And one last thing: of course a bunch of views does not an application
make. We also need models. But the models in my web app are just
Java beans, and designing Java beans such that they are reusable
components and stuff, that's just good old-fashioned software
engineering. That's the easy part, I don't need to ask about that
part ;-) If I do say so myself...

Kai
 
M

Mladen Adamovic

Kai Grossjohann said:
Well, even if I have five components and package them all in one
webapp, what about the users of the components?

What do you mean by the term "users"? Other application developer which
modify your code (1) or "ordinary" user which just put some data in your
query and USE final application (2).

For (1) if they change query then they have to change the classes query
depend to. I agree that that is not really code reusability in the term of
OO, and it could be worth thinking of avoid interclass dependenties.

For (2) I see no problems at all.
Presumably, the users
of the components would wish to access the same objects in the
session.

(For example, an application writer might wish to use my query form
component but slightly modify the query before it is processed. In
that case, the query form component and the application writer's file
would need to share a session.)

This is correct.
Is it true that two different webapps do not share a session?

1)from J2EE documentation:
Session information is scoped only to the current web application
(ServletContext), so information stored in one context will not be directly
visible in another.
2)It is simple to check with set/getAttribute I'm sure you can do that
quickly.
I think it should be true.


P.S.
Kai, about our talking about this - when I see your first message I wasn't
sure to answer or not, now with every new message I'm trying to think and to
help you, I'm not sure could I help you, becouse I couldn't help myself
often. Maybe it will be easiier if I could see your project and say my
opinions. And other people too i.e. Sudsy, he helped my twice allready and I
saw that he tried to help you.
Anyway, have a nice day.
 
M

Mladen Adamovic

The ordinary way to pack JSP files is to put webapp in the WAR file. (jar
files are ZIP files but with '.jar' extension :).
If you have five components and developer using your components want to use
two of them - he just won't use other three. But if in their design they
must to share session - pack them together in the same WAR file.
 
K

Kai Grossjohann

Mladen Adamovic said:
The ordinary way to pack JSP files is to put webapp in the WAR file. (jar
files are ZIP files but with '.jar' extension :).
If you have five components and developer using your components want to use
two of them - he just won't use other three. But if in their design they
must to share session - pack them together in the same WAR file.

The problem is that the developer using my components will also wish
to share session with the components: My components communicate via
the session, and it often makes sense to frob the objects in the
session.

For example, say a developer wishes to use the query form and also the
result list component, but for every query he wishes to add a column
to the result. (Tacking on the phone number for every employee by
looking at the in-house LDAP phonebook or whatever.) Then the
developer needs to access the result list object in the session.

Packing all the components in a *.war won't do much good -- his stuff
also needs to be in that *.war ;-)

Kai
 
K

Kai Grossjohann

Mladen Adamovic said:
What do you mean by the term "users"? Other application developer which
modify your code (1) or "ordinary" user which just put some data in your
query and USE final application (2).

I mean other application developers.
For (1) if they change query then they have to change the classes query
depend to. I agree that that is not really code reusability in the term of
OO, and it could be worth thinking of avoid interclass dependenties.

No, no. I didn't mean that they would have to change the source code
for the query class. I meant that they would like to change the
query itself. Like adding conditions, or removing conditions, or
altering conditions.

For a result list, the application developers might wish to remove
some items from it, or add more items, or sort the list, or add
additional fields (columns?) to each result item.
For (2) I see no problems at all.

Same here. The end users will see no problem, as soon as we have
solved the developer problems ;-) (Before that time, they won't see a
problem, either, but also no application to use.)
Kai, about our talking about this - when I see your first message I
wasn't sure to answer or not, now with every new message I'm trying
to think and to help you, I'm not sure could I help you, becouse I
couldn't help myself often. Maybe it will be easiier if I could see
your project and say my opinions. And other people too i.e. Sudsy,
he helped my twice allready and I saw that he tried to help you.
Anyway, have a nice day.

I appreciate a lot the time you're putting into it. I've been on the
helping side a few times, and so I know how it feels.

But dumping gobs of undocumented spaghetti code in your lap isn't
goind to help, either, I'm afraid. I've been working on it for some
months already, and I still don't grok it. But I've read Martin
Fowler's book on refactoring, so I'm working on it ;-)

Kai
 
M

Mladen Adamovic

Yes, I understand you. I develop reusable web application.
And directory structure are:
../src
../src/common
../administration
../web
../languages
../docs
etc.

ant build.xml in the base directory.
And pack it together (project is free) in zip file.
If developer want to modify my files and add his own he must to keep my
directory structure but he can add new dirs.
It is not perfect way, but I don't see one
(maybe using JBoss or WebSphere could help), but I don't see here no
problem.
 
M

Mladen Adamovic

Kai Grossjohann said:
No, no. I didn't mean that they would have to change the source code
for the query class. I meant that they would like to change the
query itself. Like adding conditions, or removing conditions, or
altering conditions.

I resolve that with class common.Configuration in my currect (and first
JSP/servlet project!).
I attached the source here, maybe it could give you some ideas.
For a result list, the application developers might wish to remove
some items from it, or add more items, or sort the list, or add
additional fields (columns?) to each result item.

Off course.
Same here. The end users will see no problem, as soon as we have
solved the developer problems ;-) (Before that time, they won't see a
problem, either, but also no application to use.)
:))).

But dumping gobs of undocumented spaghetti code in your lap isn't
goind to help, either, I'm afraid. I've been working on it for some
months already, and I still don't grok it. But I've read Martin
Fowler's book on refactoring, so I'm working on it ;-)

I've to work a lot too, and I know how it seems.


//Configuration.java
package common;
import java.sql.*;
/**
* Configuration entries you can read or change to change appearance or
settings
* i.e. upload directory, registeration type
* @author Mladen Adamovic ([email protected])
* @see LICENCE.TXT
*
*/
public class Configuration
{
/**
* Upload directory for user pictures
*/
static public String uploadDir="/uploads/";

/**
* user is register just after succesfully completing registeration form
*/
static public int REG_AUTO=1;

/**
* user is register when administrator manually check his(her) data
* and validate in database
*/
static public int REG_MANUAL=2;

/**
* user is register if his e-mail address is valid (program send him a
e-mail
* message with his(her) new password
*/
static public int REG_EMAILCHECK=3;


/**
* current registration type
*/
public int current_reg_type=REG_AUTO;


/**
* Here enter the name of SQLServer you want to use. Currently supported
* "MySql","hSQLdb"
* but you can imitate existing configuration and make support for other
* databases */
public String SQLServer="MySql";

/**
* name of MySQL driver
*/
public String MySqlDriverName="com.mysql.jdbc.Driver";


/*
* name of hSQLdb driver
*/
public String hSQLdbDriverName="org.hsqldb.jdbcDriver";

/**
* change MySQLDBURL if neccessery
*/
public String
MySqlDbURL="jdbc:mysql://localhost/photo?user=guest&password=guest";

/**
* change hSQLdbURL if neccessery
*/
public String hSQLdbURL="jdbc:hsqldb:hsql://localhost";
public String hSQLdbUser="sa";
public String hSQLdbPass="";


/**
* NOTE: Here you may want to change implementation details
* @param name of SQLserver you want to use i.e. MySQL, hSQLdb
* @return Connection to the SQLserver named in parameter
*/
public Connection getConnection()
{
Connection con;
try
{

if(SQLServer.toUpperCase().equals("MYSQL"))
{
//make connection
Class.forName(MySqlDriverName).newInstance();
con = DriverManager.getConnection(MySqlDbURL);
return con;
}
else if(SQLServer.toUpperCase().equals("HSQLDB"))
{
Class.forName (hSQLdbDriverName);
con = DriverManager.getConnection (hSQLdbURL, hSQLdbUser, hSQLdbPass);
return con;
}
else
{
System.out.println("Error in SQLServer name.");
System.exit(0);
}
}
catch (Exception e) {
System.out.println("ERROR: failed to load HSQLDB JDBC driver.");
e.printStackTrace(); }
return null;
}

/**
* @return registeration type
*/
public int getRegType()
{
return current_reg_type;
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top