我基本上有以下jsp来检索弹簧模型广告列表$ {myAdverts}附带的广告对象。
我希望当点击其中一个时,将一个帖子请求提交回我的控制器,但是有一个广告对象的实例。这有可能吗?
这是我的JSP代码:
<xc:forEach var="advertisement" items="${myAdverts}" varStatus="stats">
<li>
<a class="furtherinfo-link" onclick="javascript:submitJoin(${stats.count})" >${advertisement.getName()}</a>
</li>
</xc:forEach>
<form:form id="myform" method="POST" action="form_submit.html" commandName="myForm" name="MyForm">
<form:input id="advertisementObj" path="advertisementObj" type="hidden"/>
</form:form>
这是我尝试使用javascript来回复发送帖子,其灵感来自Spring MVC和javascript中自动填充列表的处理:
javascript代码
<script src="js/webmenu_nav.js"></script>
<script type="text/javascript">
function submitJoin(position){
$('#advertisementObj').val("myAdverts["+position+"]");
document.MyForm.submit();
}
</script>
该代码的当前行为是我总是在我的Controller对象的post方法中得到一个空的advertObj。
控制器对象非常简单,但在这里它是代码的一部分:
@Controller
public class MyController {
@RequestMapping(value="/show_advertisements.html",method = RequestMethod.GET)
public ModelAndView showAdv(@RequestParam(value="response", required=false) String incomingResponse) {
Map<String, Object> model = new HashMap<String, Object>();
model.put("response", incomingResponse);
List<AdvertisementRecord> adverts = methodThatReturnsList();
model.put("myAdverts", adverts);
MyForm jform = new MyForm();
model.put("myForm", jform);
return new ModelAndView("show_advertisements", model) ;
}
@RequestMapping(value = "/form_submit.html", method = RequestMethod.POST)
public ModelAndView formSubmit(MyForm myForm, BindingResult result, Map model){
if(null != myForm.getAdvertisement())
return showPage("adver " + myForm.getAdvertisement().getId());
else
return showPage("null advertisement on join");
}
}
解决方案!!
解决方案代码的片段
JSP代码:
<xc:forEach var="advertisement" items="${myAdverts}" varStatus="stats">
<li>
<a class="furtherinfo-link" onclick="javascript:submitForm(${stats.count})" >${advertisement.getName()}</a>
</li>
</xc:forEach>
<form:form method="POST" id="theForm" action="form_submit.html" modelAttribute="myAdverts" name="MyForm">
</form:form>
的javascript:
<script src="js/webmenu_nav.js"></script>
<script type="text/javascript">
function submitForm(position){
$('#theForm').attr("action","form_submit.html?position="+position);
document.MyForm.submit();
}
</script>
</head>
控制器:
@Controller
@SessionAttributes("myAdverts")
public class MyController {
@RequestMapping(value="/show_advertisements.html",method = RequestMethod.GET)
public ModelAndView showAdv(@RequestParam(value="response", required=false) String incomingResponse) {
Map<String, Object> model = new HashMap<String, Object>();
model.put("response", incomingResponse);
List<AdvertisementRecord> adverts = methodThatReturnsList();
model.put("myAdverts", adverts);
//MyForm jform = new MyForm();
//model.put("myForm", jform);
return new ModelAndView("show_advertisements", model) ;
}
@RequestMapping(value = "/form_submit.html", method = RequestMethod.POST)
public ModelAndView formSubmit(@RequestParam("position") final int position, @ModelAttribute("adverts") @Valid List<AdvertisementRecord> adverts, BindingResult result, Map model){
if(null != adverts && null != adverts.get(position))
return showPage("adver " + adverts.get(position).getId());
else
return showPage("null advertisement ");
}
}
请注意上面的代码,重要的是让请求参数首先出现在签名中,因为我正在调用“form_submit.html?position =”+ position“
答案 0 :(得分:2)
您放入模型的对象默认只存在当前请求。这意味着您的myAdverts
列表在第二个请求(即POST请求)中不再存在。但是,您可以使用@SessionAttribute
注释告诉spring mvc在http-session中存储对象,以便您可以在进一步的请求中访问它们。
您的控制器可能如下所示:
@Controller
@SessionAttributes("myAdverts")
public class MyController {
@RequestMapping(value="...", method=RequestMethod.GET)
public void get(ModelMap model){
List myAdverts = // get your list of adverts.
model.put("myAdverts", myAdverts)
}
@RequestMapping(value="...", method=RequestMethod.POST)
public void post(@RequestParam("position") final int position, @ModelAttribute("myAdverts") List myAdverts,SessionStatus sessionStatus){
myAdverts.get(position);
// ...
// tell spring to remove myAdverts from session
sessionStatus.setComplete();
}
}
有关@SessionAttribute
的更多信息,请查看here。
答案 1 :(得分:0)
如果广告具有某种唯一ID并存储在DAO中(或者有另一种从id获取广告的方式),您可以实现一个转换器,该转换器将接受String参数并将其转换回广告
public class StringToAdvertisementConverter implements Converter<String, Advertisement> {
private AdvertisementRepository advertisementRepository
@Autowired
public setAdvertisementRepository(AdvertisementRepository repository){
this.advertisementRepositort = repository;
}
@Override
public Advertisement convert(String id) {
return advertisementRepository.lookup(id);
}
}
在转换服务中注册转换器
<mvc:annotation-driven conversion-service="conversionService"/>
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="my.StringToAdvertisementConverter"/>
</set>
</property>
您的控制器将能够接受广告类作为@RequestParam
的参数和类似的注释:
@RequestMapping(method = RequestMethod.POST, value = "/SomeMapping")
public String handleSomething(@RequestParam(required = false) Advertisement advert,
ModelMap model) {}
作为替代方案,您可以使用PropertyEditors获得相同的结果,a good question on topic包含许多指向Spring文档的链接。