6

在我们的 web 应用程序中,使用 Spring MVC 3.2 我们显示了许多不同对象的分页列表,并且列表中其他页面的链接构造如下:

/servlet/path?pageNum=4&resultsPerPage=10&sortOrder=ASC&sortBy=name

尽管 URL 中可能还有其他请求参数(例如,搜索过滤器)。

所以我们有这样的控制器方法:

@RequestMapping(method = RequestMethod.GET, value="/ajax/admin/list")
public String ajaxlistGroups(Model model,
   @RequestParam(value="pageNumber",required=false,defaultValue="0") Long pageNumber,
   @RequestParam(value="resultsPerPage",required=false,defaultValue="10") int resultsPerPage,
   @RequestParam(value="sortOrder",required=false,defaultValue="DESC") String sortOrder,
 @RequestParam(value="orderBy",required=false,defaultValue="modificationDate")String orderBy)  {
// create a PaginationCriteria object to hold this information for passing to Service layer
// do Database search
// return a JSP view name

}

所以我们最终得到了这个笨拙的方法签名,在应用程序中重复了几次,每个方法都需要创建一个 PaginationCriteria 对象来保存分页信息,并验证输入。

如果这些请求参数存在,有没有办法自动创建我们的 PaginationCriteria 对象?例如,将以上内容替换为:

@RequestMapping(method = RequestMethod.GET, value="/ajax/admin/list")
public String ajaxlistGroups(Model model, @SomeAnnotation? PaginationCriteria criteria,
  )  {
 ...
   }

即,在 Spring 中有没有办法从常规 GET 请求中获取定义的 requestParams 子集,并自动将它们转换为对象,以便在 Controller 处理程序方法中使用?我以前只使用过@ModelAttribute,这似乎不正确。

谢谢!

4

1 回答 1

7

Spring 3.2 应该自动将请求参数映射到自定义 java bean。

@RequestMapping(method = RequestMethod.GET, value="/ajax/admin/list")
public String ajaxlistGroups(Model model, PaginationCriteriaBean criteriaBean,
  )  {
 //if PaginationCriteriaBean should be populated as long as the field name is same as 
 //request parameter names.
}

我不确定 Spring 如何神奇地实现这一点(没有 @ModelAttribute),但上面的代码对我有用。

还有另一种方式可以达到同样的目的,其实可以实现更多,那就是spring AOP。

<bean id="aspectBean" class="au.net.test.aspect.MyAspect"></bean>
<aop:config>
    <aop:aspect id="myAspect" ref="aspectBean">
    <aop:pointcut id="myPointcut"
        expression="execution(* au.net.test.web.*.*(..)) and args(request,bean,..)" />
    <aop:before pointcut-ref="myPointcut" method="monitor" />
    </aop:aspect>
</aop:config>

在应用程序上下文中,我们声明Aspect bean 以及Pointcut以及建议,在您的情况下是在建议之前

以下是源代码

    public class PaginationCriteriaBean {

        private String id;
        private String name;

        public String getId() {
            return id;
        }

        public void setId(String id) {
            this.id = id;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
//custom Aspect
public class MyAspect {

    public void monitor( HttpServletRequest request,PaginationCriteriaBean bean){
        //populate your pagination bean
        bean.setId(request.getParameter("id"));
        bean.setName("my new name");
    }
}

    @RequestMapping(value="/app")
    public String appRoot(HttpServletRequest request,PaginationCriteriaBean bean){
        System.out.println(bean.getId());
        System.out.println(bean.getName());
        return "app";
    }

通过这样做,切面将拦截spring控制器并根据请求参数填充PaginationCriteriaBean,您甚至可以更改请求中的原始值。通过这个 AOP 实现,您可以对分页应用更多逻辑,例如日志记录和验证等。

于 2013-02-07T11:41:31.720 回答