I am using Servlet in Struts2. Once the process in Servlet is completed, I need to call a Struts2 action. I am using <constant name="struts.action.excludePattern" value="/myServlet"/> in my struts.xml. How can I call a Strtus2 action from my Servlet?
Solved : Added <dispatcher>REQUEST</dispatcher> <dispatcher>FORWARD</dispatcher> in web.xml
Related
I have a several servlets and in my case I need to implement ServletRequestListener. But, I don't want the listener to react on every request in any servlet. I would like to know if there any possibility to map a specific ServletRequestListener to a specific certain servlet. My web.xml looks like:
<servlet>
<servlet-name>CommonsServlet</servlet-name>
<servlet-class>
com.promptlink.dslib.gwt.common.server.rpc.CommonsServletImpl</servlet-class>
</servlet>
...
<listener>
<listener-class>
com.promptlink.dslib.gwt.common.server.httpListeners.ServletRequestListenerImpl
</listener-class>
</listener>
That's not possible with a ServletRequestListener. A servlet request listener listens on every servlet request. Just create a Filter instead which you can simply map directly to servlet name (no, not to its URL pattern, that's maintenance unfriendly).
<filter>
<filter-name>CommonFilter</filter-name>
<filter-class>com.example.CommonFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CommonFilter</filter-name>
<servlet-name>CommonsServlet</servlet-name>
</filter-mapping>
See also:
Our servlet filters wiki page
Why do we need a servlet name?
If you only want to react on the requests of a specific servlet then the servlet itself would be the ideal place to do this.
If you don't control the servlet code you can write a Filter and give it the same URL pattern as the servlet or directly refer to the servlet in the filter mapping.
We have an existing application not using Spring MVC. We decided to keep existing features as is and add Spring MVC in for any other new features through a url like "/admin/*.
so here is the web.xml mapping:
<servlet>
<servlet-name>springRouted</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/mvc-config.xml</param-value>
</init-param>
<load-on-startup>4</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springRouted</servlet-name>
<url-pattern>/admin/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ExistingServlet</servlet-name>
<url-pattern>existing.do</url-pattern>
</servlet-mapping>
Here in the ExistingServlet, there is a call to request.getRequestDispatcher().forward("/admin/...jsp"), somehow Spring will detect this fowarding and report an error that not able to find mapping for "/admin/...jsp". It seems calling request.getRequestDispatcher().forward("/admin/...jsp") will make servlet container to recheck the web.xml and reroute through Spring's DispatchServlet. is it true? I thought this kind of internal forward won't be intercepted by Spring's DispatchServlet
A RequestDispatcher will be resolved against the mappings you have in your deployment descriptor (web.xml) or other Servlet configuration, basically all servlet mappings.
When you do
request.getRequestDispatcher("/admin/...jsp");
The Servlet container finds the Servlet (or other resource) meant to handle that path and wraps it in a RequestDispatcher object. When you then perform RequestDispatcher#forward(..) on the returned object, you are executing the service() method of the Servlet that was previously found.
In your example, that would be the DispatcherServlet. If your DispatcherServlet is configured to handle a request to /admin/...jsp, then it will do so. If not, it will throw its own custom exception, responding to the HTTP request with a 404.
Here are some more details on how getRequestDispatcher() works.
I am new to struts and as far as i know that .do extension causes the tomcat to call the action servlet and action servlet has resource process object that invokes a particular action class
But lets suppose we have a jsp page
first.jsp
<%# taglib uri="http://struts.apache.org/tags-html" prefix="s" %>
<s:form action="myform">...
when we submit this form
action-mapping in struts.config.xml is called and it picks from there as:
<action input="/first.jsp" name="actionformbean" path="/myform" scope="session"
type="actionclass"/>
whenever http://....myform.do is encountered, tell the resource process object of the action servlet to invoke actionclass
BUT how is action mapping related to servlet mapping(as url pattern .do is given in here ?)
I am confused with this .do, that how is it appended to the url :(
HELP plz
thanks !!
The standard Action Servlet mapping for Struts is defined in your web.xml, the deployment descriptor. It goes like this:
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
The servlet-name is defined earlier in the deployment descriptor:
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
...
</init-param>
<load-on-startup>2</load-on-startup>
...
</servlet>
The url-pattern binds all urls ending with .do to the Action Servlet. The Action Servlet in turn delegates all calls to the responsible action.
Now, there are action mappings like the one you mention:
<action input="/first.jsp" name="actionformbean" path="/myform" scope="session"
type="actionclass"/>
Action mappings have a path that specifies their URL. The URL doesn't need a .do suffix because Struts already "knows" it was called, otherwise the action mapping itself couldn't be executed. Once the specified action is executed, it silently appends a .do suffix since only URL with those suffixes will be matched - otherwise the next request would be lost.
"Thanks for the reply, but you have written that url-pattern binds all urls ending with .do to action servlet. I am still confused is how .do will be appended to the url"
The .do is automatically appended by default by the Struts Frame work(Hope it's been done by ActionServlet itself). If you wish to change the extension(say .abc), then you should modify the action value accordingly (as action="actionsomthing.abcd").
Corrections are appreciated
For a Java EE web application,
I have a listener that implements ServletRequestListener, and a Filter.
Is there a way to specify at web.xml that the filter should be called before the listener?
I've already tried declaring the filter and its mapping before the listener,
but the listener is still executed before.
Any idea?
<filter>
<filter-name>myfilter</filter-name>
<filter-class>com.example.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>myfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>com.example.MyServletRequestListener </listener-class>
</listener>
When Browser(client) request to the Server , the container like (Tomcat) create the Request Object for the client request HttpServletRequest and Response Object HttpServletResponse and
if you configure any listener which implements "ServletRequestListener" then "public void requestInitialized(ServletRequestEvent sre)" method will call
After creation of Request and Response Object by container if there is any listener for Request then Listener will execute first.....
After that HttpServletRequest and HttpServletResponse are assign to the Fillter , if you have configure the Fillter....
Means Listener come in picture first for ServletRequest .
So there is no way to configure to make Fillter execute before Listener in ServletRequest case ....
The ServletRequestListener.requestInitialized() will be initialized before any filter is invoked and ServletRequestListener.requestDestroyed() after all filter and service method returns.
I have a requirement to intercept all the request in spring 2.5. I don't want to use HandlerInterceptor to intercept the request because it requires to configure it with every SimpleUrlHandlerMapping bean in the context files. Is there another way to intercept all the request without using HandlerInterceptor?
You could implement a filter and map it to the DispatcherServlet in web.xml. Then you should be able to intercept all request made to Spring MVC.
In short:
Create an implementation of javax.servlet.Filter
Add the filter to web.xml
<filter>
<filter-name>MyFilter</filter-name>
<filter-class>mypackage.MyFilter</filter-class>
</filter>
and then map it to the DispatcherServlet (servlet-name should be the same that is defined for the Spring Dispatcher servlet.
<filter-mapping>
<filter-name>MyFilter</filter-name>
<servlet-name>DispatcherServlet</servlet-name>
</filter-mapping>
If you need access to the Spring ApplicationContext in the filter, use the static method
org.springframework.web.context.ContextLoader.getCurrentWebApplicationContext()