Can't load page in Spring MVC - java

I want to add a page in my spring MVC. I can call the index file but I can't click on the link in index.jsp to show page product.jsp. Its error message is "The requested resource is not available".
Below is my controller code:
#RequestMapping({"/", "/index"})
public String index(ModelMap model, HttpSession session, Principal principal) throws Exception {
return "index";
}
#RequestMapping({"/product"})
public String product(ModelMap model, HttpSession session, Principal principal) throws Exception {
return "product";
}
this index.jsp
<div class="row">
<div class="col-sm-4 menu-img-pad">
<ul class="multi-column-dropdown">
<li>Joggers</li>
<li>Foot Ball</li>
<li>Cricket</li>
</ul>
</div>
</div>

You need to define a ViewResolver in order to let spring how to find your views.
Have a look here. In your case an InternalResourceViewResolver would work.
An then -- in order to call your handler -- your link should look point to /product as you defined the path in your #RequestMapping method

Add below configuration to dispatcher-servlet.xml
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
In above configuration,views is folder name where container will look for your product.jsp file

Related

SPRING MVC form:checboxes binding error

I am working on Spring MVC project. I am getting an error while binding the checkbox value to the back end file. Can any one please suggest whats the mistake or missing step please?
I have searched for similar threads but the answers did'nt solve my issue. Appreciate any help here.
Code:
JSP:
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%#taglib uri = "http://www.springframework.org/tags/form" prefix = "form"%>
<%# page session="false" %>
<html>
<head>
<title>Home</title>
</head>
<body>
<form:form modelAttribute="listOfShapes" action="/calculateArea">
<form:checkboxes items="${listOfShapes}" path="selectedShapes" />
</form:form>
</body>
</html>
MOdelAttribute:
#ModelAttribute("listOfShapes")
public List<String> getListOfShapes() {
List<String> shapesOfList = new ArrayList<String>();
shapesOfList.add("Circle");
shapesOfList.add("Rectangle");
shapesOfList.add("Square");
return shapesOfList;
}
POJO:
package model.pojo.org;
import java.util.List;
public class ListOfShapes {
private List<String> selectedShapes;
/**
* #return the selectedShapes
*/
public List<String> getSelectedShapes() {
return selectedShapes;
}
/**
* #param selectedShapes the selectedShapes to set
*/
public void setSelectedShapes(List<String> selectedShapes) {
this.selectedShapes = selectedShapes;
}
}
XML:
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC #Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by #Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="calculate.area.org" />
</beans:beans>
I am getting the below Error. Can anyone please suggest?
org.springframework.beans.NotReadablePropertyException: Invalid property 'selectedShapes' of bean class [java.util.ArrayList]: Bean property 'selectedShapes' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
The Form Model should not be listOfShapes. The Form Model is what actually receives the input. So I believe this is wrong:
<form:form modelAttribute="listOfShapes" action="/calculateArea">
It's OK to use it as a Checkbox Display Constants getter in your <form:checkboxes items="${listOfShapes}" path="selectedShapes" /> but it's not OK to use it as an actual Form Model that gathers input. That would be your POJO instance, not a list of constants.
For example, see here:
http://www.baeldung.com/spring-mvc-form-tutorial
I assume you have a Controller that exposes the ModelAndView with the form model object, right? Something like
public String processForm(#ModelAttribute("employee")Employee employee,
BindingResult result, ModelMap model) {
}
in that case the Form Model would be
<form:form method="POST" action="/spring-mvc-xml/addEmployee" modelAttribute="employee">
as in that website example.

Ajax post to Spring MVC controller results in "Requested resource is unavailable" error

