2012-03-14 9 views
5

1回のリクエストで複数のビューを返すようにしています。すべてのリクエストをJSON文字列で返します。1回のリクエストで複数のビューをレンダリングする

例:

@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) 
} 

私は誰も私を助けることができるタイル2とSpring MVCのに

を使用していますか?

アップデート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

+0

私が話している文字列は、レンダリングされたHTMLを文字列として返します(元の質問に応じて変更しました)。 – satoshi

+0

使用しているタイルを結合して1つのコンポジットビューにタイル表示し、その名前にリダイレクトします。 – Stefan

答えて

6

更新:あなたの問題を解決する方法がいくつかあります。私はこれを試してみたいが、もっときれいな方法があるかもしれない。

@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

+0

ハングアップ。 'mav.getView()'がnullを返すので、私は 'NullPointerException'を取得しました。なぜか分かりますか? 'ModelAndView'sは、私の例とまったく同じように作成されます。ありがとう! – satoshi

+0

'getView()' doc: "Viewオブジェクトを返すか、またはViewResolverを介してDispatcherServletによって解決されるビュー名を使用している場合はnull" ...どうすればこの問題を回避できますか? – satoshi

関連する問題