gpt4 book ai didi

java - 我应该将我的实体 ID 放在 URL 中还是作为隐藏字段放入表单中?

转载 作者:IT老高 更新时间:2023-10-28 13:51:02 33 4
gpt4 key购买 nike

我认为就 REST 而言,ID 应该放在 URL 中,例如:

https://example.com/module/[ID]

然后我在该 URL 上调用 GET、PUT、DELETE。我认为这很清楚。在 Spring MVC Controller 中,我将使用 @PathVariable 获取 ID。有效。

现在,我对 Spring MVC 的实际问题是,如果我这样做,我必须不将 ID 作为表单的一部分包含(以及),Spring 会发出类型的警告

Skipping URI variable 'id' since the request contains a bind value with the same name.

否则。而且只发送一次也很有意义,对吧?如果他们不匹配你会怎么做?

这很好,但我确实有一个用于我的表单支持 bean 的自定义 validator ,它需要知道 ID! (它需要检查某个唯一名称是否已被用于不同的实体实例,但不能在不知道提交表单的 ID 的情况下)。

我还没有找到一个好方法来告诉 validator 来自@PathVariable 的 ID,因为验证甚至在我的 Controller 方法中的代码执行之前就已经发生了。

你会如何解决这个难题?

这是我的 Controller (修改):

@Controller
@RequestMapping("/channels")
@RoleRestricted(resource = RoleResource.CHANNEL_ADMIN)
public class ChannelAdminController
{
protected ChannelService channelService;
protected ChannelEditFormValidator formValidator;

@Autowired
public ChannelAdminController(ChannelService channelService, ChannelEditFormValidator formValidator)
{
this.channelService = channelService;
this.formValidator = formValidator;
}

@RequestMapping(value = "/{channelId}/admin", method = RequestMethod.GET)
public String editChannel(@PathVariable Long channelId, @ModelAttribute("channelForm") ChannelEditForm channelEditForm, Model model)
{
if (channelId > 0)
{
// Populate from persistent entity
}
else
{
// Prepare form with default values
}
return "channel/admin/channel-edit";
}

@RequestMapping(value = "/{channelId}/admin", method = RequestMethod.PUT)
public String saveChannel(@PathVariable Long channelId, @ModelAttribute("channelForm") @Valid ChannelEditForm channelEditForm, BindingResult result, Model model, RedirectAttributes redirectAttributes)
{
try
{
// Has to validate in controller if the name is already used by another channel, since in the validator, we don't know the channelId
Long nameChannelId = channelService.getChannelIdByName(channelEditForm.getName());
if (nameChannelId != null && !nameChannelId.equals(channelId))
result.rejectValue("name", "channel:admin.f1.error.name");
}
catch (EmptyResultDataAccessException e)
{
// That's fine, new valid unique name (not so fine using an exception for this, but you know...)
}

if (result.hasErrors())
{
return "channel/admin/channel-edit";
}

// Copy properties from form to ChannelEditRequest DTO
// ...

// Save
// ...

redirectAttributes.addFlashAttribute("successMessage", new SuccessMessage.Builder("channel:admin.f1.success", "Success!").build());
// POST-REDIRECT-GET
return "redirect:/channels/" + channelId + "/admin";
}


@InitBinder("channelForm")
protected void initBinder(WebDataBinder binder)
{
binder.setValidator(formValidator);
}
}

最佳答案

我想我终于找到了解决办法。

事实证明,Spring 也将路径变量绑定(bind)到形成 bean!我没有在任何地方找到这个文档,也没有预料到它,但是当尝试重命名路径变量时,就像@DavidW 建议的那样(我原以为它只会在我的 Controller 方法中产生局部效果),我意识到因为前面提到的,有些东西坏了。

因此,基本上,解决方案是在表单支持对象上也具有 ID 属性,但不包括 HTML 表单中的隐藏输入字段。这样,Spring 将使用路径变量并将其填充到表单上。甚至可以跳过 Controller 方法中的本地 @PathVariable 参数。

关于java - 我应该将我的实体 ID 放在 URL 中还是作为隐藏字段放入表单中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50511854/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com