如何在不将Model作为参数的情况下将Attribute传递给View?

时间:2013-01-23 15:20:38

标签: java spring spring-mvc

我正在覆盖属于超类的方法。方法不带参数。因此,我无法使用模型将对象传递给视图。有人有什么建议吗?

@Override
protected String connectView(){
    // I'd like to include an object in Model here
    // e.g. model.addAttribute(....) 
    // but unpossible because super does not take a Model as param
    return "connect/status";
}

2 个答案:

答案 0 :(得分:1)

如果没有至少请求对象,我不相信你可以简单地做你要求的。但是,有几个选择:

  1. 使用servlet过滤器...将所需的值添加到那里的会话
  2. 使用装饰器模式,在其中您将在另一个包装类中创建类的实例(在本例中为控制器)。在你的包装器中,你将进行额外的处理,然后调用包装的内部对象(你的包装控制器),然后进行任何最终处理。
  3. 像@ sp00m一样的HandlerInterceptor建议(虽然我从未使用它,所以我没有输入)
  4. 我相信可能还有其他一些选择,但我想不出其他任何选择。

答案 1 :(得分:0)

这应该符合您的需求,使用HandlerInterceptor,自定义注释@Model和反射。

Model.java

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Model {

}

RequestInterceptor.java

@Service
public class RequestInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException {
        try {
            Class<?> clazz = request.getClass();
            if (clazz.isAnnotationPresent(Controller.class)) {
                for (Field field : clazz.getDeclaredFields()) {
                    if (field.isAnnotationPresent(Model.class)) {
                        field.set(request, new ModelMap());
                        break;
                    }
                }
            }
        } catch (IllegalAccessException e) {
            // log("Cannot access model field of controller " + clazz.getSimpleName());
        }
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        try {
            Class<?> clazz = request.getClass();
            if (clazz.isAnnotationPresent(Controller.class)) {
                for (Field field : clazz.getDeclaredFields()) {
                    if (field.isAnnotationPresent(Model.class)) {
                        ModelMap model = (ModelMap) field.get(request);
                        if (model != null) {
                            modelAndView.addAllObjects(model);
                        }
                        break;
                    }
                }
            }
        } catch (IllegalAccessException e) {
            // log("Cannot access model field of controller " + clazz.getSimpleName());
        }
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }

}

的applicationContext.xml

<!-- register the interceptor -->
<mvc:interceptors>
    <bean class="your.package.to.the.RequestInterceptor" />
</mvc:interceptors>

YourController.java

@Controller
public class YourController extends ConnectController {

    @Model
    private ModelMap model;

    @Override
    protected String connectView(){
        // model is here available
        model.addAttribute("attrName", "attrValue");
        return "connect/status";
    }

}