Solved

Question on spring 3.0

Posted on 2011-09-13
14
839 Views
Last Modified: 2012-05-12
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
Comment
Question by:Micheal_Male
  • 9
  • 4
14 Comments
 
LVL 10

Expert Comment

by:gordon_vt02
ID: 36538690
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
 

Author Comment

by:Micheal_Male
ID: 36539844
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
 

Author Comment

by:Micheal_Male
ID: 36540394
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
 

Author Comment

by:Micheal_Male
ID: 36540398
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
 
LVL 4

Expert Comment

by:reijnemans
ID: 36541994
Could you post the stacktrace you see when executing your code
0
 

Author Comment

by:Micheal_Male
ID: 36542685
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
 

Author Comment

by:Micheal_Male
ID: 36542706
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
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 
LVL 10

Expert Comment

by:gordon_vt02
ID: 36542794
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
 

Author Comment

by:Micheal_Male
ID: 36542801
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
 

Author Comment

by:Micheal_Male
ID: 36542810
And what is the value i am suppose to put in action attribue in the JSP ?
0
 
LVL 10

Accepted Solution

by:
gordon_vt02 earned 250 total points
ID: 36542880
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
 

Author Comment

by:Micheal_Male
ID: 36542930
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
 
LVL 10

Expert Comment

by:gordon_vt02
ID: 36543737
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
 

Author Closing Comment

by:Micheal_Male
ID: 36543801
Thanks
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Suggested Solutions

Java had always been an easily readable and understandable language.  Some relatively recent changes in the language seem to be changing this pretty fast, and anyone that had not seen any Java code for the last 5 years will possibly have issues unde…
Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
Viewers will learn about basic arrays, how to declare them, and how to use them. Introduction and definition: Declare an array and cover the syntax of declaring them: Initialize every index in the created array: Example/Features of a basic arr…
This tutorial covers a practical example of lazy loading technique and early loading technique in a Singleton Design Pattern.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now