在单个请求中呈现多个视图

发布于 2021-02-02 11:22:25

我试图在单个请求中返回多个视图,并将它们全部以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存储库,其中包含一个很小的示例来重现该问题。

关注者
0
被浏览
63
1 个回答
  • 面试哥
    面试哥 2021-02-02
    为面试而生,有面试问题,就找面试哥。

    更新: 有一些方法可以解决您的问题。我会尝试这种方法,但也许有更清洁的方法。

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


推荐阅读
知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看