利用 @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的封装和组装。在构造框架时,很多时候需要深挖这些基础类。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
@RequestMapping注解是Spring MVC中常用的注解之一,用于将请求映射到控制器的处理方法上。@RequestMapping注解可以接受多个参数,下面是一些常用的参数及其作用[^1]: 1. value:指定请求的URL路径,可以是一个字符串或字符串数组。例如,@RequestMapping(value = "/users")表示将请求映射到"/users"路径上。 2. method:指定请求的HTTP方法,可以是RequestMethod枚举值或枚举值数组。例如,@RequestMapping(value = "/users", method = RequestMethod.GET)表示将请求映射到"/users"路径上的GET方法。 3. params:指定请求的参数条件,可以是一个字符串或字符串数组。例如,@RequestMapping(value = "/users", params = "id=1")表示只有当请求参数中包含"id=1"时才会映射到该方法上。 4. headers:指定请求的头部条件,可以是一个字符串或字符串数组。例如,@RequestMapping(value = "/users", headers = "Content-Type=application/json")表示只有当请求头部中包含"Content-Type=application/json"时才会映射到该方法上。 5. consumes:指定请求的媒体类型条件,可以是一个字符串或字符串数组。例如,@RequestMapping(value = "/users", consumes = "application/json")表示只有当请求的媒体类型为"application/json"时才会映射到该方法上。 6. produces:指定响应的媒体类型条件,可以是一个字符串或字符串数组。例如,@RequestMapping(value = "/users", produces = "application/json")表示只有当响应的媒体类型为"application/json"时才会映射到该方法上。 下面是一个使用@RequestMapping注解的示例[^2]: ```java @Controller @RequestMapping("/owners/{ownerId}") public class RelativePathUriTemplateController { @RequestMapping(value = "/pets/{petId}", method = RequestMethod.GET, params="myParam=myValue") public void findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) { // 实现省略 } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值