I have faced the problem when decided to create a web-app without JSPs, but using only HTML-pages which are under directory WEB-INF/pages.
I've made the view resolver:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="WEB-INF/pages/"/>
<property name="suffix" value=""/>
</bean>
Also I've imported all the resources in WEB-INF/pages:
<mvc:resources mapping="/**" location="WEB-INF/pages/"/>
My controller have the following view:
#PreAuthorize("isAuthenticated()")
#RequestMapping("/")
public String indexPage() {
return "redirect:/index.html";
}
It works fine for mapping "/" (redirects to login page if not authenticated), but it is not secured for url "/index.html" due to importing of this page as static resource (but it will not work at all if not import it).
Finally, I found the solution. Maybe, it will be interesting to anybody. The main servlet mapping that I had, had url-pattern: /**
And that was my problem. As I understood the main servlet in someway intercepted viewResolver even if it had such configuration: <bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".html"/>
</bean>
When I make the configuration of servlet make as the next one:
<servlet-mapping>
<servlet-name>main</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
everything became ok.
i dont know why you want to do that ..... as putting pages under web-inf is a wrong practice.......
also the container cant access the static contents that are under web-inf folder. I have faced exactly same problem see resource problem post.
what i have found from googling is you can access dynamic resources under web-inf folder but not the static. I have tried even regestring all the static contents (ie. css, js,html, etc) in xml at the first place but nothing worked. finally i moved my pages out and it worked with no configuration ....
so try moving the resources out of web-inf and under webcontent
tell me if you got some extras on this.
thanks.
Related
I am using spring-mvc framework in my current project. ROOT folder has lots of web folders containing html, jsp, css, js etc. My spring mvc configuration is as follows:
<context:annotation-config />
<bean id="comicControllerBean" class="tv.cinemacraft.videogramwebapp.springmvc.controllers.ComicController" />
<bean id="dashboardControllerBean" class="tv.cinemacraft.videogramwebapp.springmvc.controllers.DashBoardController" />
<bean id="genericControllerBean" class="tv.cinemacraft.videogramwebapp.springmvc.controllers.GenericController" />
<bean id="channelControllerBean" class="tv.cinemacraft.videogramwebapp.springmvc.controllers.ChannelController" />
<!-- <context:component-scan base-package="tv.cinemacraft.videogramwebapp.springmvc.controllers" /> -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/" />
<property name="suffix" value=".jsp" />
<property name="order" value="1" />
</bean>
<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename" value="views" />
<property name="order" value="0" />
</bean>
And I have mapping defined in my java controller. But this is causing static content like any image to vanish. If I request for any image inside any folder by accessing ROOT//.jpg, it gives me 404 response code although image exists.
If I remove spring-mvc, image gets displayed.
Note that spring-mvc's resources attribute works for static content but that need my static content to be present inside particular folder e.g. resouce folder. So this approach is not useful for me.
Let’s say you have a directory (/resources/my_images/) that contains some product images, and you want to serve these images upon request. For example, if the requested URL is http://localhost:8080/ mystore/resource/my_images/P123.png, then you would like to serve the image with the P123.png name. Similarly, if the requested URL is http://localhost:8080/mystore/resource/images/P1234.png, then an image with the name P1234.png needs to be served.
Now how you can serve static images with Spring MVC?
Place some images under the src/main/webapp/resources/my_images/ directory;
Add the following tag in our web application context’s configuration
DispatcherServlet-context.xml file: <mvc:resources location="/resources/" mapping="/resource/**"/>
run your application and enter
http://localhost:8080/mystore/resource/images/P123.png (change the
image name in the URL based on the images you placed
FYI: <mvc:resources> tag in the web application context configuration to tell Spring where these image files are located in our project so that spring can serve those files upon request.
If I try:
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
I get this error:
No mapping found for HTTP request with URI [/sample/WEB-INF/jsp/person.jsp]
If I try just / as <url-pattern> then everything works fine.
My url : http://localhost:8080/sample/person
Why is this happening? What is the preferred way of doing this configuration in web.xml?
My app-servlet.xml has :
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
You mapped /* (every request to your app) to your servlet called 'app'. The InternalResourceViewResolver than looks (internally) for '/person' inside '/WEB-INF/jsp/person.jsp'. This way you can access your views, while the scripts are secured inside WEB-INF, which is not accessible from the url (public).
/* means every public request to your web-app. It means for your jsp it should be public accessed, since it is in WEB-INF and not public it will give error.
If you use only / it means server took the request and the web-app processes it internal without any public access.
I'm using Spring 3.0.5 with <context:component-scan> and #RequestMapping annotations on my controllers. This works, and URLs are registered by the package scan.
But there is a problem when I have a handler mapping defined in the XML config. The #RequestMapping annotations are no longer picked up.
I've isolated the problem to a simple application.
If I have the following controller:
package test.pack.age;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
#Controller
public class TestController {
#RequestMapping(value="/test")
public String showTestPage() {
return "testPage";
}
}
and the following configuration:
<context:component-scan base-package="test.pack.age" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
The application works correctly and the URL /test is registered and works properly.
18/09/2011 20:02:55 org.springframework.web.servlet.handler.AbstractUrlHandlerMapping INFO Mapped URL path [/test] onto handler 'testController'
18/09/2011 20:02:55 org.springframework.web.servlet.handler.AbstractUrlHandlerMapping INFO Mapped URL path [/test] onto handler 'testController'
But if I add a handler mapping to the XML it no longer works. Even something simple like this:
<bean id="handlerMappings" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" />
which basically does nothing, and the <context:component-scan> no longer registers my URL.
I need an extra handler mapping for some (third party) controllers which I can't annotate, but when adding it it breaks all my #RequestMappings.
Is this normal? A bug? (I can't change the Spring version)
Am I missing something?
Is this normal? A bug? (I can't change the Spring version)
Am I missing something?
I was missing something :D. Found this buried in the Spring's JavaDocs for DefaultAnnotationHandlerMapping:
NOTE: If you define custom HandlerMapping beans in your DispatcherServlet context, you need to add a DefaultAnnotationHandlerMapping bean explicitly, since custom HandlerMapping beans replace the default mapping strategies.
Added this to my config XML and now everything works:
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
I am not sure why your annotated Controller is not being picked up anymore, but I think your issue lies in the id you provide your SimpleUrlHandlerMapping. It should be handlerMapping.
I'm using Spring 3 and i don't know how to map somepage.htm to somepage.jsp without a controller.
That is: if i go to somepage.htm, i want it to show me the jsp. But of course without redirect. I dontw want anyone to see ".jsp" only ".htm"
<servlet>
<servlet-name>Training01</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Training01</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/jsp/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
The way to do is to use the <mvc:view-controller..> tag in combination with a view resolver.
See here for more documentation:
The <mvc:view-controller..> tag maps urls to views. So if you want to map the relative url /login to a view names login you would do it by adding the following line to you webmvc-context.xml file:
<mvc:view-controller path="/login" view-name="login" />
Of course to get this to work you'll have to have a view resolve - something that maps logic names to specific views - setup in your context. In your case since you are using straight jsps for you view layer you'll want to add something like this to your configuration:
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
So with this setup if you had a jsp login.jsp located in you /WEB-INF/jsp directory then you would be able to directly reference that jsp from the url www.myapp.com/mycontenxtroot/login
See here for some more info on view resolvers:
You might be interested in UrlRewriteFilter. This is the approach I would recommend. If you're serious about clean URLs you'll likely need it at some point anyway.
On the other hand, if it's a one-off, a minimal controller might be easier:
#Controller
public class Somepage {
#RequestMapping("/somepage")
public String handler() {
return "somepage.jsp";
}
}
On my web.xml I have a "springmvc" servlet declaration (which has a corresponding springmvc-servlet.xml)
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/myapp/*</url-pattern>
</servlet-mapping>
I also have my usual applicationContext.xml file.
Which one gets loaded first? The springmvc-servlet.xml or the applicationContext.xml?
The reason I'm asking this is whenever I place the <mvc:annotation-driven/> element in the applicationContext.xml, I get a Severe Context error. But when I put that element in the springmvc-servlet.xml, my web app runs fine.
Any ideas why?
On another web-app, I have the <mvc:annotation-driven/> inside the applicationContext.xml and it runs fine.
Addendum:
I do notice that the presence of aop:config poses conflict against mvc:annotation-driven
the applicationContext.xml context is parent to the dispatcher-servlet.xml context. I don't know whether this means it is loaded first, but it does not matter in your case:
<mvc:annotation-driven /> must be in the dispatcher-servlet.xml, because it belongs to the web-part of the application.
I solved my problem!
It turns out it has nothing to do with the load order or where the <mvc:annotation-driven/> is declared.
I tried deploying my web-app on another Tomcat and to my surprise there's a stack trace in the localhost log. I had a hint by trial and error that the conflict is with <aop:config/>. But what particular conflict?
Then I saw this error in the log file:
java.lang.ClassCastException: org.aspectj.weaver.ResolvedType$Array cannot be cast to org.aspectj.weaver.ReferenceType
So we have a cast exception. I googled that exact error above and found this: Spring 3: adding causes ClassCastException
It appears the thread starter and I have the same exact issue. So I downloaded the aspectj-1.6.10.jar but I was still missing a class. Then it turns out it should be the aspectjweaver-1.6.9
I was still using a very old aspectjweaver. It didn't have any version on its name. Problem solved. Case closed.
By the way as a bonus, I've manually unrolled the <mvc:annotation-driven/> element to its equivalent xml declaration:
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="order" value="0" />
</bean>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="webBindingInitializer">
<bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer">
<property name="validator" ref="validator" />
</bean>
</property>
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />
<bean class="org.springframework.http.converter.StringHttpMessageConverter" />
<bean class="org.springframework.http.converter.FormHttpMessageConverter" />
<bean class="org.springframework.http.converter.xml.SourceHttpMessageConverter" />
<bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter" />
</list>
</property>
</bean>
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
<bean id="conversion-service" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" />
They're exactly the same when you declare the <mvc:annotation-driven/> based on what I've researched.
Thanks to everybody who helped me out.
Except for web.xml there is no predefined order.
This happens:
web.xml is loaded by the servlet engine, this triggers the load of all defined servlets, filters, listeners,
the ContextLoaderListener loads the
root application context XML, this
might include a bean definition for a
LocalSessionFactoryBean, triggering
the load of all Hibernate mapping XML
files
the DispatcherServlet loads the web
application context XML
Study the web.xml to determine the order in each case.
see also:
link
You probably have to add the mvc namespace to the application context:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"
>
(other namespaces stripped)