I have been trying to get this code to work. I've just started with Spring MVC (and I'm relatively new to web dev - my background is GUI dev/science) but I think the error may be triggered because there is a problem linking the jquery code in my jsp to the Spring controller. I've literally been trying to get this to work for days without success and I've tried all the suggestions made by posters on this forum with a similar problem - to no avail. I'd therefore very much appreciate your input. The project is being developed using Netbeans, Tomcat 8, Maven, Spring MVC, and Jquery.
projectDashboard.jsp (in WEB-INF/views):
<div class="col-lg-8 col-md-8 col-sm-8">
<div id="projectForm">
<div class="form-group">
<input id="name" name="name" type="text" class="form-control" placeholder="Project name (50 characters or less)"/>
<textarea id="description" name="description" class="form-control" placeholder="Project Description (200 characters or less)"></textarea>
</div>
<div class="form-group">
<input class="btn btn-primary pull-right" id="createProjectButton" value="Create" type="button"/>
</div>
</div>
</div>
JQuery:
<script>
$(document).ready(function(){
$("#createProjectButton").on("click", function(){
var projectJson = {
"name":$("#name").val(),
"description":$("#description").val()
};
$.ajax({
type: "POST",
url: "/ProgressManagerOnline/projectDashboard",
data: JSON.stringify(projectJson),
contentType: "application/json; charset=utf-8",
dataType: "json"
});
});
});
</script>
ProjectDashboard.java (Spring MVC controller class in src/main/java):
#RequestMapping(value = "/projectDashboard", method = RequestMethod.POST)
public String saveProject(#RequestBody Project project) throws Exception {
return "OK";
}
Relevant code in appconfig-mvc.xml:
<mvc:annotation-driven/>
<mvc:view-controller path="/" view-name="login"/> //home web page - login.jsp
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
Maven pom.xml includes:
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.5</version>
</dependency>
Tomcat context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/ProgressManagerOnline"/>
Error in Firefox web console:
The requested resource is not available. (404 error)
My Project.java:
#Entity
#Table(name = "projects")
public class Project implements Serializable {
private Long id;
private String name;
private String description;
private java.util.Date dateCreated;
public Project(){};
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id){
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
#Column(name = "dateCreated", columnDefinition="DATETIME")
#Temporal(TemporalType.TIMESTAMP)
public Date getDateCreated() {
return dateCreated;
}
public void setDateCreated(Date dateCreated) {
this.dateCreated = dateCreated;
}
}
I've been at this for days now and have tried every suggestion posted on this forum and others.
Many thanks in advance to anyone who can help out.
You are missing couple of configurations I guess in your application.
You require auto conversion of json to java object ,
#RequestBody Project project
Hence you need to add json converter so please look documentation : http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/converter/json/MappingJackson2HttpMessageConverter.html
Add following in your configuration context xml along with required dependencies added in your pom.xml,
<!-- Configure bean to convert JSON to POJO and vice versa -->
<beans:bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
<!-- Configure to plugin JSON as request and response in method handler -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonMessageConverter"/>
</list>
</property>
</bean>
(Posted on behalf of the OP).
The solution suggested by TechBreak worked - I was missing the Spring context dependency in my pom.xml and the extra config in my xml:
<!-- Configure bean to convert JSON to POJO and vice versa -->
<bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
<!-- Configure to plugin JSON as request and response in method handler -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonMessageConverter"/>
</list>
</property>
</bean>
After a restart of the server and
mvn clean install
Cheers.

Reset spring url. URL gets appended after submitting form twice

