Часто бывает нужно передать данные с серверной части на клиентскую, причём не в виде текста, а в виде готовых объектов. К сожалению, в HTML-страницу нельзя внедрить данные напрямую, но можно сгенерировать js-скрипт, в который бы передавался JSON, готовый к употреблению. Обычно я делал это вручную, но теперь решил написать спринговый interceptor
, который бы перехватывал все атрибуты model
, начинающиеся с “js_”, и добавлял их на клиент автоматически.
Пример использования
@RequestMapping(value = "/create", method = RequestMethod.GET)
public String viewCreate(Model model) {
NewsArticle article = new NewsArticle();
// Этот атрибут будет доступен только в JSP при генерации страницы
model.addAttribute( "article", article );
// А этот атрибут также попадёт и в js-код в качестве атрибута глобального объекта JS_DATA
model.addAttribute( "js_article_id", article.getId() );
return "edit";
} |
@RequestMapping(value = "/create", method = RequestMethod.GET)
public String viewCreate(Model model) {
NewsArticle article = new NewsArticle();
// Этот атрибут будет доступен только в JSP при генерации страницы
model.addAttribute( "article", article );
// А этот атрибут также попадёт и в js-код в качестве атрибута глобального объекта JS_DATA
model.addAttribute( "js_article_id", article.getId() );
return "edit";
}
$(function() {
var articleId = JS_DATA['js_article_id'];
// ...
}); |
$(function() {
var articleId = JS_DATA['js_article_id'];
// ...
});
Код
Все необходимые кусочки файлов можно посмотреть на github, а здесь приведу только код интерсептора:
public class JsDataInjectionInterceptor extends HandlerInterceptorAdapter
{
private final static Log log = LogFactory.getLog( JsDataInjectionInterceptor.class );
@Override
public void postHandle( HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView ) throws Exception {
//
if (null == modelAndView) return;
Map<String, Object> jsObjects = null;
for ( Map.Entry<String, Object> entry : modelAndView.getModelMap().entrySet() ) {
if (entry.getKey().startsWith( "js_" )) {
if (null == jsObjects)
jsObjects = new HashMap<>( );
jsObjects.put( entry.getKey(), entry.getValue() );
}
}
if (jsObjects != null) {
ObjectMapper mapper = new ObjectMapper();
mapper.enable( SerializationFeature.INDENT_OUTPUT );
String jsData = mapper.writeValueAsString( jsObjects );
log.debug( "JsData: " + jsData );
modelAndView.getModelMap().addAttribute( "__js_data__",
jsData
);
}
}
} |
public class JsDataInjectionInterceptor extends HandlerInterceptorAdapter
{
private final static Log log = LogFactory.getLog( JsDataInjectionInterceptor.class );
@Override
public void postHandle( HttpServletRequest request,
HttpServletResponse response,
Object handler,
ModelAndView modelAndView ) throws Exception {
//
if (null == modelAndView) return;
Map<String, Object> jsObjects = null;
for ( Map.Entry<String, Object> entry : modelAndView.getModelMap().entrySet() ) {
if (entry.getKey().startsWith( "js_" )) {
if (null == jsObjects)
jsObjects = new HashMap<>( );
jsObjects.put( entry.getKey(), entry.getValue() );
}
}
if (jsObjects != null) {
ObjectMapper mapper = new ObjectMapper();
mapper.enable( SerializationFeature.INDENT_OUTPUT );
String jsData = mapper.writeValueAsString( jsObjects );
log.debug( "JsData: " + jsData );
modelAndView.getModelMap().addAttribute( "__js_data__",
jsData
);
}
}
}
0