提交 c283ba11 编写于 作者: C Calvin

#59 再次泪流满面,终于有一个彻底满意的写法.

上级 dc0578ab
......@@ -5,13 +5,15 @@ import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springside.examples.quickstart.entity.Task;
import org.springside.examples.quickstart.service.TaskManager;
import org.springside.modules.web.springmvc.OptionalPathVariable;
/**
* Task管理的Controller, 使用Restful风格的Urls:
......@@ -53,7 +55,8 @@ public class TaskController {
}
@RequestMapping(value = "update/{id}")
public String updateForm(Model model) {
public String updateForm(@PathVariable("id") Long id, Model model) {
model.addAttribute("task", taskManager.getTask(id));
return "taskForm";
}
......@@ -72,14 +75,22 @@ public class TaskController {
}
/**
* 使用@ModelAttribute, 实现Struts2 Preparable二次绑定的效果,先根据url中的id从数据库查出Task对象,再把Form提交的内容绑定到该对象上。
* 本方法仅用于updateForm()/update(),其他方法的url不存在id,因此使用了@OptionalPathVariable。
* 使用@ModelAttribute, 实现Struts2 Preparable二次绑定的效果,先根据form的id从数据库查出Task对象,再把Form提交的内容绑定到该对象上。
* 因为仅update()方法的form中有id属性,因此本方法在该方法中执行.
*/
@ModelAttribute("task")
public Task getTask(@OptionalPathVariable("id") Long id) {
private Task getTask(@RequestParam(value = "id", required = false) Long id) {
if (id != null) {
return taskManager.getTask(Long.valueOf(id));
return taskManager.getTask(id);
}
return null;
}
/**
* 不要绑定对象中的id属性.
*/
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setDisallowedFields("id");
}
}
......@@ -12,12 +12,7 @@
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 在spring mvc 标准annotation基础上,增加了@OptionalPathVariable -->
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class=" org.springside.modules.web.springmvc.OptionalPathVariableMethodArgumentResolver"/>
</mvc:argument-resolvers>
</mvc:annotation-driven>
<mvc:annotation-driven/>
<mvc:default-servlet-handler/>
......
......@@ -8,12 +8,14 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springside.examples.showcase.common.entity.User;
import org.springside.examples.showcase.common.service.AccountManager;
import org.springside.modules.web.springmvc.OptionalPathVariable;
import com.google.common.collect.Lists;
......@@ -50,12 +52,23 @@ public class UserController {
return "redirect:/common/user/";
}
/**
* 使用@ModelAttribute, 实现Struts2 Preparable二次绑定的效果,先根据form的id从数据库查出User对象,再把Form提交的内容绑定到该对象上。
* 因为仅update()方法的form中有id属性,因此本方法在该方法中执行.
*/
@ModelAttribute("user")
public User getAccount(@OptionalPathVariable("id") Long id) {
private User getUser(@RequestParam(value = "id", required = false) Long id) {
if (id != null) {
return accountManager.getUser(id);
}
return null;
}
/**
* 不要绑定对象中的id属性.
*/
@InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setDisallowedFields("id");
}
}
......@@ -12,12 +12,7 @@
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 在spring mvc 标准annotation基础上,增加了@OptionalPathVariable -->
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class=" org.springside.modules.web.springmvc.OptionalPathVariableMethodArgumentResolver"/>
</mvc:argument-resolvers>
</mvc:annotation-driven>
<mvc:annotation-driven/>
<mvc:default-servlet-handler/>
......
package org.springside.modules.web.springmvc;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 用于标注不一定存在的PathVarible. 主要用于无@RequestMapping定义, 只有方法级@ModelAttribute标注的函数的参数。
*
* @author calvin
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OptionalPathVariable {
/** The URI template variable to bind to. */
String value() default "";
}
package org.springside.modules.web.springmvc;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.annotation.ValueConstants;
import org.springframework.web.servlet.mvc.method.annotation.PathVariableMethodArgumentResolver;
/**
* 用于标注不一定存在的PathVarible. 主要用于无@RequestMapping定义, 只有方法级@ModelAttribute标注的函数的参数。
*
* @author calvin
*/
public class OptionalPathVariableMethodArgumentResolver extends PathVariableMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(OptionalPathVariable.class);
}
@Override
protected NamedValueInfo createNamedValueInfo(MethodParameter parameter) {
OptionalPathVariable annotation = parameter.getParameterAnnotation(OptionalPathVariable.class);
return new PathVariableNamedValueInfo(annotation);
}
private static class PathVariableNamedValueInfo extends NamedValueInfo {
private PathVariableNamedValueInfo(OptionalPathVariable annotation) {
//设定required为false
super(annotation.value(), false, ValueConstants.DEFAULT_NONE);
}
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册