Spring MVC: Introduction II - Value Transmission between Controller and View

Outline:

1) Annotation Based Url Mapping Config

2) Pass Value from View to Controller

3) Pass Value from Controller to View

 

HandlerMapping

1) SimpleUrlHandlerMapping (Not often used)

<beans ...>
 
   <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
      <property name="mappings">
		<value>
			/index.htm=welcomeController
			/welcome.htm=welcomeController
			/main.htm=welcomeController
			/home.htm=welcomeController
		</value>
      </property>
   </bean>	
 
   <bean id="welcomeController" 
      class="com.mkyong.common.controller.WelcomeController" />
 
</beans>

2) ControllerBeanNameHandlerMapping (Not often userd)

<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:mvc="http://www.springframework.org/schema/mvc"  
    xsi:schemaLocation="    
        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    
        http://www.springframework.org/schema/mvc    
        http://www.springframework.org/schema/context/spring-mvc.xsd">  
    <!-- Handler Mapping -->  
    <bean  
        class="org.springframework.web.servlet.mvc.support.ControllerBeanNameHandlerMapping" />  
  
    <bean name="/welcome.html" class="edu.xmu.webproject.controller.WelcomeController"></bean>  
 
</beans>

3) DefaultAnnotationHandlerMapping (Often used)

springmvc-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

	<context:component-scan base-package="edu.xmu.webproject.controller" />
	<mvc:annotation-driven />

	<!-- View Resolver for JSPs -->
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />
	</bean>

</beans> 

HelloController.java

package edu.xmu.webproject.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloController
{
	// RequestMapping represents which url mapped to this method
	@RequestMapping({ "/hello", "/" })
	public String hello()
	{
		return "hello";
	}
}

hello.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
	<h1>Hello</h1>
</body>
</html>

Final Test

Spring MVC: Introduction II - Value Transmission between Controller and View_第1张图片Spring MVC: Introduction II - Value Transmission between Controller and View_第2张图片

2. Value Transportation

1) Pass Value from View to Controller

HelloController.java

package edu.xmu.webproject.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class HelloController
{
	// RequestMapping represents which url mapped to this method
	@RequestMapping({ "/hello", "/" })
	public String hello(@RequestParam("username") String userName)
	{
		System.out.println("username=" + userName);
		return "hello";
	}
}

Request Url

http://localhost:8080/WebProject/hello?username=davy

Console Output

username=davy

Request Url

http://localhost:8080/WebProject/hello

Got HTTP Stauts 400 Error. Bad request.

Why? Cause spring-mvc supports RESTFUL style, as long as we pass the params, RESTFUL style regards that as a part of URL.

2) A more simple way to pass value from View to Controller

HelloController.java

package edu.xmu.webproject.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloController
{
	// RequestMapping represents which url mapped to this method
	@RequestMapping({ "/hello", "/" })
	public String hello(String username)
	{
		System.out.println("username=" + username);
		return "hello";
	}
}

We removed the annotation "@RequestParam". That requires "username" be exactly the same with the request url's param key.

http://localhost:8080/WebProject/hello?username=davy
# username=davy
http://localhost:8080/WebProject/hello
# username=null
http://localhost:8080/WebProject/hello?userName=davy
# username=null

3) Pass value from Controller to View

HelloController.java

package edu.xmu.webproject.controller;

import java.util.Map;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloController
{
	// RequestMapping represents which url mapped to this method
	@RequestMapping({ "/hello", "/" })
	public String hello(String username, Map<String, Object> context)
	{
		System.out.println("username=" + username);
		context.put("username", username);
		return "hello";
	}
}

hello.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
	<h1>Hello ${username}</h1>
</body>
</html>

Request Url

http://localhost:8080/WebProject/hello?username=davy

Output

Hello davy

4) A recommanded way to pass value from Controller to View

HelloController.java

