• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 885
  • Last Modified:

Question on spring 3.0

I am working on spring rest WS. I have a controller with 2 methods. one which displays the JSP page with a textfield and the other which process the value of the textfield. When user types this URL :-

http://localhost:8080/11/foo/

It executes displayForm mehod which has a textfield and submit. Now once user types something in the textfield and click submit my second method in the controller getUserInfo() should get invoked and the data should be displayed on the same page. However, the request never reaches the second method of the controller because it expects the URI to look like this :-

http://localhost:8080/11/foo/foo1

My question is that what can i do in the userview JSP page from which when user enters something in the textfield should create the above URI so it actually calls my second method in the controller.

@Controller
public class UserController {
	
    @Autowired
    private UserService userService;
    
    @RequestMapping(value="{age}/{firstName}", method=RequestMethod.GET )
    public String displayForm(@PathVariable("age")Integer age,@PathVariable("firstName") String firstName,Model model) {
    	model.addAttribute("user", new User());
        return "userview";
    }
    
    @RequestMapping(params="submit", value="{age}/{firstName}/{lastName}", method=RequestMethod.GET )
    public String getUserInfo(@PathVariable("age")Integer age,@PathVariable("firstName") String firstName,@PathVariable("lastName") String lastName, Model model) {
    	User userInfo = userService.getUser(age, firstName, lastName);
    	model.addAttribute("user", userInfo);
    	return "userview";
    }
}


Sample JSP

<form:form modelAttribute="user" method="get">
  <table>
    <tr>
      <th>
        LastName: 
        <br/>
        <form:input path="lastName" size="30" maxlength="30"/> <p class="submit"><input type="submit" name="submit" value="Submit"/></p>
      </th>
    </tr>
    </table>
    </form:form>
   <c:if test="${user.age != null}">
  ${user.age }
  ${user.firstName }
  ${user.lastName }
    </c:if>

Open in new window

0
Micheal_Male
Asked:
Micheal_Male
  • 9
  • 4
1 Solution
 
gordon_vt02Commented:
Not sure exactly what you're trying to do with your URL scheme, but for true RESTful operation, you'll want to change the method on the form submission to POST instead of GET, and correspondingly change the submit method of the form to POST.  That should solve your problem.

In general -- using age/firstName/lastName as your URL scheme might be problematic since you could have multiple John Smiths that are all 27 years old, but that is a separate design question.
0
 
Micheal_MaleAuthor Commented:
Thank you. I tried your solution by changing the get to post on controller and jsp but now when I click submit it states request method post not supported. The request never came to the post method. What M I doing wrong ?
0
 
Micheal_MaleAuthor Commented:
Here is my updated code. When i click on submit i get

message Request method 'POST' not supported

description The specified HTTP method is not allowed for the requested resource (Request method 'POST' not supported).

@Controller
public class UserController {
	
    @Autowired
    private UserService userService;
    
    @RequestMapping(value="{age}/{firstName}", method=RequestMethod.GET )
    public String displayForm(@PathVariable("age")Integer age,@PathVariable("firstName") String firstName,Model model) {
     User user = new User();
	user.setAge(age);
	user.setFirstName(firstName);
    	model.addAttribute("user", user);
        return "userview";
    }
    
    @RequestMapping(params="submit", value="{age}/{firstName}/{lastName}", method=RequestMethod.POST )
    public String getUserInfo(@PathVariable("age")Integer age,@PathVariable("firstName") String firstName,@PathVariable("lastName") String lastName, Model model) {
    	User userInfo = userService.getUser(age, firstName, lastName);
    	model.addAttribute("user", userInfo);
    	return "userview";
    }
}


Sample JSP

<form:form modelAttribute="user" method="post" action='/user/${user.age}/${user.fistName}/${user.lastName}'>
  <table>
    <tr>
      <th>
        LastName: 
        <br/>
        <form:input path="lastName" size="30" maxlength="30"/> <p class="submit"><input type="submit" name="submit" value="Submit"/></p>
      </th>
    </tr>
    </table>
    </form:form>
   <c:if test="${user.age != null}">
  ${user.age }
  ${user.firstName }
  ${user.lastName }
    </c:if>

Open in new window

0
Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

 
Micheal_MaleAuthor Commented:
And here is the URL where the form is access

http://localhost:8080/user/11/foo

And the URL should look like this once the user enters lastname and click submit


http://localhost:8080/user/11/foo/foo1

At  this point i get the the POST error. Any clue ?
0
 
reijnemansCommented:
Could you post the stacktrace you see when executing your code
0
 
Micheal_MaleAuthor Commented:
Well this is the only thing i get
HTTP Status 405 - Request method 'POST' not supported

type Status report

