`
duanhengbin
  • 浏览: 383375 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

利用 @RequestMapping 多样的参数类型简化框架代码

阅读更多

【前言】

本文主要针对上一篇mybatis分页器实现一个不够合理的地方进行了优化。

原文链接 http://duanhengbin.iteye.com/blog/1998017

=================================================================================

今天研究了一下@RequestMapping 的文档,spring 提供了极其丰富的入参选择,利用HttpServletRequest 实现了一个简化 分页框架的方法。

 

先来看一下简化结果

【改造前】

  @RequestMapping(value = "/user/users")
  public String list(
    @RequestParam(required = false, defaultValue = "1") int pageNo,
    @RequestParam(required = false, defaultValue = "5") int pageSize,
    @ModelAttribute("name") String name,
    @ModelAttribute("levelId") String levelId,
    @ModelAttribute("subjectId") String subjectId,
    Model model) {
    // 这里是“信使”诞生之地,一出生就加载了很多重要信息!
    Page page = Page.newBuilder(pageNo, pageSize, "users");
    page.getParams().put("name", name);           //这里再保存查询条件
    page.getParams().put("levelId", levelId);
    page.getParams().put("subjectId", subjectId);
      
    model.addAttribute("users",userService.selectByNameLevelSubject(
            name, levelId, subjectId, page));
    model.addAttribute("page", page);             //这里将page返回前台
    return USER_LIST_JSP;
  }

【改造后】

  @RequestMapping(value = "/user/users")
  public String list(
    @ModelAttribute("name") String name,
    @ModelAttribute("levelId") String levelId,
    @ModelAttribute("subjectId") String subjectId,
    Model model, HttpServletRequest request) {
    Page page = Page.newBuilder2(5, request);  // 第一个参数为每页行数
      
    model.addAttribute("users",userService.selectByNameLevelSubject(
            name, levelId, subjectId, page));
    model.addAttribute("page", page);             //这里将page返回前台
    return USER_LIST_JSP;
  }

newBuilder2()的结构要简洁得多,Controller入参无需再追加 pageNo 和pageSize了,也无需再将入参手动加入到page对象中,只是需要引入 HttpServletRequest对象。

另外,最大的好处在于,通用性增强了,将来请求接口发生变化时无需为分页修改代码。

 

现在看看 newBuilder2()的实现方法

 

  /**
   * 从 HttpServletRequest 抽取请求入参来构造Page对象
   */
  public static Page newBuilder2(int pageSize, HttpServletRequest request){
    Page page = new Page();
    String uri = request.getRequestURI();
    int pot= uri.lastIndexOf("/");
    // 从uri中抽取右侧"/"后字符串作为的acton名 例子中对应的是 "users"
    page.setSearchUrl(uri.substring(pot+1));
    // 这里是核心代码:遍历 request.getParameterMap() 提取请求参数,要注意数组的情况
    for (Object key : request.getParameterMap().keySet()){
      String[] args = request.getParameterValues(key.toString());
      if (args.length>1){
        page.getParamLists().put(key.toString(), convertParamArr(args,request));
      }else{
        page.getParams().put(key.toString(), convertIsoToUtf8(request.getParameter(key.toString()),request));
      }
    }
    page.setPageSize(pageSize);  // 这里是每页行数
    if ( page.getParams().get("pageNo") == null ){
      page.getParams().put("pageNo", "1");    // 当前页 原来缺省值设定改到了这里
    }else{
      page.setPageNo( Integer.parseInt(page.getParams().get("pageNo")));
      // 点击分页标签时的请求 编辑totalRecord 项目(避免重复查询总记录数)
      page.setTotalRecord(Integer.parseInt(page.getParams().get("totalRecord")));
    }
    return page;
  }

  /**
   * GET请求时,单个入参的转码处理
   */
  private static String convertIsoToUtf8(String strIn, HttpServletRequest request) {
    if (strIn == null || !request.getMethod().equalsIgnoreCase("get")) {
      return strIn;
    }
    try {
      String result = new String(strIn.getBytes("iso-8859-1"), "utf-8");
      return result;
    } catch (UnsupportedEncodingException e) {
      return strIn;
    }
  }

  /**
   * GET请求时,数组型入参的转码处理
   */
  private static List<String> convertParamArr(String[] param,
      HttpServletRequest request) {
    List<String> list = Lists.newArrayList();
    if (param != null) {
      for (String p : param) {
        String convertP = convertIsoToUtf8(p, request);
        if (!list.contains(convertP)) {
          list.add(convertP);
        }
      }
    }
    return list;
  }
 上面两个方法convertIsoToUtf8 和 convertParamArr 是为了处理Get请求时乱码问题。

 

【总结】

Spring提供了令人眼花缭乱的参数类型及相关注解方法来获取参数,但是本质上还是对 HttpSession, HttpServletRequest, HttpServletResponse等这些基础API的封装和组装。在构造框架时,很多时候需要深挖这些基础类。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics