Here is my view resolver:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".html"/>
</bean>
I also have a controller that should return hello.html:
#Controller
#RequestMapping("/")
public class IndexController {
#RequestMapping(method = RequestMethod.GET)
public String getHtmlPage() {
return "hello";
}
}
When I access localhost:8080 I get an error message:
WARNING: No mapping found for HTTP request with URI [/WEB-INF/pages/hello.html] in DispatcherServlet with name 'mvc-dispatcher'
Now when I change my suffix value to .jsp, then hello.jsp is returned correctly.
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
hello.jsp and hello.html are in the same folder. Any ideas how to fix this?
EDIT:
For html you don't need view resolvers. Instead just create a folder in your webapp folder.
Call it static for example , then add <mvc:resources mapping="/static/**" location="/static/" /> to your xml.
In controller instead of return "hello"; put return "static/hello.html";
As a complement to answers of How to map requests to HTML file in Spring MVC?, I would say that the InternalResourceViewResolver knows how to render JSP or JSP+JSTL views. You could of course use HTML views - even if it makes little sense(*) - by writing a custom ViewResolver that would be able to render plain HTML pages.
(*) Normally, the controller prepares a model that will be used by the view. In a plain HTML view, you cannot use the model. Normally when you try to do that, you actually needs to redirect to a plain HTML page, not use it like a view.
To redirect to the HTML page, you put it out of the WEB-INF folder, in a place accessible as a resource.
But in your particular need, you are trying to display hello.html for the root URL. The best way to do it is to put it directly at the root of the web application folder atn declare it in the welcome-file-list of the web.xml :
<welcome-file-list>
<welcome-file>hello.html</welcome-file>
</welcome-file-list>
Related
I am a spring newbie and have a question about view resolution. I am changing a webapp that I downloaded online and it uses the simple view resolver strategy:
<bean id="jspViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
and I keep getting 404 errors for view resolution and I am suspecting that it uses some sort of rewriting / filtering mechanism. Is there a log that I can view in tomcat / Spring class that I can override in order to understand what file is Spring trying to look for when resolving an incoming request?
I understand the operation of InternalResourceViewResolver which strips file name extensions. But what if the request does not have an extension? For instance:
#RequestMapping("/foo")
protected ModelMap render() { return new ModelMap(); }
Then what is the view name that will be resolved to in this case?
See this link for log4j integration
Spring-mvc doesn't use any file for request handling, it uses controllers and requestmapping to map the request to a controller and respective method if any.
The InternalResourceViewResolver that you have written Resolves “view name” that is returned from the controller class to a JSP page residing in /WEB-INF/view/ directory.
an example
#Controller
public class SimpleController{
#RequestMapping("/home")
public String homeMapper(Model model) {
return "home";
}
}
here homeMapper method will be called if you try to access "home" and as it returns home the relative jsp to be rendered is "home.jsp" should be present in /WEB-INF/view/
For more information see spring mvc reference or any tutorial.
I have login.jsp , forgotpass.jsp files in webapps directory, I have 2 more jsp file under WEB-INF/jsp folder.
Now when the user clicks ForgotPassword link on login.jsp page he is redirected to forgotpassword.jsp when the user enters some data, which is read by one of Spring Controller, the spring controller sets an attribute and returns same jsp page.
My remote-servlet.xml file is having the following configuration.
...
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
ForgotPasswordController.java
#RequestMapping(value = "/pass", method =RequestMethod.POST)
public String recoverPassword(#RequestParam String email, ModelMap model){
List<String> emails = usersDao.getEmails();
...
if (!emails.contains(email)) {
model.addAttribute("failMessage", "Password Recovery Failed ! Invalid loginId or EmailId");
}else{
String validEmail = email;
model.addAttribute("successMessage", "A New Password is Sent to your emailId "+ "xxx"+email.substring(email.indexOf('#')-3,email.length()));
}
return "forgotpassword";
}
}
The Problem is
After prefixing and suffixing the configuration properties the return Path will be /myapp-Path/WEB-INF/jsp/forgotpassword.jsp.
But my forgotpassword.jsp is under /webapps/ directory, but Spring is checking it under WEB-INF/jsp/ folder.
Can we add another property with prefix "/" and suffix ".jsp" ? If this is not possible, please suggest me any solution.
If you are so intent of not having the forgotPass.jsp in the same folder, you could always return a ModelAndView, setting the View to a JstlView, or rolling your own for that matter. I have to agree with #funnyfox, however, that it seems silly that you have some requirement that prevents these JSP files from living in the same directory tree.
How to map a jsp for a url in spring 3 without requestmapping to any controller.
eg. /login to login.jsp without having any userdefined controller in between
Like URLFILENAMECONTROLLER in spring2.5, similarly in spring 3
You can use this paragraph from Spring docs for reference. In short, you can do in several ways one of them with view-controller annotation. The other way when using Java Config:
#EnableWebMvc
#Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
}
}
Where the code maps request for /login to /WEB-INF/views/login.jsp view if the view resolver is defined as in the previous answer.
You can do this:
<mvc:view-controller path="/login" view-name="login"/>
Assuming that you have defined a ViewResolver, something like this:
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
This will resolve a request to /login to a /WEB-INF/views/login.jsp page
I am attempting to use Spring 3' MVC support for annotated controllers in my web application.
In my application-context.xml, I've added the following:
<mvc:annotation-driven />
<context:component-scan base-package="com.abc.def.etc"/>
<bean id="jspViewResolver" 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"/>
<property name="order" value="1" />
</bean>
My Controller is annotated as follows:
#Controller
#RequestMapping("/optimizerRules")
public class OptimizerRulesController {
private OptimizerRulesService optimizerRulesService;
private static final Log LOG = LogFactory.getLog(OptimizerRulesController.class);
public OptimizerRulesController()
{
LOG.info("Initializing OptimizerRulesController");
}
#RequestMapping(method = RequestMethod.GET)
public ModelAndView getRuleAttributesAndRules(ModelMap model)
{
LOG.info("Entering getRuleAttributesAndRules method");
}
When I start up my application I can see in my logs that the OptimizerRulesController has been initialized. I can also see the following:
Creating instance of bean 'optimizerRulesController'
Initializing OptimizerRulesController
Mapped URL path [/optimizerRules] onto handler 'optimizerRulesController'
However, when I invoke my application using http://localhost:8080/appName/optimizerRules I get a 404 error!
What configuration am I missing here?
Thanks
Spring MVC would normally log that no mapping is found for a particular request at WARN level. Assuming you're not seeing that in your logs and assuming that WARN is enabled, and since you're not seeing your own log statement, it sounds like your request isn't even hitting the Spring MVC DispatcherServlet, which probably means the URL is wrong.
The URL should be http://server:port/war/dispatcherServletMapping/optimizerRules, so your web.xml should tell you the missing path component, if my assumptions are valid.
I have a scenario where I'm making a simple get request through a link and my #RequestMapping configuration is not behaving as I'd expect.
Within an anchor tag I reference a url with the following pattern '/action-plan/export/pdf?token=xxx&taskId=1111&taskId=2222...'
Within my controller class I have this mapping at the class level:
#RequestMapping("/action-plan/export")
And this mapping at the method level
#RequestMapping(value="/pdf", method=RequestMethod.GET)
public String exportToPdf(#RequestParam("taskId") String[] taskIds,
#RequestParam("token") String[] encryptedEmplId, ModelMap model)
But every time I try this I get a 404 page not found error and the following Spring exception:
org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException: No matching handler method found for servlet request: path '/pdf', method 'GET', parameters map['taskId' -> array['1962326', '1962264', '1962317', '1962328', '1962324', '1962427', '1962325', '1962323', '1963147', '1962327', '1962318', '1962329', '1962330'], 'token' -> array['xxxx']]
I've noticed that when I remove the "/pdf?" portion of the link and remove 'value="/pdf"' from the method #RequestMapping it works fine. For the life of me I don't understand why adding /pdf to the url and RequestMapping is not working.
I think danny.lesnik's answer was pretty close but I'm writing my own answer so I can be more verbose.
I was working on a different project and figured out why the above doesn't work. In reference to my original question here is the relevant web.xml servlet mapping:
<servlet-mapping>
<servlet-name>spring-dispatcherServlet</servlet-name>
<url-pattern>/action-plan/export/*</url-pattern>
</servlet-mapping>
I noticed that whatever portion of the path I included in the of web.xml was not being included in the evaluation of RequestMapping values. I would have thought this bean configuration would have prevented that scenario (note the "alwaysUseFullPath" property):
<bean id="annotationHandlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="order" value="2"/>
<property name="alwaysUseFullPath" value="true"/>
</bean>
Maybe someone can shed some light on this detail for me.
In any case, thanks danny.lesnik
I recreated your problem and solved it by mapping servlet using .action extentions.
For example:
#Controller
#RequestMapping(value="/test")
public class DefaultController {
#RequestMapping(value="/pdf.action", method=RequestMethod.GET)
public ModelAndView indexView(#RequestParam("taskId") String[] taskIds,
#RequestParam("token") String[] encryptedEmplId){
ModelAndView mv = new ModelAndView("index");
return mv;
}
Spring XML mapping:
<context:annotation-config />
<context:component-scan base-package="com.vanilla.controllers" />
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
and this web.xml servlet mapping
<display-name>SpringMvcServlet</display-name>
<servlet>
<servlet-name>SpringMvcServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMvcServlet</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
This code resolves this url
/test/pdf.action?token=3&token=4&taskId=4
flawless.