2012-11-14 122 views
1

我基本上有以下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通過autopopulating列出的處理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方法中獲得一個空的advertisementObj。

控制器對象非常簡單,但萬一這裏是它的代碼的一部分:

@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 "); 


} 

} 

注意的代碼ABOV即,它是重要的是有要求PARAM來第一次在簽名林叫「form_submit.html?位置=」你把你的模型只對有默認情況下,當前請求+位置」

+0

如果你發佈你的控制器,它會讓事情變得更容易。 – Yevgeniy

+0

@YevgeniyM。只是粘貼了一部分,儘管那裏沒有什麼特別的東西。真正的控制器有更多的RequestMappings指向不同的URL。表單對象只有一個廣告對象,其中包含幾個字段 – Thomas

+0

thx,現在我們可以更全面地瞭解您正在做什麼,並且可以提供更好的答案。 – Yevgeniy

回答

2

對象。這意味着您的myAdverts列表在第二個請求(即POST請求)中不再存在。但是,您可以使用@SessionAttribute註釋來告訴spring mvc將對象存儲在http會話中,以便您可以在其他請求中訪問它們。

控制器看起來是這樣的:

@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

+0

會話屬性存儲多久?是否有可能在請求映射方法上註釋它,並且只與這些方法有關? – Thomas

+0

@Thomas你希望myAdverts在會話中保持多久。要從sesion中刪除它,您可以在post方法中注入一個SessionStatus實例,並調用setComplete()從會話中刪除myAdverts。我將編輯我的答案並將其放入代碼中。 – Yevgeniy

+0

@Thomas myAdverts只能在MyController中注入......用你的話來說它只與那裏有關。但是,當然這些對象位於會話中並且可以在任何地方訪問,其中存在對會話的引用。 – Yevgeniy

0

如果廣告有某種獨特的ID,並存儲在一個DAO(或有另一種方式來獲得ID的廣告),你可以實現一個轉換器,將字符串參數,並將其轉換回廣告

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文檔的鏈接。