是否可以在我的控制器映射方法中将我的视图渲染为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;
}
我想知道在控制器方法中创建视图并将视图呈现为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());
答案 0 :(得分:21)
尝试自动装配ViewResolver,然后调用resolveViewName("myview", Locale.US)
以获取视图。
然后在视图上调用render()
,将其传递给" mock" 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());
答案 1 :(得分:0)
如果要在DispatcherServlet
呈现的同一区域设置下呈现视图,请尝试处理render
- 方法:
/** LocaleResolver used by this servlet */
private LocaleResolver localeResolver;
/** List of ViewResolvers used by this servlet */
private List<ViewResolver> viewResolvers;
/**
* Render the given ModelAndView.
* <p>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).
* <p>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<String, Object> 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
也会在自动装配失败时使用回退。
答案 2 :(得分:-1)
您可以使用模板库来创建html,例如Velocity。然后,您需要将返回类型定义为
public @ResponseBody SomeObject viewAcc(...) {...}
并且对象本身可以获取html以及其他一些变量
答案 3 :(得分:-1)
如果由于没有请求而无法以简单的方式呈现视图(例如,您希望以预定的服务方式呈现电子邮件),请查看本文:https://technologicaloddity.com/2011/10/04/render-and-capture-the-output-of-a-jsp-as-a-string/3/
在GitHub上有一个专案:https://github.com/bobrob/CaptureJSP