I have a Vaadin 7 application where I originally had just one UI. The following things happened, which I did not mind and even liked:
When installed new WAR file, all browser tabs currently opened to that URL gave the black "Connection failed" or "Session expired" error, forcing me to refresh. Also, I would often get a "server loading" error in the upper right corner while the application deployed. This one is kind of hard to explain, but hopefully this makes sense. None of this was triggered by my code directly, all of it was behavior I got from Vaadin out of the box.
If I was logged in to the same website (and same user) in multiple browser tabs, and then logged out of one tab, my code to logout/inactivate all tabs worked great - they all went back to the login screen, as I coded them to.
At that time, I had web.xml as follows:
web-app id="WebApp_ID" version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name>vaadinwebsite</display-name>
<context-param>
<description>Vaadin production mode</description>
<param-name>productionMode</param-name>
<param-value>${productionMode}</param-value>
</context-param>
<servlet>
<!-- <servlet-name>WmsUIServlet</servlet-name> -->
<servlet-name>WmsServlet</servlet-name>
<servlet-class>com.mobiwms.website.WmsServlet</servlet-class>
<init-param>
<param-name>UI</param-name>
<param-value>com.mobiwms.website.WmsUI</param-value>
</init-param>
</servlet>
<servlet-mapping>
<!-- <servlet-name>WmsUIServlet</servlet-name> -->
<servlet-name>WmsServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<!-- Uncomment if add more than one UI
<servlet-mapping>
<servlet-name>Vaadintutorial</servlet-name>
<url-pattern>/VAADIN/*</url-pattern>
</servlet-mapping>
-->
... <!-- some other stuff-->
</web-app>
I recently added a second UI, which meant I needed to tweak the path of the first UI. So I did the following:
Changed web.xml so it uses 3.0, and comment out servlet references in web.xml so it would use WebServlet annotations in the code.
Changed the url pattern of my first UI from #WebServlet(urlPatterns = "/*", name = "WmsServlet", asyncSupported = true) to #WebServlet(urlPatterns = {"/*", "/VAADIN/*"}, name = "WmsServlet", asyncSupported = true), as per the documentation. So this makes it so the "root" application is my main UI, like it was when I only had one UI. As per my web.xml snippet above, I always had a url pattern of "/*".
Added a new UI and url pattern using #WebServlet(urlPatterns = "/Registration/*", name = "WmsRegistrationServlet", asyncSupported = true).
Now I am getting the following weirdness:
Installing a new WAR does not force me to refresh. In other words, I don't even notice I need to refresh until I start doing something, at which point I get the normal black "communication failed", like normal.
When I am logged in on two tabs and logout, it definitely invalidates the session in the other tab (I see the black "communication failed" error), but it does not go back to the login screen like it used to.
At various times we see a failed to load widgetset error.
On occasion, when we are doing things, like uploading files, we get the black "communication failed" error.
The 2 UIs and servlets are much the same, just a different layout. The newer UI is a registration UI and so really only has one form, one view, and is very simple. The other is a full fledged application.
I tried it with asyncSupported = false on my newer application (the Registration UI), but that did not work. I then commented out #WebServlet(urlPatterns = "/Registration/*", name = "WmsRegistrationServlet", asyncSupported = false), so effectively my new UI is not accessible. This did not fix it either.
Since I also changed the web.xml such that I am using 3.0 (web.xml had 2.5 before this), I changed asyncSupport to false for both my UI servlets so it matches the default behavior for 2.5. This also did not fix it.
So then I commented out the Registration WebServlet annotation again and changed #WebServlet(urlPatterns = {"/*", "/VAADIN/*"}, name = "WmsServlet", asyncSupported = false) to #WebServlet(urlPatterns = "/*", name = "WmsServlet", asyncSupported = false) (so got rid of VAADIN reference). This actually fixed things, and now things work like before. So am I handling 2 UI's wrong? Maybe I am dealing with "/VAADIN/*" wrong?
Ok, after reading the documentation multiple times, I finally noticed one minor point they made:
You do not have to provide the above /VAADIN/* mapping if you serve
both the widget sets and (custom and default) themes statically in the
/VAADIN directory in the web application. The mapping simply allows
serving them dynamically from the Vaadin JAR. Serving them statically
is recommended for production environments as it is faster. If you
serve the content from within the same web application, you may not
have the root pattern /* for the Vaadin servlet, as then all the
requests would be mapped to the servlet.
So once I changed #WebServlet(urlPatterns = {"/*", "/VAADIN/*"}, name = "WmsServlet", asyncSupported = false) to #WebServlet(urlPatterns = "/*", name = "WmsServlet", asyncSupported = true), things worked much better. Since I am not using the VAADIN jar file, but the Vaadin stuff is in my WAR file that gets exploded to a directory (the default setup, as far as I know), it is effectively static, thus this works.
BTW, I set asyncSupported = true to get around the "A filter or servlet of the current chain does not support asynchronous operations." error (I mention this error here), although, honestly, I am not 100% sure I had to. Since it seems not to be hurting me, I left it as "true".
Related
I thought I'd got all my routing sorted! Just one little glitch to sort out, but first I need to explain our set-up.
I decided against a catch-all router, and instead am trapping HTTP errors in my web.config file (this question helped). First I turned the old-fashioned CustomErrors off:
<!--<customErrors mode="Off" />-->
Then I turned HTTP error-trapping on:
(as often happens, I couldn't seem to insert this as script). In the interests of full disclosure, my web.config file includes this:
I'm not trapping any application errors in Global.asax.cs. This all works fine - I then have a router which picks up on 404 errors:
routes.MapRoute(
"Error 404",
"Error/MissingPage404",
new { controller = "Error", action = "MissingPage404" }
);
and another for 500 errors:
routes.MapRoute(
"Error 500",
"Error/ServerError500",
new { controller = "Error", action = "ServerError500" }
);
My question is: how can I stop static files being trapped by this? I've already solved the problem for images, thanks to this question, which is to include these lines at the top of my routing config file:
routes.IgnoreRoute("{*allfiles}", new { allfiles = #".*\.(gif|jpg|png|ico)" });
However, the equivalent doesn't work for .js, .ico, .css or .zip files. I tried from another site:
routes.IgnoreRoute("{*allaspx}", new { allaspx = #".*\.css(/.*)?" });
routes.IgnoreRoute("{*allaspx}", new { allaspx = #".*\.ico(/.*)?" });
but that did nothing either. Again in the interests of disclosure, I've got this line at the top of the routing config file, but my understanding is that this only affects files which are found:
routes.RouteExistingFiles = true;
Can anyone help? It seems like MVC is brilliantly thought out, right up until the point of making routing easy to understand and implement.
Many thanks in advance
Andy
To read a properties file in JSF2.0 with Glassfishv3 webserver, which is located at root directory of my web application, I am using below code-
ServletContext ctx = (ServletContext) FacesContext
.getCurrentInstance().getExternalContext().getContext();
String deploymentDirectoryPath = ctx.getRealPath("/");
Properties prop = new Properties();
prop.load(new FileInputStream(deploymentDirectoryPath
+ File.separator + "portal-config.properties"));
Below is the screenshot of web portal-
While running the portal I am getting FileNotFound Error, since the file is not present in glassfish domain.
Is there any way to read properties file which can work in both the situations, at development stage and in war file also?
You should never use java.io.File to refer web resources. It knows nothing about the context it is sitting in. You should also never use ServletContext#getRealPath() as it may return null when the server is configured to expand WAR file in memory instead of on disk, which is beyond your control in 3rd party hosts.
Just use ExternalContext#getResourceAsStream() to get the web resource directly in flavor of an InputStream. It takes a path relative to the webcontent root.
ExternalContext ec = FacesContext.getCurrentInstance().getExternalContext();
properties.load(ec.getResourceAsStream("/portal-config.properties"));
See also:
getResourceAsStream() vs FileInputStream
What does servletcontext.getRealPath("/") mean and when should I use it
Where to place and how to read configuration resource files in servlet based application?
Update it does not seem to be a web resource at all. You should move the file into the "WebContent" folder as shown in the screenshot. Or, better, the /WEB-INF folder so that nobody can access it by URL.
properties.load(ec.getResourceAsStream("/WEB-INF/portal-config.properties"));
An alternative would be to put it in the classpath, the "Java source" folder as shown in the screenshot. You don't need to put it in a package, that's optional. Assuming that you didn't put it in a package, then do so:
ClassLoader cl = Thread.currentThread().getContextClassLoader();
properties.load(cl.getResourceAsStream("portal-config.properties"));
(note that the path may not start with a slash!)
I need to use some connectors which are actually servlets. How can I do this in Grails and what about the web.xml? How do I configure the url of the servlet?
I actually have a Spring application here and I am trying to convert it into a partial Grails app. I have a connector servlet in the spring-app, which I wish to use here but the mapping is a must to call the servlet in the gsp file. How can I do this? I basically need to know where the xml file is in case of Grails.
To get the web.xml file, you can run:
grails install-templates
Then, the file can be found in:
<yourapp>/src/templates/war/web.xml
Edit this as usual to add <servlet> and <servlet-mapping> sections, then put your servlet code in:
<yourapp>src/java/your/package/structure/WhateverServlet.java
and you should be good to go
If you are within a grails-plugin, then you have a defined place within your *GrailsPlugin.groovy, where to do such things. E.g. Look at the auto generated closure:
def doWithWebDescriptor = { xml ->
[]
}
In here you can add your custom servlet configurations:
def servlets = xml.'servlet'
servlets[servlets.size() - 1] + {
servlet {
'servlet-name'('yourName')
'servlet-class'('yourpackage.YourClass')
}
}
def mappings = xml.'servlet-mapping'
mappings[mappings.size() - 1] + {
'servlet-mapping' {
'servlet-name'('yourName')
'url-pattern'('/yourPattern/*')
}
}
good news and bad news, and I myself have asked this question here before. With spring application you can have multiple level of URI such as domain.com/abc/def/efg/abc vs grails has a lot of issue with anything beyond domain.com/controller/view. here is a link to my original question: Grails URL mapping cause error on GSP
The good news is, you don't need to deal with XML mapping, grails does it seemlessly by controllers and views. So you are almost limited to domain.com/YouController/YourView/SomeParamteres... but if thats all you'll need, all u have to do is create grails-app/Controller/SomethingController.groovy and you automatically have domain.com/Something
Currently we need fetch mails from an IMAP server using Mule ESB. Once the mails have been fetched, we only need the attachments and save them on the harddrive. So far so good. Now I got a couple of questions:
How do I keep the original name intact using a file:outbound-endpoint?
How can I check how many attachments I got?
How do save a copy of the mail on the IMAP and local drive?
#1: I tried #header:fileName or #originalFileName or even removing the outputpattern (this results in the filename being "35c7dea0-519a-11e1-b8b2-092b658ae008.dat")
#2: I am trying to make a flow where I check how many attachments there are. If there are less then 1 then I want to save the files and no further process them. If it's more then 1, then save it and process it. I tried COUNT but it didn't work.
#3: am trying to MOVE a message when READ to a back-up folder on the IMAP-server. On top of that I'll save a copy on the local server. Problem is that with the current code, the message does not get marked as read nor moved. The messages stay unread and they get copied (over and over, enldess loop) instead of getting moved to the IMAP back-up folder. When enabling the deleteReadMessages then the loop is broken but the message does not get copied on the IMAP.
Here's the code I am currently using:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:spring="http://www.springframework.org/schema/beans"
xmlns:imap="http://www.mulesoft.org/schema/mule/imap"
xmlns:file="http://www.mulesoft.org/schema/mule/file"
xmlns:email="http://www.mulesoft.org/schema/mule/email"
xmlns:vm="http://www.mulesoft.org/schema/mule/vm"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/3.2/mule.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/3.2/mule-file.xsd
http://www.mulesoft.org/schema/mule/imap http://www.mulesoft.org/schema/mule/imap/3.2/mule-imap.xsd
http://www.mulesoft.org/schema/mule/email http://www.mulesoft.org/schema/mule/email/3.2/mule-email.xsd
http://www.mulesoft.org/schema/mule/vm http://www.mulesoft.org/schema/mule/vm/3.2/mule-vm.xsd">
<imap:connector name="imapConnector" checkFrequency="5000"
backupEnabled="true" backupFolder="/home/mark/workspace/Eclipse/RHZ_Project/src/Archive/"
mailboxFolder="INBOX" moveToFolder="INBOX.Backup" deleteReadMessages="false"
defaultProcessMessageAction="SEEN" />
<expression-transformer name="returnAttachments">
<return-argument evaluator="attachments-list" expression="*.txt,*.ozb,*.xml" optional="false"/>
</expression-transformer>
<flow name="Flow1_IMAP_fetch">
<imap:inbound-endpoint user="USER" password="PASS" host="IP"
port="143" transformer-refs="returnAttachments" disableTransportTransformer="true"/>
<collection-splitter/>
<file:outbound-endpoint path="/home/mark/workspace/Eclipse/RHZ_Project/src/Inbox/#[function:datestamp].dat">
<expression-transformer>
<return-argument expression="payload.inputStream" evaluator="groovy" />
</expression-transformer>
</file:outbound-endpoint>
</flow>
</mule>
1) How do I keep the original name intact using a file:outbound-endpoint?
Attachments are javax.activation.DataHandler instances so you should be able to call getName() on them, with an OGNL or Groovy expression. For example:
#[groovy:payload.name]
Should give you the original attachment name.
2) How can I check how many attachments I got?
Before the splitter, use a choice router and an condition that checks the size() attribute of the attachment list, like:
#[groovy:payload.size()>1]
3) How do save a copy of the mail on the IMAP and local drive?
I do not know what the issue is here. Maybe marking as seen is not supported. Or maybe the fact that you disable the transport transformer prevents a post-read action to kick in.
By the way, I suggest you leave the default transport transformer as-is and move the returnAttachments transformer after the inbound endpoint, before the splitter.
Does Apache Tiles have a devMove like Struts that would reload the tiles.xml file with each request? If so, how can this be enabled?
Here is another working configuration that uses Listener instead of Filter.
(since Tiles 2.1.2)
In web.xml:
<context-param>
<param-name>org.apache.tiles.definition.dao.LocaleUrlDefinitionDAO.CHECK_REFRESH</param-name>
<param-value>true</param-value>
</context-param>
<listener>
<listener-class>org.apache.tiles.web.startup.TilesListener</listener-class>
</listener>
I've used tiles, but have never tried to dynamically reload it.
However, this page : http://tiles.apache.org/tutorial/configuration.html
says:
Load the Tiles filter. It is useful if your definition files can be changed and you periodically need to reload them.
The following has worked for me using tiles 2.2.2 inside servlet container.
....
import org.apache.tiles.definition.DefinitionsFactory;
import org.apache.tiles.definition.UnresolvingLocaleDefinitionsFactory;
import org.apache.tiles.definition.dao.ResolvingLocaleUrlDefinitionDAO;
import org.apache.tiles.impl.BasicTilesContainer;
import org.apache.tiles.servlet.context.ServletUtil;
//When using SimpleTilesListener => BasicTilesContainer is returned
//When using StrutsTilesListener => CachingTilesContainer is returned which extends BasicTilesContainer
BasicTilesContainer tilesCont = (BasicTilesContainer) ServletUtil.getContainer(ServletActionContext.getServletContext());
DefinitionsFactory defFact = tilesCont.getDefinitionsFactory();
Field field= UnresolvingLocaleDefinitionsFactory.class.getDeclaredField("definitionDao");
field.setAccessible(true);
ResolvingLocaleUrlDefinitionDAO rludDAO = (ResolvingLocaleUrlDefinitionDAO)field.get(defFact);
rludDAO.refresh();