Java 如何手动将 Spring MVC 视图呈现为 html?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22422411/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to manually render Spring MVC view to html?
提问by bertie
Is it possible to render my view into html in my controller mapping method, so that i can return the rendered html as a part of my json object ?
是否可以在我的控制器映射方法中将我的视图呈现为 html,以便我可以将呈现的 html 作为我的 json 对象的一部分返回?
Example of my usual controller method :
我常用的控制器方法示例:
@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";
}
What i expect :
我的期望:
@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;
}
I wonder what is the right way to create the view and render the view into html manually within the controller method.
我想知道在控制器方法中手动创建视图并将视图呈现为 html 的正确方法是什么。
Update
更新
Here's the working example from the accepted answer's guidance :
这是接受的答案指南中的工作示例:
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());
采纳答案by Ted Bigham
Try autowiring the ViewResolver then calling resolveViewName("myview", Locale.US)
to get the View.
尝试自动装配 ViewResolver,然后调用resolveViewName("myview", Locale.US)
以获取视图。
Then call render()
on the view, passing it a "mock" HTTP response that has a ByteArrayOutputStream for its output, and get the HTML from the ByteArrayOutputStream.
然后调用render()
视图,向它传递一个“模拟”HTTP 响应,该响应具有用于其输出的 ByteArrayOutputStream,并从 ByteArrayOutputStream 获取 HTML。
Update
更新
Here's the working example, copied from the question. (so the code is actually with the answer)
这是从问题中复制的工作示例。(所以代码实际上是有答案的)
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());
回答by Milo? Luka?ka
you can use templating library for creating html, Velocityfor example. Then, you need to define return type as
您可以使用模板库来创建 html,例如Velocity。然后,您需要将返回类型定义为
public @ResponseBody SomeObject viewAcc(...) {...}
and the object itself can obtain the html, as well as some other variables
并且对象本身可以获得html,以及其他一些变量
回答by TheConstructor
If you want to render the view under the same locale as the DispatcherServlet
would render it, try coping it's render
-method:
如果您想在与渲染视图相同的语言环境下渲染视图DispatcherServlet
,请尝试处理它的render
-method:
/** 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;
}
It should usually be sufficient to add @Autowired
to the fields on top, but the DispatcherServlet
also employs a fallback when autowiring would fail.
通常应该足以添加@Autowired
到顶部的字段,但是DispatcherServlet
当自动装配失败时也会采用回退。
回答by izogfif
If you cannot render your view the easy way since you don't have the request (e.g. you want to render e-mail in scheduled service method), take a look at this article: https://technologicaloddity.com/2011/10/04/render-and-capture-the-output-of-a-jsp-as-a-string/3/
如果您因为没有请求而无法以简单的方式呈现您的视图(例如,您想以预定的服务方式呈现电子邮件),请查看这篇文章:https: //technologicaloddity.com/2011/10 /04/render-and-capture-the-output-of-a-jsp-as-a-string/3/
There is a project on GitHub for it: https://github.com/bobrob/CaptureJSP
GitHub 上有一个项目:https: //github.com/bobrob/CaptureJSP