package edu.xmu.webproject.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class HelloController
{
	// RequestMapping represents which url mapped to this method
	@RequestMapping({ "/hello", "/" })
	public String hello(String username, Model model)
	{
		System.out.println("username=" + username);
		model.addAttribute("username", username);
		// The key is the type of the value, first letter lowercase
		model.addAttribute(username);
		return "hello";
	}
}

hello.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
	<h1>Hello ${username} & ${string}</h1>
</body>
</html>

 

3. Model Driven Value Transportation

What if we need to pass 20 params to the controller?

How should we encapsulate these params into Object/Model?

Example below shows how to use model driven to pass model between view and controller.

1) User.java

package edu.xmu.webproject.bean;

public class User
{
	private String username;
	private String password;
	private String nickname;
	private String email;

	public User(String username, String password, String nickname, String email)
	{
		super();
		this.username = username;
		this.password = password;
		this.nickname = nickname;
		this.email = email;
	}

	public User()
	{
		super();
	}

	public String getNickname()
	{
		return nickname;
	}

	public void setNickname(String nickname)
	{
		this.nickname = nickname;
	}

	public String getEmail()
	{
		return email;
	}

	public void setEmail(String email)
	{
		this.email = email;
	}

	public String getUsername()
	{
		return username;
	}

	public void setUsername(String username)
	{
		this.username = username;
	}

	public String getPassword()
	{
		return password;
	}

	public void setPassword(String password)
	{
		this.password = password;
	}

}

2) UserController.java

package edu.xmu.webproject.controller;

import java.util.HashMap;
import java.util.Map;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import edu.xmu.webproject.bean.User;

@Controller
@RequestMapping("/user")
public class UserController
{
	private Map<String, User> userMap = new HashMap<String, User>();

	public UserController()
	{
		userMap.put("davy", new User("Davy", "Jones", "davy", "[email protected]"));
		userMap.put("calypso", new User("Calypso", "Jones", "carl",
				"[email protected]"));
		userMap.put("obama", new User("Obama", "Barack", "obama",
				"[email protected]"));
		userMap.put("tom", new User("Tom", "Cruize", "tom", "[email protected]"));
	}

	@RequestMapping(value = "/users", method = RequestMethod.GET)
	public String listAllUsers(Model model)
	{
		System.out.println("List all users");
		model.addAttribute("userMap", userMap);
		return "/user/list";
	}

	// This method nevigate us to the page for add user
	@RequestMapping(value = "/add", method = RequestMethod.GET)
	public String addUser(Model model)
	{
		System.out.println("Nevigate to add user page");
		// For the benefit of open model driven
		model.addAttribute("user", new User());
		return "/user/add";
	}

	// This method handle the request for add user
	@RequestMapping(value = "/add", method = RequestMethod.POST)
	public String addUser(User user)
	{
		System.out.println("Add user");

		String username = user.getUsername();
		userMap.put(username, user);
		return "redirect:/user/users";
	}
}

3) list.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
	<a href="add">Add User</a>
	<br />
	<c:forEach items="${userMap}" var="user">
		---------${user.value.username}
		---------${user.value.password}
		---------${user.value.nickname}
		---------${user.value.email}
		<br />
	</c:forEach>
</body>
</html>

4) add.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="sf"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
	<!-- Here we didn't assign an action for this form. -->
	<!-- By default, the form will be submitted to current path '/user/add' -->
	<!-- With the method POST -->
	<sf:form method="post" modelAttribute="user">
		username: <sf:input path="username" /> <sf:errors path="username"/>
		<br />
		password: <sf:input path="password" /><sf:errors path="password"/>
		<br />
		nickname: <sf:input path="nickname" />
		<br />
		email: <sf:input path="email" /><sf:errors path="email"/>
		<br />
		<input type="submit" value="Submit" />
	</sf:form>
</body>
</html>

