I'm working on a project that uses an old, custom-built CMS to run a website that is quite heavy in JavaScript. Throughout a given template (.jsp), they're using Java conditionals to set up inline JavaScript variables and functions. They're also making external JavaScript and CSS requests all over the place. This has led to some very poor performance, as you can imagine.
I'm trying to organize things so that most of the JavaScript is in external files, being called before the closing body tag. One of the tricky parts of this is externalizing inline JavaScript when they're using Java to create variables. As far as i know, I can't drop bits of Java into a .js file.
The solution I've come up with is to create an object into which Java can print some variable values, and then pass them on to the external JS files. For example:
var foo = new Object;
foo.bar = <s:property value="bar" escape="false"/>;
Then in the external file:
(function(){
console.log(foo.bar);
}());
From a conceptual standpoint, does this seem like a valid solution? It seems to work fine, but I'm wondering if there's a specific reason that I shouldn't do it this way. Please excuse my wording if I'm not using the proper terms.
Related
I have some text templates stored in a database. We need to use a templating engine to process these texts. We first thought of Velocity / Freemaker / Thymeleaf to process these texts. However, I thought (but could be wrong) that one could interact with the application server JSP compiler. I'd prefer to use JSP compiler rather than importing a new bunch of jars.
Thanks
AFAIK they are different concepts and work differently so they won't directly interact :
JSP is processed by a JSP compiler to generate java code for a servlet that is compiled (at run-time) in a .class file. It is later used by the servlet container as any other servlet. You can include any java code in a JSP with scriptlets (even if it now considered as bad practice)
template engines (Velocity / Freemaker / Thymeleaf) take a template and only allow to replace variable place holders with values at run time to produce text. Of course, they also allow tests and loops, but no java source nor class object is ever generated. In a web application they use one single servlet that takes the template and the replacement values and generate the text that will be sent in the response.
But of course as JSP can contain arbitrary java code, you could call a template engine from a JSP, but I really cannot imagine a proper use case.
Edit per comment:
You could try to use JSP as a template engine, but my advice is : don't do that ! You would need :
create a stub implementing ServletResponse where the getOutputStream() and the getWriter() methods end in a String.
force the ServletContainer to generate the java source and the class file - or manage to do that at compile time (I don't know how exactly how to do that, but I'm pretty sure it can be done)
at run time include the generated servlet with the response stub to generate the output String.
But beware, even if you succeed, it will lead to hardly maintainable code heavily coupled to a servlet container or using special steps (JSP -> java) at build time. As already said : don't do that.
I've just come to JSP compilation to string or in memory bytearray with Tomcat/Websphere, looks like your question is a duplicate of that one ...
the problem is quite simple yet maybe not resolvable?
Atleast for me :/
Situation:
Let's say I have a dynamic Page System where the Server provides additional copies of self containing GWT Modules. Meaning a main GWT instance on the client side is supposed to manage the new incoming GWT Scripts, which are simply added by the main instance itself using Tags.
Now the main GWT instance needs to communicate with the newly created script instances in the most easiest (GWT internally) way possible.
So what is out of the question: Writing stupid JSNI Wrappers on both sides, if not absolutely required.
Soltuions I came up with were:
Make a module both use, including a common interface, example:
package com.whatever.interfaces;
public interface Communication {
void showMessage(String message);
}
So both would now inherit this module and know of the definition.
The main client would now load the dynamic JS and register an implementation of Communication and the dynamic one would go and use it. I tried storing references on $wnd and on elements using setPropertyObject. On $wnd they are null, which maybe/probably related to the the GWT Iframing? For the property on the RootPanel element for example, ClassCastException would be raised.
Is there any good way to encounter this? Another idea I have is using JSNI for calling the interface as an implementation on the bridge module, but I'm not sure if this a good way.
Your help is appreciated, thanks.
EDIT:
Well I have pretty much come to the conclusion that this is not possible whatsoever.
Even though you might have used same interfaces somewhere, they will be very own instantiations of it, for different modules compiled, even if using the same module as a common ground.
The approach using JSNI certainly is somewhat possible, but not without mapping all attributes to real JS Objects and remapping them back. Meaning you can't pass complex Java Objects around like you probably would be used to. My conclusion would be, using CodeGenerators you could build the JSNI Wrappers automatically and the remappers, for both modules, but this is too much of a hassle for me.
I'm still open if someone comes up with a better idea, but I just want to provide some inside on my findings, so others can benefit of my wasted time ;)
A while ago, I created a simple prototype implementation to share Object instances to other GWT modules. You can find the code on https://code.google.com/p/gwt-plug/. And yes, as you described, it's a problem to transfer Java objects. As far as I remember, you can only transfer primitive values (int, float, ...), Strings and JavaScriptObjects. But JavaScriptObjects are a good possibility
As you already found out communicating between separately compiled GWT modules is somewhat of a challenge since everything is obfuscated. It is possible though through javascript, JSNI, JSO's and JSON.
You can use JSNI to create communication hooks through javascript directly on the $wnd object. Sort of an event bus approach would work.
You can use JSON to pass around complex objects.
You can use JSO's (JavaScript Overlays) to consume and manipulate the JSON in each of the disperate modules.
Putting all that together you would end up with a mini-framework library module that you would share between the various GWT modules you want to have communicate with each other. They would each inherit the common framework module and compile in their own obfuscated form but since they are using javascript and JSON as a common language they won't have to worry about the obfuscation.
Make sense?
As explained in the xsee's answer, you can create a hook from GWT using JSNI
In order to do this, take a look to very useful project http://code.google.com/p/gwt-exporter/
I need to store a few configuration parameters on the client side of my GWT app--I'm only using the client side of the framework. I just want to store things like an API access URL base.
Ideally, it would be nice if this were dynamically read, but I can live with having the values statically baked in on every compilation.
When scouring the web for answers, I kept running into all the deferred binding and locale management stuff. I don't care about any of that. I just want to set some property like api.url and read it from the Java code. Failing that, I'd like to set it in an external JavaScript file and read it in from the main generated JS code somehow. However, keeping it simple is an important goal; I don't want to go down the path of some Rube Goldberg-esque JSNI monstrosity.
Is there any means of accomplishing that with some sort of properties files, or a simple JSNI import mechanism? Or am I pretty much stuck with using a Constants-based configuration class (which still requires a recompile to bake in)?
This is what you're looking for: http://www.gwtproject.org/articles/dynamic_host_page.html
In order to escape from the compilations each time when configuration changed i would like to suggest the RPC call of configuration parameters in onmodule load.
In onsuccess you can assign those parameters to your Gwt static variables,those available throughout the Gwt code.
This may reduce the pain,you can change the parameters on serverside and deploy again,No Need To Compile each time for a single line change.
You can define a property on the module xml. Like this:
<define-property values="desenv, production" name="environment"/>
<set-property name="environment" value="production"/>
This question already has answers here:
How can I avoid Java code in JSP files, using JSP 2?
(31 answers)
Closed 3 years ago.
What is the advantage (if there is one) of using a custom action instead of a scriptlet?
For example, which is better in a performance context?
<c:if test="${param.Clear}">
<font color="#ff0000" size="+2"><strong>
You just cleared your shopping cart!
</strong><br> <br></font>
</c:if>
or
<%if (param.Clear){%>
<font color="#ff0000" size="+2"><strong>
You just cleared your shopping cart!
</strong><br> <br></font>
<%}%>
I have a big JSP project and I want to know if is necessary to use tag libraries or if I can keep my Java scriptlets.
Also, I want to implement custom tags for some things that now are separate JSP files with Java, JavaScript, CSS, and HTML code.
As far as performance goes, they both get compiled down to servlets, so they should perform equally well.
There doesn't seem to be much to recommend JSTL in the example you give, but what happens to projects I've seen is code like:
<%if (param1.Clear() && param2.isSomeFlagSet() && !param3.isSomeOtherFlagSet()){%>
<font color="#ff0000" size="+2"><strong>
You just cleared your shopping cart!
</strong><br> <br></font>
<%}%>
and it gets copied all over. >_< If you replace this with JSTL mechanically you can get something just as bad, obviously, but it gives you an opportunity to organize things better.
Follow BalusC's advice and get rid of inline Java code from your JSPs where you can.
I love JSP. I think its the best of the Java page serving markup languages. It's main fault is that it doesn't work well for things like emails and such, since you can't just pass a string and a map to an evaluator and get a result back like you can with something like Velocity.
But beyond that use case, JSP is great.
To answer your question, you can still retain your scriptlet code. Something like a scriptlet "if" vs a c:if tag is certainly going to be faster CPU wise since an "if" is simply an if whereas a c:if is a method call plus some environmental shenanigans when invoking the tag.
That said, it's a different question as to how much of an impact that speed difference makes.
Most of the code shouldn't be in the JSP, obviously, the logic should mostly be in the Servlet or whatever else you're using on your back end, and the JSP contains just rendering code (which can certainly involve IFs and FORs etc.)
The primary argument against scriptlets is JSP Tag Files. Tag files are what separate JSP from the others. JSP Tag files make JSP refactorable, and make adding new tags painless. But the downside is that when using Tag Files, any tags your create can not have scriptlet code within their boundaries.
For example, if you created a "TABLE" tag, anything between the t:table and /t:table elements could not have scriptlet elements. However, you can certainly have scriptlet code within the Tag File implementations, so I just wrap any scriptlet stuff I need in those.
You can go here: JSP tricks to make templating easier? for an overview of Tag Files. But we go far beyond that here. We define forms and tables and components and all sorts of stuff using Tag Files.
Here is why I think JSTL is the better choice.
Using JSTL is easier to read.
If you created a method in your JSP, then only that JSP can use it. So reusability is also one.
pageScope and requestScope objects are already readable using ${foo} and not request.getAttribute('foo')
Cons - There are somethings you just can't do in JSTL.
I'd rather get rid of JSP at all...
I have worked with JSP now for 6 to 8 years and it is simply not worth using. A template engine gives you a better turn around.
There may be some negligible performance differences between the two options you proposed, however I do not think runtime performance is really the problem that Tag Libraries are intended to solve.
IMHO, the valid arguments against scriptlets are almost all about coding, debugging and maintenance concerns. One of the main reasons JSP has been derided for so long is not so much about JSP, but more about how people have used it. There is nothing worse then opening a JSP (that someone else wrote) in your IDE and seeing this spaghetti code mess of scriptlets and HTML. If you want to mix server side code and HTML all over the place, you might as well go and code in PHP! :)
Using Taglibs will make your JSPs way easier to develop initially, debug quicker and maintain over the long run.
I think scriptlets are such a poor option, that I always like to add something similar to this little snippet to my web.xml files when starting a new project:
<jsp-config>
<jsp-property-group>
<url-pattern>*.jsp</url-pattern>
<scripting-invalid>true</scripting-invalid>
</jsp-property-group>
</jsp-config>
This turns off scriptlet evaluation in the JSPs inside the web app, forcing developers to find better alternatives.
Another big argument for Taglibs is that you will be coding in a more rigorous manner. For example, you will have to handle any exceptions thrown in your code (one way or another) when you write a Taglib. If you write the same code in a scriptlet, you will not be prompted by your IDE or the JSP compiler to wrap the code in a try-catch block. Lazy/unprofessional programmers will probably rejoice at avoiding having to write a few lines of error handling code. Real programmers know from experience that catching exceptions and handling them properly in Java is way easier, cleaner and robust than having JSPs throw exceptions at runtime. Also if you are into JUnit etc. then unit testing taglibs is pretty straightforward - by definition you probably can't really unit test a JSP, at best you might be able to do some kind of integration test.
Also, as someone also mentioned, there is an architectural benefit to using Taglibs. The code design and reuse factor is way in favor of Taglibs. There is no easy way to share scriptlet code that is embedded in a JSP file. So you end up with copy-paste coding all over the place.
I am investigating large project that uses FreeMarker. I am newbie to FreeMarker. How I can find which classes of java are used to receive values for templates? Investigate all project seems enormous work.
Thanks.
May be need some plugins for Eclipse?
FreeMarker is a typical "dynamic language", which means refactoring/changing is hard. The templates don't declare what they expect to be in the data-model. Furthermore, when a template tries to read a value from the data-model, like with ${foo.bar}, it could mean foo.get("bar") or foo.getBar() or whatever the ObjectWrapper used makes possible, and it's only decided when the template is executed. Certainly you will need to fall back to good-old search-and-replace and lot of testing (a good test suite is essential...) if you change something. And of course, you could look at the place in the program where the data-model is built, and see what was put into it. Or dump the data-model somehow on runtime.