2012-03-14 91 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