Я создал пользовательский HandlerInterceptorAdapter
для переопределения postHandle
метода:
public class AcmeInterceptor extends HandlerInterceptorAdapter {
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
super.postHandle(request, response, handler, modelAndView);
AcmeController controller = (AcmeController) handler;
controller.finalize(modelAndView);
}
}
В AcmeModel я определяю поле, помеченное NumberFormat:
public class AcmeModel {
private BigDecimal cost = BigDecimal.valueOf(67890.6789);
@NumberFormat(style = Style.CURRENCY)
public BigDecimal getCost() {
return cost;
}
}
В acme.jsp я использую <spring:bind>
для вывода отформатированного значения:
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<spring:bind path="acmeModel.cost">
Cost: <c:out value="${status.value}" />
</spring:bind>
Теперь сначала я попробую контроллер следующим образом:
@Controller
public class AcmeController {
@RequestMapping("/")
public ModelAndView index() {
ModelAndView modelAndView = new ModelAndView("WEB-INF/views/acme.jsp");
modelAndView.addObject(new AcmeModel());
return modelAndView;
}
public void finalize(ModelAndView modelAndView) {
}
}
И вот что я получаю:
Стоимость: $ 67 890,68
Вот загадочная часть. Если я переместу вызов на addObject
в тело finalize
:
@Controller
public class AcmeController {
@RequestMapping("/")
public ModelAndView index() {
ModelAndView modelAndView = new ModelAndView("WEB-INF/views/acme.jsp");
//modelAndView.addObject(new AcmeModel());
return modelAndView;
}
public void finalize(ModelAndView modelAndView) {
modelAndView.addObject(new AcmeModel());
}
}
Тогда вывод будет:
Стоимость: 67890,6789
В чем разница между добавлением объекта к ModelAndView
в методе обработчика по сравнению с обычным методом контроллера, который влияет на <spring:bind>
?
Редактировать : Вот определение бина для сервлета.
<beans ...>
<mvc:annotation-driven />
<context:component-scan base-package="com.example" />
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**" />
<bean id="acmeInterceptor" class="com.example.numberformat.AcmeInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
</beans>