5) springmvc-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

	<context:component-scan base-package="edu.xmu.webproject.controller" />
	<mvc:annotation-driven />

	<!-- View Resolver for JSPs -->
	<bean
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass"
			value="org.springframework.web.servlet.view.JstlView"></property>
		<property name="prefix" value="/WEB-INF/" />
		<property name="suffix" value=".jsp" />
	</bean>

</beans>  

6) web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
	id="WebApp_ID" version="3.0">
	<display-name>WebProject</display-name>
	
	<servlet>
		<servlet-name>springmvc</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>springmvc</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>
</web-app>

7) pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>edu.xmu.web.WebProject</groupId>
	<artifactId>WebProject-Core</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>

	<properties>
		<spring.version>3.0.5.RELEASE</spring.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.8.1</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>provided</scope>
		</dependency>
		<!-- Spring 3 dependencies -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<!-- JSTL -->
		<dependency>
			<groupId>jstl</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-war-plugin</artifactId>
				<version>2.1.1</version>
				<configuration>
					<webXml>WebContent\WEB-INF\web.xml</webXml>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

8) Final Test

Spring MVC: Introduction II - Value Transmission between Controller and View_第3张图片

Spring MVC: Introduction II - Value Transmission between Controller and View_第4张图片

Spring MVC: Introduction II - Value Transmission between Controller and View_第5张图片

Model Driven Summary:

1) Model from Controller to View to display user info:

1> Store beans to model

@RequestMapping(value = "/users", method = RequestMethod.GET)
public String listAllUsers(Model model)
{
	System.out.println("List all users");
	model.addAttribute("userMap", userMap);
	return "/user/list";
}

2> Use JSTL in JSP page in order to display model content

<!-- JSTL -->
<dependency>
	<groupId>jstl</groupId>
	<artifactId>jstl</artifactId>
	<version>1.2</version>
</dependency>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
...
<c:forEach items="${userMap}" var="user">
	---------${user.value.username}
	---------${user.value.password}
	---------${user.value.nickname}
	---------${user.value.email}
	<br />
</c:forEach>

2) Model from View to Controller to add user info:

1> Open model driven in controller, if we don't add User to model, then the view will not know the type of Model.

Exceptions below will occur:

十一月 09, 2013 8:29:48 下午 org.springframework.web.servlet.tags.RequestContextAwareTag doStartTag
严重: Neither BindingResult nor plain target object for bean name 'user' available as request attribute
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'user' available as request attribute
// First way to open model driven
// This method nevigate us to the page for add user
@RequestMapping(value = "/add", method = RequestMethod.GET)
public String addUser(Model model)
{
	System.out.println("Nevigate to add user page");
	// For the benefit of open model driven
	model.addAttribute("user", new User());
	return "/user/add";
}
// Second way to open model driven
// This method nevigate us to the page for add user
@RequestMapping(value = "/add", method = RequestMethod.GET)
public String addUser(@ModelAttribute("user") User user)
{
	System.out.println("Nevigate to add user page");
	return "/user/add";
}
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="sf"%>
...
<sf:form method="post" modelAttribute="user">
	username: <sf:input path="username" /> <sf:errors path="username"/>
	<br />
	password: <sf:input path="password" /><sf:errors path="password"/>
	<br />
	nickname: <sf:input path="nickname" />
	<br />
	email: <sf:input path="email" /><sf:errors path="email"/>
	<br />
	<input type="submit" value="Submit" />
</sf:form>
// This method handle the request for add user
@RequestMapping(value = "/add", method = RequestMethod.POST)
public String addUser(User user)
{
	System.out.println("Add user");

	String username = user.getUsername();
	userMap.put(username, user);
	return "redirect:/user/users";
}

 

Reference Links:

1) http://www.mkyong.com/spring-mvc/configure-the-handler-mapping-priority-in-spring-mvc/

2) http://docs.spring.io/spring/docs/3.0.x/reference/mvc.html

你可能感兴趣的:(spring,mvc,value,Transmission)