本文代码转载自 《Servlet、JSP和Spring MVC初学指南》
Spring 自定义重定向仅需要在 Controller 用相应的request处理方法中将
return 中对要从定向的链接加redirect前缀
在重定向的同时 一般需要 进行重定向传值 如像从定向之后的
controller的某处理函数添加 attribute 用于后续页面渲染等操作
这可以借用
RedirectAttributes.addFlashAttribute
完成
下面是一个重定向 并进行传值的简单实例
用于数据绑定的Bean
package domain; import java.io.Serializable; public class Product implements Serializable { private static final long serialVersionUID = 5784L; private long id; private String name; private String description; private float price; 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; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } }
package form; public class ProductForm { private String name; private String description; private String price; 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; } public String getPrice() { return price; } public void setPrice(String price) { this.price = price; } }
逻辑处理 简单接口
package service; /** * Created by admin on 2017/3/1. */ import domain.Product; public interface ProductService { Product add(Product product); Product get(long id); }
package service; /** * Created by admin on 2017/3/1. */ import java.util.HashMap; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; import org.springframework.stereotype.Service; import domain.Product; @Service public class ProductServiceImpl implements ProductService { private Map<Long, Product> products = new HashMap<>(); private AtomicLong generator = new AtomicLong(); public ProductServiceImpl(){ Product product = new Product(); product.setName("JX1 Power Drill"); product.setDescription("Powerful hand drill, made to perfection"); product.setPrice(129.99F); add(product); } @Override public Product add(Product product){ long newId = generator.incrementAndGet(); product.setId(newId); products.put(newId, product); return product; } @Override public Product get(long id){ return products.get(id); } }
ProductForm.jsp
<%-- Created by IntelliJ IDEA. User: admin Date: 2017/3/1 Time: 9:23 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Add Product Form</title> <style type="text/css">@import url("/css/main.css");</style> </head> <body> <div id = "global"> <form action = "/product_save" method="post"> <fieldset> <legend>Add a product</legend> <p> <label for = "name">Product Name </label> <input type = "text" id = "name" name = "name" tabindex="1"> </p> <p> <label for = "description">Description:</label> <input type="text" id = "description" name = "description" tabindex="2"> </p> <p> <label for = "price">Price:</label> <input type = "text" id = "price" name = "price" tabindex="3"> </p> <p id = "buttons"> <input type="reset" id = "reset" tabindex="4"> <input type = "submit" tabindex="5" value="Add Product"> </p> </fieldset> </form> </div> </body> </html>
ProductView.jsp
<%-- Created by IntelliJ IDEA. User: admin Date: 2017/3/1 Time: 9:30 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>View Product</title> <style type="text/css">@import url(/css/main.css);</style> </head> <body> <div id = "global"> <h4>${message}</h4> <p> <h5>Details:</h5> Product Name: ${product.name}<br/> Description: ${product.description}<br/> Price: ${product.price} </p> </div> </body> </html>
Controller类package controller; /** * Created by admin on 2017/3/1. */ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.servlet.mvc.support.RedirectAttributes; import domain.Product; import form.ProductForm; import service.ProductService; @Controller public class ProductController { private static final Log logger = LogFactory.getLog(ProductController.class); @Autowired private ProductService productService; @RequestMapping(value = "/product_input") public String inputProduct(){ logger.info("inputProduct called"); return "ProductForm"; } @RequestMapping(value = "/product_save", method = RequestMethod.POST) public String saveProduct(ProductForm productForm, RedirectAttributes redirectAttributes){ logger.info("saveProduct called"); Product product = new Product(); product.setName(productForm.getName()); product.setDescription(productForm.getDescription()); try{ product.setPrice(Float.parseFloat(productForm.getPrice())); }catch(NumberFormatException e){ } Product savedProduct = productService.add(product); redirectAttributes.addFlashAttribute("message","The product was successfully added."); return "redirect:/product_view/" + savedProduct.getId(); } @RequestMapping(value = "/product_view/{id}") public String viewProduct(@PathVariable Long id, Model model){ Product product = productService.get(id); model.addAttribute("product", product); return "ProductView"; } }
配置文件
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/config/dispatcher-config.xml</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
<?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:mvc="http://www.springframework.org/schema/mvc" 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="controller"/> <context:component-scan base-package="service"/> <mvc:resources mapping="/css/**" location="css/"/> <mvc:resources mapping="/*.html" location="/"/> <mvc:annotation-driven/> <bean id = "viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name = "prefix" value="/WEB-INF/jsp/"/> <property name = "suffix" value=".jsp"/> </bean> </beans>
进行页面表单提交后 会发现 message 作为(重定向)attribute 被渲染出来
在一般进行Model处理的过程中 有时需要进行预处理
这可以借用ModelAttribute
被其声明的方法 会在controller进行具体页面处理的逻辑调用之前进行调用
将某个类设定为attribute
下面是一个简单例子
表单jsp
<%-- Created by IntelliJ IDEA. User: admin Date: 2017/3/1 Time: 9:23 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Add Product Form</title> <style type="text/css">@import url("/css/main.css");</style> </head> <body> <div id = "global"> <form action = "/employee_save" method="post"> <input type="hidden" name="number" value="1"> <fieldset> <legend>Add a product</legend> <p> <label for = "name">Product Name </label> <input type = "text" id = "name" name = "name" tabindex="1"> </p> <p> <label for = "description">Description:</label> <input type="text" id = "description" name = "description" tabindex="2"> </p> <p> <label for = "price">Price:</label> <input type = "text" id = "price" name = "price" tabindex="3"> </p> <p id = "buttons"> <input type="reset" id = "reset" tabindex="4"> <input type = "submit" tabindex="5" value="Add Product"> </p> </fieldset> </form> </div> </body> </html>
展示jsp
<%-- Created by IntelliJ IDEA. User: admin Date: 2017/3/1 Time: 9:20 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Save Product</title> <style type="text/css">@import url(/css/main.css);</style> </head> <body> <div id = "global"> <h4>The product has been saved.</h4> <p> <h5>Details:</h5> Product Name: ${product.name}<br/> Description: ${product.description}<br/> Price: ${product.price} </p> </div> </body> </html>
Controller类
package controller; /** * Created by admin on 2017/3/1. */ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.validation.FieldError; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.stereotype.Controller; import domain.Product; @Controller public class EmployeeController { private static final Log logger = LogFactory.getLog(EmployeeController.class); @RequestMapping(value = "/employee_input") public String inputEmployee(){ logger.info("inputEmployee called"); return "ProductForm"; } @RequestMapping(value = "/employee_save") public String saveEmployee(Product product, BindingResult bindingResult, Model model){ logger.info("saveEmployee called"); logger.info("as map :" + model.asMap()); logger.info("The number id :" + product.getId()); if(bindingResult.hasErrors()){ logger.info("has errors"); FieldError fieldError = bindingResult.getFieldError(); logger.info("Code:" + fieldError.getCode() + ", field:" + fieldError.getField() ); return "ProductForm"; } model.addAttribute("product", product); return "ProductDetails"; } @ModelAttribute public Product addAccount(@RequestParam String number){ logger.info("addAccount called number is " + number); Product product = new Product(); product.setName("ana"); product.setId(1000000); return product; } @ModelAttribute public void populateModel(@RequestParam String number, Model model){ logger.info("populateModel called. number is " + number); model.addAttribute("blah"); } }
Spring 为表单对象实现了自动绑定 该绑定 仅仅是对于Field的 对相应的类名
等并没有具体要求 甚至允许绑定的类 的 Field比表单的Field多
(这里以Id为例)
在addAccount方法中 可以对传输到具体处理逻辑的对象product进行预处理
其结果是 设定未设定的对象 如Id 但是对于表单传输的对象 不进行修改
如当输入name不是ana时 仍然显示出输入name
当然 ModelAttribute还可以用于修饰 controller的方法 其基本作用是当整个模型
不存在此名称的attribute时调用相应的类构造函数初始化相应的javaBean类
当存在此名称的attribute时与一般的类参数相同 用于表单对象绑定。
相应较为细致的论述见
http://www.cnblogs.com/shucunbin/p/4438711.html