2012-03-14 90 views
5

我試圖在單個請求中返回多個視圖中的多視圖,返回他們都在一個JSON字符串。渲染單個請求

例子:

@RequestMapping(value = "my-request") 
public void myRequest(HttpServletRequest request, HttpServletResponse response) throws Exception 
{ 
    Map<String,Object> model1 = new Hashtable<String,Object>(); 
    model1.put(...); 
    ModelAndView modelAndView1 = new ModelAndView("path/to/view1", model1); 
    // Render modelAndView1 in some way, in order to obtain the rendered HTML as a String 

    Map<String,Object> model2 = new Hashtable<String,Object>(); 
    model2.put(...); 
    ModelAndView modelAndView2 = new ModelAndView("path/to/view2", model2); 
    // Render modelAndView2 in some way, in order to obtain the rendered HTML as a String 

    // Now write a JSON String to the HttpServletResponse containing both the rendered views (strings). 
    // (this is not part of my problem, I'm able to do it as long as I have the two strings) 
} 

我使用Spring MVC的使用Tiles 2.

誰能幫助我?

更新1 - 視圖名稱使用的是ViewResolver解決:

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
    <property name="prefix" value="/WEB-INF/tiles/" /> 
    <property name="suffix" value=".jsp" /> 
</bean> 

更新2 - 我已經創建了一個包含github repository一個非常小的例子重現問題。

+0

所以其實你不希望出現任何意見,但傳遞一個字符串給你的客戶? – Stefan 2012-03-14 15:56:42

+0

我談論的字符串呈現的HTML作爲字符串(相應地改變原來的問題) – satoshi 2012-03-14 16:11:08

+0

如果您使用的瓷磚相結合,瓷磚的意見到一個單一的複合視圖,並重定向到它的名稱。 – Stefan 2012-03-14 16:18:24

回答

6

UPDATE:有一些方法解決您的問題。我會嘗試這個,但也許有更清潔的方法。

@Component 
public class JsonMultipleViewFactory { 

    @Autowired private List<ViewResolver> viewResolverList; 

    public View getView(List<ModelAndView> mavList) { 
     for (ModelAndView mav : mavList) { 
      if (mav.getView()==null) { 
       mav.setView(resolve(mav.getViewName())); 
      } 
     } 
     return new JsonMultipleView(mavList); 
    } 

    private View resolve(String viewName) { 
     for (ViewResolver vr : viewResolverList) { 
      View view = vr.resolve(viewName, LocaleContextHolder.getLocale()); 
      if (view!=null) { 
       return view; 
      } 
     } 
     return null; 
    } 
} 

public class JsonMultipleView implements View { 

    private final List<ModelAndView> mavList; 

    public JsonMultipleView(List<ModelAndView> mavList) { 
     this.mavList = mavList; 
    } 

    public String getContentType() { 
     return "application/json"; 
    } 

    public void render(Map<String,?> model, HttpServletRequest request, HttpServletResponse response) { 
     Json json = new Json(); // You can use several Json libraries here 
     for (ModelAndView mav : mavList) { 
      MockHttpServletResponse mockResponse = new MockHttpServletResponse(); 
      mav.getView().render(mav.getModel(), request, mockResponse); 
      json.add(mav.getViewName(), mockResponse.getContentAsString()); 
     } 
     json.write(response.getOutputStream()); 
     response.getOutputStream().close(); 
    } 
} 

並且可以使用這樣的:

@Autowired private JsonMultipleViewFactory jsonMultipleViewFactory; 

@RequestMapping(value = "my-request") 
public View myRequest() { 
    ... 
    List<ModelAndView> mavList = new ArrayList<ModelAndView>(); 
    mavList.add(modelAndView1); 
    mavList.add(modelAndView2); 
    return jsonMultipleViewFactory.getView(mavList); 
} 
+0

謝謝!它的工作:) – satoshi 2012-03-14 17:00:56

+0

掛上。我得到'NullPointerException',因爲'mav.getView()'返回null,你知道爲什麼嗎? ModelAndView的創建和我的例子完全一樣。謝謝! – satoshi 2012-03-14 18:13:48

+0

從'getView()'DOC:「返回查看對象或null如果我們使用要由DispatcherServlet會通過一個ViewResolver解析的視圖名。」 ......我怎樣才能避免這種情況? – satoshi 2012-03-14 18:16:08