How .do extension is appended in the URL in struts? - struts1

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

Related

How to bypass certain url patterns not invoking dispatcher servelet in spring MVC

I declared below url pattern within servelet definition for handler mapping.
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Now i have some specific url with above '/' pattern (ex: /demo/), but i dont want to allow this request to get handled by dispatcher servlet (since i dont have any handler mapping in controller for this request).
Is there any similar prototype like mvc:resources ?
It would be very thankful if someone tells how to find out whether the declared resources are invoked properly or not?
I declared like this:
<mvc:resources mapping="/resources/**" location="/resources/MainTemplate/"/>
In jsp:
<link rel="stylesheet" href="/resources/css/components.css">
<script type="text/javascript" src="/resources/js/jquery-1.8.3.min.js"></script>
You can write an interceptor for the pattern you want and handle it there. Configure your interceptor as shown below for specific patterns. You can also exclude the url patterns you want from entering into the interceptor.
<mvc:interceptor>
<mapping path="/url_pattern/**"/>
<exclude-mapping path="/exclude/**"/>
..
</mvc:interceptor>

Spring mvc, why my controller not mapped

I defined my Dispatcher servlet's url mapping in web.xml like this:
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
<url-pattern>/data/*</url-pattern>
</servlet-mapping>
my controller's method is annotated with:
#RequestMapping(value="/data/sys/CodeCatalogs")
when I request the url in browser I got 404 error, if I change the mapping to this:
#RequestMapping(value="/sys/CodeCatalogs")
the full url:
http://localhost:8080/cwe/data/sys/CodeCatalogs
it works, why? I am new to spring mvc, please help.
I tested url that contain no wildcard:
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
<url-pattern>/data/*</url-pattern>
url-pattern>/test/foo</url-pattern>
</servlet-mapping>
then this request mapping will works:
#RequestMapping(value="/test/foo")
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
<url-pattern>/data/*</url-pattern>
</servlet-mapping>
In the preceding example, all requests starting with /data and anything which ends with *.do will be handled by the DispatcherServlet instance named dispatcher.
So for controller's method is annotated with:
#RequestMapping(value="/data/sys/CodeCatalogs")
http://localhost:8080/cwe/data/sys/CodeCatalogs - Does not match
http://localhost:8080/cwe/data/data/sys/CodeCatalogs - Does matches
URL passes from browser will be first matched against URL pattern specified and
then the URL specified in #RequestMapping.
For controller's method is annotated with :
#RequestMapping(value="/test/foo")
http://localhost:8080/cwe/test/foo - Matches since URL matches the exact pattern which is allowed as per Servlet Specification.
http://localhost:8080/cwe/data/test/foo - This will also match because of pattern /data/*
For an incoming request of the form /data/sys/CodeCatalogs, your servlet container will consume the /data/ portion before passing the pattern to your Spring servlet. So the controller will receive /sys/CodeCatalogs and hence this is why your second #RequestMapping works and the first does not.

Map ServletRequestListener to Special Servlet

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.

HTTP 405 error when connecting to spring-security auto-generated log-in page

I cannot connect to the auto generated spring security log-in page. According to the documentation, including the following lines in your security-context.xml will have Spring generate an html log-in form and redirect the user to it when trying to connect to the specific URL:
<http auto-config="true" >
<intercept-url pattern="/management-console" access="ROLE_ADMIN"/>
</http>
<authentication-manager ... />
Here is the rest of my configuration. Web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath:/context/applicationContext.xml <!-- I am importing my security-context.xml in here -->
<param-value>
</context-param>
<!-- Security Configuration -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/management-console</url-pattern>
</filter-mapping>
I have tried importing the security-context.xml directly in the web.xml, but I still see the error.
After deploying my application, I can connect to each my specified urls without issue. However, when I try to go to localhost:{port}/{appName}/management-console, the filter chain redirects me to /spring_security_login (as expected). However, I see an "HTTP Status 405 - Request method 'GET' not supported" error once I am forwarded and the following comes up on the console (spring-mvc is the name I gave to my servlet):
org.springframework.web.servlet.PageNotFound | No mapping found for HTTP request with URI [/InternalManagementViewer/spring_security_login] in DispatcherServlet with name 'spring-mvc' |
I have seen this error before when I miss declaring a POST/GET mapping in the controller. According to the documentation, I should not have to include such a method in my controller to handle the /spring_security_login mapping. From what I have read, spring is supposed to know to return the auto-generated log-in html page.
Just to see what happens, I declared a method in my controller to handle the /spring_security_login mapping. Since the function returns void (because I do not know the local view name of the generated html log-in page), it looks for the resource named "spring_security_login.jsp", which is not explicitly created in my project, and thus I get an "HTTP resource not found" error.
I'm stumped on this one and could really use a hand. Thanks a lot for taking a look.
Apply springSecurityFilterChain filter to all URLs:
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
springSecurityFilterChain is an entry point for all Spring Security features. So if this filter is not applied to some URL then you will not be able use Spring Security there (in this case handle /spring_security_login URL).

Struts2 action from Servlet

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

Resources