我有这个对象
public class Deportista implements Serializable {
private static final long serialVersionUID = 6229604242306465153L;
private String id;
...
@NotNull(message="{field.null}")
public String getId() {
return id;
}
...
}
我有以下控制器的方法
@InitBinder(value="deportistaRegistrar")
public void registrarInitBinder(WebDataBinder binder) {
logger.info(">>>>>>>> registrarInitBinder >>>>>>>>>>>>>");
}
@RequestMapping(value="/registrar.htm", method=RequestMethod.GET)
public String crearRegistrarFormulario(Model model){
logger.info("crearRegistrarFormulario GET");
Deportista deportista = new Deportista();
model.addAttribute("deportistaRegistrar", deportista);
return "deportista.formulario.registro";
}
@RequestMapping(value="/registrar.htm", method=RequestMethod.POST)
public String registrarPerson(@Validated @ModelAttribute("deportistaRegistrar") Deportista deportista,
BindingResult result){
logger.info("registrarPerson POST");
logger.info("{}", deportista.toString());
if(result.hasErrors()){
logger.error("There are errors!!!!");
for(ObjectError objectError : result.getAllErrors()){
logger.error("Error {}", objectError);
}
return "deportista.formulario.registro";
}
logger.info("All fine!!!!");
this.fakeMultipleRepository.insertDeportista(deportista);
return "redirect:/manolo.htm";
}
直到这里控制器能够创建一个表单(GET)并提交(POST)一个新的 命令对象,Validation
代码运行良好。
问题在于更新。
我有以下内容:
@InitBinder(value="deportistaActualizar")
public void actualizarInitBinder(WebDataBinder binder) {
logger.info(">>>>>>>> actualizarInitBinder >>>>>>>>>>>>>");
binder.setDisallowedFields("id");
}
观察我有binder.setDisallowedFields("id")
public String crearActualizarFormulario(@PathVariable("id") String id, Model model){
logger.info("crearActualizarFormulario GET");
Deportista deportista = this.fakeMultipleRepository.findDeportista(id);
model.addAttribute("deportistaActualizar", deportista);
return "deportista.formulario.actualizacion";
}
@RequestMapping(value="/{id}/actualizar.htm", method=RequestMethod.POST)
public String actualizarPerson(@Validated @ModelAttribute("deportistaActualizar") Deportista deportista,
BindingResult result){
logger.info("actualizarPerson POST");
logger.info("{}", deportista.toString());
if(result.hasErrors()){
logger.error("There are errors!!!!");
for(ObjectError objectError : result.getAllErrors()){
logger.error("Error {}", objectError);
}
return "deportista.formulario.actualizacion";
}
logger.info("All fine!!!!");
this.fakeMultipleRepository.updateDeportista(deportista);
return "redirect:/manolo.htm";
}
问题是:
- 当表单或命令有任何错误时,控制器会重新渲染视图,并且表单会显示错误消息,但没有 ID 值
或者
- 如果我尝试更新对象,当然保留 id 值,并且没有任何错误以简单地继续更新,它会失败
控制台中出现以下内容:
- -------- createCollections ---------------
- >>>>>>>> actualizarInitBinder >>>>>>>>>>>>>
- Skipping URI variable 'id' since the request contains a bind value with the same name.
- actualizarPerson POST
- Deportista [id=null, nombre=Manuel, ...]
- There are errors!!!!
- Error Field error in object 'deportistaActualizar' on field 'id': rejected value [null]; codes [NotNull.deportistaActualizar.id,NotNull.id,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [deportistaActualizar.id,id]; arguments []; default message [id]]; default message [The field must be not empty]
id为空。我如何解决这个问题,保持请求范围?
我有一个正在使用的备用控制器,@SessionAttributes
并且一切正常。但是,如果用户在同一个 Web 浏览器中打开了许多选项卡,一个用于创建,另一个用于更新,那么这是一个巨大的风险,所有这些都将是非常错误的。根据Spring MVC + Session 属性和多个选项卡,应使用请求范围而不是会话范围。它有道理。
可悲的是,Spring似乎不会解决这个问题: @SessionAttributes 不适用于选项卡式浏览
添加
根据你的建议,我有以下几点:
@ModelAttribute("deportistaActualizar")
public Deportista populateActualizarFormulario(@RequestParam(defaultValue="") String id){
logger.info("populateActualizarFormulario - id: {}", id);
if(id.equals(""))
return null;
else
return this.fakeMultipleRepository.findDeportista(id);
}
观察使用的方法@RequestParam
,我的问题是当要更新的 URL 具有以下样式时,如何更新该方法
http://localhost:8080/spring-utility/deportista/1/actualizar.htm
。URL中没有参数,因此@RequestParam
现在没用。
我已经阅读了 Spring 参考文档: 在方法上使用 @ModelAttribute
第二次加法
是的,你是对的,我昨天也这样做了,但我忘记分享以下内容:
@ModelAttribute("deportistaActualizar")
public Deportista populateActualizarFormulario(@PathVariable(value="id") String id){
logger.info("populateActualizarFormulario - id: {}", id);
if(id.equals(""))
return null;
else
return this.fakeMultipleRepository.findDeportista(id);
}
由于@ModelAttribute
之前总是通过任何handler
方法调用a,因此以下URL失败http://localhost:8080/spring-utility/deportista/registrar.htm
,页面上出现以下内容
HTTP Status 400 -
type Status report
message
description The request sent by the client was syntactically incorrect.
当然因为 URL 不包含预期的id
. 因此,我无法创建新记录以供以后编辑/查看。
我可以确认,对于以下工作:
http://localhost:8080/spring-utility/deportista/1/detalle.htm
http://localhost:8080/spring-utility/deportista/1/actualizar.htm
id (1) 被检索。
我该如何解决这个问题?
谢谢你