message Request method 'POST' not supported

description The specified HTTP method is not allowed for the requested resource (Request method 'POST' not supported).

And this is in the log 

011-09-15 08:04:47 PageNotFound [WARN] Request method 'POST' not supported

Open in new window

0
 
Micheal_MaleAuthor Commented:
Here is my web.xml and dispatcher servlet
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	version="2.4"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
	<display-name>user</display-name>
	<description>user</description>

	<context-param>
		<param-name>log4jConfigLocation</param-name>
		<param-value>classpath:log4j.properties</param-value>
	</context-param>

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
            classpath:user-servlet.xml
            
        </param-value>
	</context-param>

	<!-- Comment out if using JBoss -->
	<listener>
		<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
	</listener>

	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<servlet>
		<servlet-name>user</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value />
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>user</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

	<servlet>
		<servlet-name>Resources Servlet</servlet-name>
		<servlet-class>org.springframework.js.resource.ResourceServlet</servlet-class>
	</servlet>

	<servlet-mapping>
		<servlet-name>Resources Servlet</servlet-name>
		<url-pattern>/resources/*</url-pattern>
	</servlet-mapping>

	<filter>
   <filter-name>httpMethodFilter</filter-name>
   <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter
      </filter-class>
</filter>

<filter-mapping>
   <filter-name>httpMethodFilter</filter-name>
   <servlet-name>troublecode</servlet-name>
</filter-mapping>
	
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>

</web-app>


dispatcher-servlet.xml


<context:component-scan base-package="com.user" />

	<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
	</bean>

	<bean id="contentNegotiatingViewResolver"
		class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver" p:order="1">
		<property name="mediaTypes">
			<map>
				<entry key="xml" value="application/xml" />
			</map>
		</property>
		<property name="defaultViews">
			<list>
				<bean class="org.springframework.web.servlet.view.xml.MarshallingView">
					<constructor-arg>
						<bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
							<property name="classesToBeBound">
								<list>
									<value>com.user.User</value>
									
								</list>
							</property>
						</bean>
					</constructor-arg>
				</bean>
			</list>
		</property>
		 <property name="ignoreAcceptHeader" value="true" />
	</bean>
	
	<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" p:order="2"/>
</beans>

Open in new window

0
 
gordon_vt02Commented:
I'm wondering if you're running into problems because your POST URL contains your GET URL:

GET: /{age}/{firstName}
POST: /{age}/{firstName}/{lastName}

Try changing your POST to:

/info/{age}/{firstName}/{lastName}

and see if it works as expected.
0
 
Micheal_MaleAuthor Commented:
Now if i change my method to GET and like the above code then all is well. I can see the data but the URLi get is this :-

http://localhost:8080/user/11/foo?submit=Submit&lastName=foo1

As you can see this is not REST. I want the URI when the form is submitted to be like this :-


http://localhost:8080/user/11/foo/foo1


@RequestMapping(params="submit", value="{age}/{firstName}", method=RequestMethod.GET )
    public String getUserInfo(@PathVariable("age")Integer age,@PathVariable("firstName") String firstName, String lastName, Model model) {
    	User userInfo = userService.getUser(age, firstName, lastName);
    	model.addAttribute("user", userInfo);
    	return "userview";
    }

Open in new window

0
 
Micheal_MaleAuthor Commented:
And what is the value i am suppose to put in action attribue in the JSP ?
0
 
gordon_vt02Commented:
If lastName is a form parameter, it is perfectly acceptable in REST for it to be a URL parameter.  The concept behind REST is that every item has its own unique URL, so for your users, ideally you would have some unique identifier and your URL scheme would be:

/user/uid/{userId}

A GET to that URL would return all information about that user or, for specific fields, something like:

/user/uid/{userId}?properties=age

would return the value of the age property.  You could also provide multiple values for properties to return more than one.

A POST to /user/uid/{userId} would provide parameters (as POST params, not URL params) that would set the properties of the user.
0
 
Micheal_MaleAuthor Commented:
So what you saying is that the URL it generates is absolutely correct ?. I mean the URL I posted with the query parameters is acceptable in REST ? So there is no other way to have the absolute URI which I want ? The problem is I have to show it on the same Jsp page. If it was some other JSP page I could have easily send the client to that path
0
 
gordon_vt02Commented:
There's no reason your view can't return the user to the same page regardless of how the URL is handled on the back end.  The difficulty you run into with your URL scheme is what happens when two users have identical property values.  There are no restrictions that the combination of age, first name and last name are unique -- and if you artifically create them, you will likely run into problems down the road when two people share those properties.  That's why you typically would have some system ID to uniquely identify each user.
0
 
Micheal_MaleAuthor Commented:
Thanks
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 9
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now