`
duanhengbin
  • 浏览: 384838 次
  • 性别: 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的封装和组装。在构造框架时,很多时候需要深挖这些基础类。
分享到:
评论

相关推荐

    最新JAVA面试题总结之框架.docx

    ### 最新JAVA面试题总结之...综上所述,Spring及其SpringMVC框架为Java开发人员提供了一套强大而灵活的工具集,不仅简化了开发过程,还提高了代码的可维护性和可扩展性。掌握这些知识点对于Java开发人员来说至关重要。

    Java实训教程 Java软件开发实战 Java开发框架介绍 SpringMVC_3_方法入参 共41页.pptx

    SpringMVC支持多种方式处理客户端发送的请求参数,使得参数传递更加灵活多样。 1. **操作原始Servlet对象**: - **访问原始Servlet对象**:可以通过在控制器方法中声明`HttpServletRequest`, `HttpServletResponse...

    spring2.5注解介绍[参考].pdf

    在Spring框架2.5版本中,引入了大量注解,极大地简化了配置和依赖注入的过程,使得Java代码更加简洁且易于维护。以下是主要的注解及其用途: 1. **@Controller**:用于标记在Spring MVC中的控制器类,这些类通常...

    spring-framework-3.0.0.RC3-with-docs.zip

    Spring 3.0.0.RC3极大地推动了注解在Java应用中的使用,比如@Controller、@Service、@Repository和@Service注解,它们简化了配置文件,使得代码更加简洁、直观。此外,@Autowired用于自动装配bean,@Qualifier用于...

    spring3.0+spring mvc3.0+mybaits3.0

    3. **MVC框架增强**: Spring MVC 3.0引入了更多的注解支持,如@Controller、@RequestMapping等,简化了控制器的定义。 4. **数据绑定与验证**: 提供了数据绑定和验证功能,便于表单数据处理。 5. **支持更多模板引擎...

    springMVC+myibatis的maven项目架构

    MyBatis的动态SQL功能使得在编写SQL时无需关心参数类型和结果映射,大大简化了开发工作。 3. **Maven项目管理** Maven是Java项目的构建工具,它通过POM(Project Object Model)文件来管理项目的依赖关系,自动...

    Spring MVC 详细入门教程(含jar包)

    它是Spring框架的一个重要组成部分,遵循Model-View-Controller(MVC)设计模式,旨在简化Web应用的开发流程。本教程将带你一步步了解并掌握Spring MVC的基础知识。 一、Spring MVC 概述 Spring MVC 提供了丰富的...

    互联网高频Java后端面试题20道(适合1~3年)V1.0.90.docx

    - **对象序列化与反序列化**:Spring MVC框架支持JSON/XML等格式的数据序列化和反序列化,这有助于实现资源的表示形式多样性。 #### 二、Spring Boot及其优势 **知识点概要**: - **定义**:Spring Boot是Spring...

    spring-framework-4.2.5.RELEASE

    3. **改进的RESTful支持**:通过增强`@RestController`和`@RequestMapping`注解,4.2.5.RELEASE简化了RESTful服务的开发,提高了API设计的灵活性。 4. **更多注解驱动的配置**:4.2.5.RELEASE版本鼓励使用注解进行...

    springmvc配置

    Spring MVC的设计目的是简化开发,提供清晰的架构,并通过松耦合的方式促进代码的可测试性。在这个“springmvc配置”主题中,我们将探讨两种配置方式:XML配置和注解配置。 ### XML配置 XML配置是Spring MVC早期...

    spring-3.0.5.jar

    《Spring框架3.0.5版本详解》 Spring框架,作为Java开发中的核心组件,以其强大的功能和灵活性深受开发者喜爱。本次我们关注的是Spring的3.0.5版本,这是一个重要的里程碑,它在前一版本的基础上进行了一系列优化和...

    SpringMVC文档

    - 可以直接接收原始类型参数(如`String`、`int`)或自定义对象类型。 - 支持通过`HttpServletRequest`、`HttpSession`等获取额外的信息。 5. **返回值处理**: - 最常见的做法是返回一个`String`类型的值,该值...

    springboot+vue基于java的少数民族音乐网站的设计与实现论文.docx

    控制层使用Spring Boot提供的@RestController注解来标记控制器类,通过@RequestMapping注解来映射URL请求。控制层还使用了Spring Boot提供的自动装配机制,来简化系统的配置和开发。 三、业务处理层Service设计 ...

    netty_demo-master.zip

    通过Springboot的自动配置特性,我们可以轻松地将Netty服务器集成到项目中,简化了传统Java网络编程的复杂性。 Netty的核心在于其异步事件驱动模型,通过NIO(非阻塞I/O)提供高性能的网络通信能力。在"Netty_demo-...

    spring-framework-4.0.7.RELEASE-dist.zip

    4.0.7.RELEASE版对AOP进行了优化,提供了更强大的切面定义和通知类型,包括前置、后置、异常、最终和环绕通知,为代码的维护和扩展提供了便利。 3. **数据访问/集成**: Spring Framework 4.0.7.RELEASE提供了对...

    springboot+vue汽车租赁管理系统答辩PPT.ppt

    Spring Boot 是基于 Spring Framework 的一套快速应用开发框架,它简化了配置文件,自动配置了 Spring 和第三方库,使得开发者可以更加专注于业务逻辑的开发。 **特点**: - **简化配置**:Spring Boot 自动配置了...

    com.jj.Springboot-vue.rar

    SpringBoot 是由 Pivotal 团队提供的全新框架,它基于 Spring 平台,旨在简化 Spring 应用的初始搭建以及开发过程。SpringBoot 的核心特性包括自动配置、内嵌式 Web 服务器、运行时健康检查以及起步依赖等,使得...

    SpringBoot入门1

    Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目标是用来简化新 Spring 应用的初始搭建以及开发过程。它整合了大量常用的第三方库配置,如 JDBC、MongoDB、JPA、RabbitMQ、Quartz 等等,提供了开箱即用的...

    jquery+ajaxform+springboot控件实现数据更新功能

    通过使用ajaxForm插件,开发者可以无需重写表单数据到AJAX请求体中,而是直接利用现有的表单结构,使代码更加简洁、清晰。ajaxForm插件会拦截表单的提交行为,并将表单数据自动以AJAX的形式发送到服务器。 ### 知识...

    互联网高频Java后端面试题20道(适合1~3年)V1.0.95.docx

    MyBatis是一款持久层框架,主要用于简化SQL语句的编写,并通过映射机制将Java对象与SQL语句关联起来。 **详细解释:** 1. **工作原理**: - 配置文件或注解定义SQL语句。 - 使用`SqlSessionFactory`创建`...

Global site tag (gtag.js) - Google Analytics