<form:form action="register/student.htm" method="post" modelAttribute="registerForm">
.....
</form:form>
When I initially submit this form the url is
"loclhost:8080/SpringSchool/register/student.htm"
If the submit fails and I submt it again, the new url gets appended and becomes:
"loclhost:8080/SpringSchool/register/register/student.htm"
As a result I get 404 error. How can I reset the url so that the url is not appended or just basically make this work?
#Controller
#RequestMapping("/register")
public class RegisterController {
#RequestMapping(method=RequestMethod.GET)
public ModelAndView registerPage(){
return new ModelAndView("registerStudent", "registerForm", new Student());
}
#RequestMapping(value="/student", method = RequestMethod.POST)
public ModelAndView registerStudent(#ModelAttribute("registerForm") final Student student, RedirectAttributes redirectAttr){
....
return new ModelAndView("registerStudent", "registerForm", student);
}
view resolver
<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>
If you start URL from '/' then it indicate the root of the context but if you start URL from word -- it means 'from the current path'. Your problem should be resolved if you add '/' to the URL:
<form:form action="/${pageContext.request.contextPath}/register/student.htm" method="post" modelAttribute="registerForm">
.....
</form:form>
This is because your form action is using a relative path. To fix your problem, you should organize your jsp in a folder and your controller should return views with the corresponding paths.
Move your jsp to:
/WEB-INF/jsp/register/registerStudent.jsp
Your controller should return the view name:
register/registerStudent
In your form, change action to:
<form:form action="student.htm" method="post" modelAttribute="registerForm">
.....
</form:form>

Spring Security with XML configuration does not authenticate user

I have a website section (everything under /secure URL) that I'm trying to secure with Spring Security 3.2.5. I'm using the following XML configuration:
<http use-expressions="true">
<intercept-url pattern="/secure/login" access="permitAll" />
<intercept-url pattern="/secure/**" access="isAuthenticated()" />
<form-login default-target-url="/secure/home" always-use-default-target="true" login-page="/secure/login" />
</http>
<authentication-manager>
<authentication-provider>
<user-service>
<user name="user" password="password" authorities="ROLE_SECURE" />
</user-service>
</authentication-provider>
</authentication-manager>
I'm trying to use a custom login form for which I have this controller:
#Controller
#RequestMapping(value = "/secure")
public class LoginController {
#RequestMapping(value = "/login", method = RequestMethod.GET)
public String getLogin() {
return "secure/login";
}
#RequestMapping(value = "/home", method = RequestMethod.GET)
public String getHome() {
return "secure/home";
}
}
and this code inside the login page:
<form method="POST" action="<c:url value="/secure/login" />">
username: <input type="text" name="username" /><br/>
password: <input type="password" name="password" /><br/>
<input type="submit" value="Login" />
</form>
I have the security context loaded in the web.xml using ContextLoaderListener and the
springSecurityFilterChain delegating proxy filter is also setup.
When I try to access the /secure URL I get redirected to /secure/login, my controller is called in the getLogin method and I see my login page. That's all OK.
Now my problem: whatever I submit in the login form gets sent directly to the LoginController and I get an exception saying that POST is not a supported
method, which makes sense because there is no POST handler in the controller.
If I add a method like this in the controller:
#RequestMapping(value = "/login", method = RequestMethod.POST)
public String postLogin() {
return "redirect:/secure/home";
}
I no longer get the error but my postLogin method is invoked wich sends me to /secure/home unauthenticated which then redirects me to /secure/login and I'm back to square one.
I don't know what I'm doing wrong. All examples I see online are Java configured which I prefer not to use and all workflows hapen in the context of the application not under some extra URL path (in my case /secure).
What am I missing?
Form the docs(http://docs.spring.io/spring-security/site/docs/3.0.x/reference/appendix-namespace.html):
default-target-url:
Maps to the defaultTargetUrl property of UsernamePasswordAuthenticationFilter. If not set, the default value is "/" (the application root). A user will be taken to this URL after logging in, provided they were not asked to login while attempting to access a secured resource, when they will be taken to the originally requested URL.
You have to submit the form to j_spring_security_check
<form name='loginForm'
action="<c:url value='j_spring_security_check' />" method='POST'>
This will be handled by Spring Security and will check the user and pass depending on your config.
See this example http://www.mkyong.com/spring-security/spring-security-form-login-example/
Edit: j_security_check should also be supported.
This post helped me get the correct result: http://codehustler.org/blog/spring-security-tutorial-form-login/

Handle 404 errors in Spring?

Here is the code I have for redirecting unmapped requests to 404 page
#RequestMapping("/**")
public ModelAndView redirect() {
ModelAndView mv = new ModelAndView();
mv.setViewName("errorPage");
return mv;
}
The above code works fine but the problem is with the web resources like css and js files
also go inside this redirect method and it is not loading any of the files. But i already have this code in my dispatcher servlet,but spring controller is not recognizing this resources mapping.
<mvc:resources mapping="/resources/**" location="/WEB-INF/web-resources/" />
so i tried some regex expression in the request mapping to negate the resources url something like this
#RequestMapping("/{^(?!.*resources/**)}**")
public ModelAndView redirect() {
ModelAndView mv = new ModelAndView();
mv.setViewName("errorPage");
return mv;
}
But this is not working as expected ..So if anyone could help it would be great :)
I found the solution to handle 404 (Unmapped links), I used a SimpleUrlHandlerMapping to do this.
I added the below code to my dispatcher servlet .xml
<!-- Here all your resources like css,js will be mapped first -->
<mvc:resources mapping="/resources/**" location="/WEB-INF/web-resources/" />
<context:annotation-config />
<!-- Next is your request mappings from controllers -->
<context:component-scan base-package="com.xyz" />
<mvc:annotation-driven />
<!-- Atlast your error mapping -->
<bean id="errorUrlBean" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/**">errorController</prop>
</props>
</property>
</bean>
<bean id="errorController" class="com.xyz.controller.ErrorController">
</bean>
com.xyz.controller.ErrorController class
public class ErrorController extends AbstractController {
#Override
protected ModelAndView handleRequestInternal(HttpServletRequest arg0,
HttpServletResponse arg1) throws Exception {
// TODO Auto-generated method stub
ModelAndView mv = new ModelAndView();
mv.setViewName("errorPage");
return mv;
}
}
I found the below reasons
#RequestMapping("/**") uses RequestHandlerMapping and
<mvc:resources mapping="/resources/**" location="/WEB-INF/web-resources/" />
uses SimpleUrlHandlerMapping
RequestHandlerMapping takes presedence over SimpleUrlHandlerMapping, so that was the reason all resources request went inside the redirect method in my case.
So i just changed the #RequestMapping("/**") request to SimpleUrlHandlerMapping by configuring that as a bean as given above in my dipatcher servlet and mapped it at the last and it solved the problem.
Also add the below code to your web.xml
<error-page>
<error-code>404</error-code>
<location>/WEB-INF/jsp/error.jsp</location>
</error-page>
Now this simple solution can be used to redirect all unmapped requests i.e) 404 errors to an error page :)

Categories