1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.springframework.batch.admin.web.freemarker;
17
18 import org.springframework.util.StringUtils;
19 import org.springframework.web.servlet.View;
20 import org.springframework.web.servlet.ViewResolver;
21 import org.springframework.web.servlet.support.RequestContextUtils;
22 import org.springframework.web.servlet.view.freemarker.FreeMarkerView;
23
24 import javax.servlet.ServletException;
25 import javax.servlet.http.HttpServletRequest;
26 import javax.servlet.http.HttpServletResponse;
27 import java.util.Map;
28
29
30
31
32
33
34
35
36
37
38
39
40 public class AjaxFreeMarkerView extends FreeMarkerView {
41
42
43
44
45 private static final String FRAGMENTS_PARAM = "fragments";
46
47
48
49
50 private static final String AJAX_ACCEPT_CONTENT_TYPE = "text/html;type=ajax";
51
52
53
54
55 private static final String AJAX_SOURCE_PARAM = "ajaxSource";
56
57 private ViewResolver viewResolver;
58
59 @Override
60 public void afterPropertiesSet() throws Exception {
61 super.afterPropertiesSet();
62 }
63
64 public void setViewResolver(ViewResolver viewResolver) {
65 this.viewResolver = viewResolver;
66 }
67
68 protected void renderMergedTemplateModel(Map<String, Object> model, HttpServletRequest request,
69 HttpServletResponse response) throws Exception {
70
71 if (isAjaxRequest(request, response)) {
72
73 String[] attrNames = getRenderFragments(model, request, response);
74 if (attrNames.length == 0) {
75 logger.warn("An Ajax request was detected, but no fragments were specified to be re-rendered. "
76 + "Falling back to full page render.");
77 super.renderMergedTemplateModel(model, request, response);
78 }
79
80
81
82
83 request.getSession();
84 response.flushBuffer();
85 for (int i = 0; i < attrNames.length; i++) {
86 View fragmentView = null;
87
88 try {
89 fragmentView = (View) getApplicationContext().getBean(attrNames[i], View.class);
90 }
91 catch (Exception e) {
92 if (getAttributesMap().containsKey(attrNames[i])) {
93 String viewName = (String) getAttributesMap().get(attrNames[i]);
94 fragmentView = viewResolver.resolveViewName(viewName, RequestContextUtils.getLocale(request));
95 }
96 }
97
98 if (fragmentView == null) {
99 throw new ServletException("No View with a name of '" + attrNames[i] + "' could be found: " + this);
100 }
101 else {
102 fragmentView.render(model, request, response);
103 }
104 }
105 }
106 else {
107 super.renderMergedTemplateModel(model, request, response);
108 }
109 }
110
111 protected boolean isAjaxRequest(HttpServletRequest request, HttpServletResponse response) {
112 String acceptHeader = request.getHeader("Accept");
113 String ajaxParam = request.getParameter(AJAX_SOURCE_PARAM);
114 if (AJAX_ACCEPT_CONTENT_TYPE.equals(acceptHeader) || StringUtils.hasText(ajaxParam)) {
115 return true;
116 } else {
117 return false;
118 }
119 }
120 protected String[] getRenderFragments(Map<String, Object> model, HttpServletRequest request,
121 HttpServletResponse response) {
122 String attrName = request.getParameter(FRAGMENTS_PARAM);
123 String[] renderFragments = StringUtils.commaDelimitedListToStringArray(attrName);
124 return StringUtils.trimArrayElements(renderFragments);
125 }
126
127 }