如何手动将Spring MVC视图呈现为html?

是否可以在我的控制器映射方法中将我的视图渲染为html,以便我可以将渲染的html作为我的json对象的一部分返回?

我通常的控制器方法示例:

@RequestMapping(value={"/accounts/{accountId}"}, method=RequestMethod.GET) public String viewAcc(final HttpServletRequest req, final HttpServletResponse resp, final Model model, @PathVariable("accountId") final String docId) { // do usual processing ... // return only a STRING value, // which will be used by spring MVC to resolve into myview.jsp or myview.ftl // and populate the model to the template to result in html return "myview"; } 

我期待的是:

 @RequestMapping(value={"/accounts/{accountId}"}, method=RequestMethod.GET) public String viewAcc(final HttpServletRequest req, final HttpServletResponse resp, final Model model, @PathVariable("accountId") final String docId) { // do usual processing ... // manually create the view ModelAndView view = ... ? (how) // translate the view to the html // and get the rendered html from the view String renderedHtml = view.render .. ? (how) // create a json containing the html String jsonString = "{ 'html' : " + escapeForJson(renderedHtml) + "}" try { out = response.getWriter(); out.write(jsonString); } catch (IOException e) { // handle the exception somehow } return null; } 

我想知道在控制器方法中手动创建视图和手动渲染视图的正确方法是什么。

———更新———

以下是接受的答案指导中的工作示例:

 View resolvedView = thiz.viewResolver.resolveViewName("myViewName", Locale.US); MockHttpServletResponse mockResp = new MockHttpServletResponse(); resolvedView.render(model.asMap(), req, mockResp); System.out.println("rendered html : " + mockResp.getContentAsString()); 

尝试自动assemblyViewResolver,然后调用resolveViewName("myview", Locale.US)来获取View。

然后在视图上调用render() ,向其传递一个“模拟”HTTP响应,该响应具有用于输出的ByteArrayOutputStream,并从ByteArrayOutputStream获取HTML。

更新

这是从问题中复制的工作示例。 (所以代码实际上是答案)

 View resolvedView = thiz.viewResolver.resolveViewName("myViewName", Locale.US); MockHttpServletResponse mockResp = new MockHttpServletResponse(); resolvedView.render(model.asMap(), req, mockResp); System.out.println("rendered html : " + mockResp.getContentAsString()); 

如果要在DispatcherServlet呈现它的同一语言环境下呈现视图,请尝试处理它的render -method:

 /** LocaleResolver used by this servlet */ private LocaleResolver localeResolver; /** List of ViewResolvers used by this servlet */ private List viewResolvers; /** * Render the given ModelAndView. * 

This is the last stage in handling a request. It may involve resolving the view by name. * @param mv the ModelAndView to render * @param request current HTTP servlet request * @param response current HTTP servlet response * @throws ServletException if view is missing or cannot be resolved * @throws Exception if there's a problem rendering the view */ protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception { // Determine locale for request and apply it to the response. Locale locale = this.localeResolver.resolveLocale(request); response.setLocale(locale); View view; if (mv.isReference()) { // We need to resolve the view name. view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request); if (view == null) { throw new ServletException("Could not resolve view with name '" + mv.getViewName() + "' in servlet with name '" + getServletName() + "'"); } } else { // No need to lookup: the ModelAndView object contains the actual View object. view = mv.getView(); if (view == null) { throw new ServletException("ModelAndView [" + mv + "] neither contains a view name nor a " + "View object in servlet with name '" + getServletName() + "'"); } } // Delegate to the View object for rendering. if (logger.isDebugEnabled()) { logger.debug("Rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'"); } try { view.render(mv.getModelInternal(), request, response); } catch (Exception ex) { if (logger.isDebugEnabled()) { logger.debug("Error rendering view [" + view + "] in DispatcherServlet with name '" + getServletName() + "'", ex); } throw ex; } } /** * Resolve the given view name into a View object (to be rendered). *

The default implementations asks all ViewResolvers of this dispatcher. * Can be overridden for custom resolution strategies, potentially based on * specific model attributes or request parameters. * @param viewName the name of the view to resolve * @param model the model to be passed to the view * @param locale the current locale * @param request current HTTP servlet request * @return the View object, or {@code null} if none found * @throws Exception if the view cannot be resolved * (typically in case of problems creating an actual View object) * @see ViewResolver#resolveViewName */ protected View resolveViewName(String viewName, Map model, Locale locale, HttpServletRequest request) throws Exception { for (ViewResolver viewResolver : this.viewResolvers) { View view = viewResolver.resolveViewName(viewName, locale); if (view != null) { return view; } } return null; }

@Autowired添加到顶部的字段通常应该足够了,但DispatcherServlet在自动assembly失败时也会使用回退。

如果由于您没有请求而无法以简单的方式呈现视图(例如,您希望以预定的服务方式呈现电子邮件),请查看以下文章: https : //technologicaloddity.com/2011/10 / 04 /渲染和夺输出对的一JSP作为一种串/ 3 /

GitHub上有一个项目: https : //github.com/bobrob/CaptureJSP

你可以使用模板库来创建html,例如Velocity 。 然后,您需要将返回类型定义为

 public @ResponseBody SomeObject viewAcc(...) {...} 

并且对象本身可以获取html以及一些其他变量