草庐IT

java - 来自多个来源的 Spring MVC 复杂模型填充

coder 2024-03-03 原文

好吧,我的问题可能听起来有点模糊,但不管怎样,我的问题就在这里。 我正在使用 Spring MVC 3.1.M1、JSP 2.1 构建一个 Web 应用程序(没有 Tiles,我使用纯 JSP 标记文件来组成我的布局)。

基本上,我的页面是使用一些常见部分的布局构建的 - 页眉、页脚、横幅、菜单等。这些部分中的大多数是动态的,即包含当前用户的相关信息。

JSP 没有“组件”概念,所以我无法在某个地方定义我的模板的一部分及其支持的 Java 代码,并将它们耦合在一起。在我的@Controllers 中,我必须完全填充我的模型,包括页眉、页脚、菜单和其他内容的数据。我真正想做的是避免这种代码重复。具有一些通用模型填充方法的抽象 BaseController 类看起来也不太好。

JSP 和 Spring MVC 经常一起使用,所以我希望在这个主题上存在一些最佳实践。 让我们讨论一下。

最佳答案

好的,所以我花了一些时间研究 Spring MVC 引用和示例应用程序,并找到了一些其他方法来完成我的任务。他们在这里:

1) 方法一,不好用,这里提一下。使用 populateHeaderData(Model model)、populateFooterData(Model model) 等方法抽象 BaseController。所有扩展 BaseController 的 Controller 类中的所有 @RequestMapping 方法都调用这些方法来填充特定于布局的模型数据。

优点:

缺点:代码重复保持不变,只是减少了重复代码的数量

2) @ModelAttribute 方法,即隐式模型丰富。看起来像

@Controller
@RequestMapping(value="/account")
public class AccountController {

    @ModelAttribute("visitorName")
    private String putVisitor() {
        return visitorService.getVisitorName();
    }

    // handler methods
}

在 JSP 中,

<span id="username">Welcome, ${visitorName}!</span>

优点:无需显式调用模型扩充方法 - 它可以正常工作

缺点:这是一件棘手的事情。 Spring MVC 使用“推”模板模型而不是“拉”。在这种情况下,这意味着当调用此类中定义的任何 @RequestMapping 方法时,都会调用此类的所有 @ModelAttribute 方法。如果模板确实需要 visitorName 以及模板是否确实存在用于特定操作,则没有区别。这包括表单提交的 POST 请求等。实际上,这迫使我们更改 Controller 分离。例如,所有表单提交都应该在单独的 Controller 类中,并且处理程序方法应该以某种方式按布局分组。我得想一想,也许它并没有第一眼看上去那么糟糕。

更多缺点:假设我们的布局 A 和 B 具有相同的非静态页眉,B 和 C 具有相同的非静态页脚(所有其他部分都不同)。我们不能为布局 B 实现基类,因为 Java 中没有多重继承。

向听众提问: Spring MVC 引用声明“处理程序方法支持以下返回类型:一个 ModelAndView 对象,模型隐式地丰富了命令对象和 @ModelAttribute 注释的引用数据访问器方法的结果......”。这些命令对象到底是什么?

3) 我自己的pull-like方法。我们可以以

的形式创建自定义上下文
@Component("headerContext")
public class HeaderContext {

    @Autowired
    private VisitorService visitorService;

    public String getVisitorName() {
        return visitorService.getVisitorName();
    }

    // more getters here

}

然后,通过

将这些 bean 暴露给 JSP EL
<!-- Resolves view names to protected .jsp resources within the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <beans:property name="prefix" value="/WEB-INF/views/"/>
    <beans:property name="suffix" value=".jsp"/>
    <beans:property name="exposedContextBeanNames" value="headerContext,footerContext"/>
</beans:bean>

并在 header.tag(重用 header 的 JSP 标记文件)

<span id="username">Welcome, ${headerContext.visitorName}!</span>

优点:“拉”策略(没有人问 - 没有任何内容被执行),易于创建上下文 @Scope("request") 并启用请求范围的缓存,多重继承没有问题。只需在一处编码,在一处配置,并且可以作为常用表达式在任何 JSP 或标记文件中使用。

缺点:在一个框架内混合推和拉(必须考虑更多),在上下文实现类中不支持 Spring MVC(我的意思是 Controller 处理程序方法中这些讨厌的预填充参数),只是 Spring Bean 。

关于java - 来自多个来源的 Spring MVC 复杂模型填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5383112/

有关java - 来自多个来源的 Spring MVC 复杂模型填充的更多相关文章

  1. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  2. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  3. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  4. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  5. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  6. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  7. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  8. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  9. ruby - 多个属性的 update_column 方法 - 2

    我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2

  10. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

随机推荐