Spring MVC框架:第三章:获取请求参数和页面跳转控制

简介: Spring MVC框架:第三章:获取请求参数和页面跳转控制

获取请求参数

1.什么是请求参数?

<a href="emp/remove?empId=3">删除</a>
<form action="emp/save" method="post">
    姓名:<input type="text" name="empName"/><br/>
    年龄:<input type="text" name="empAge"/><br/>
    工资:<input type="text" name="empSalary"/><br/>
    <input type="submit" value="保存"/>
</form>

2.请求参数的四种情况

①一名一值

<a href=“emp/remove?empId=3”>删除</a>

在handler方法的参数上使用@RequestParam注解。

@RequestMapping("/caseOne")
public String caseOne(@RequestParam("empId") Integer empId) {
    System.out.println("empId="+empId);
    return "result";
}

SpringMVC会自动帮我们进行类型转换。如果请求参数的名字和handler方法中对应形参的名字一致那么可以省略@RequestParam注解。

@RequestMapping("/caseOne")
public String caseOne(Integer empId) {
    System.out.println("empId="+empId);
    return "result";
}

②一名多值

<form action="team" method="post">
    请选择你最喜欢的球队:
    <input type="checkbox" name="team" value="Brazil"/>巴西
    <input type="checkbox" name="team" value="German"/>德国
    <input type="checkbox" name="team" value="French"/>法国
    <input type="checkbox" name="team" value="Holland"/>荷兰
    <input type="checkbox" name="team" value="Italian"/>意大利
    <input type="checkbox" name="team" value="China"/>中国
    <br/>
    <input type="submit" value="保存"/>
</form>

使用List或数组来接收。

@RequestMapping("/caseTwo")
public String caseTwo(@RequestParam("team") List<String> teams) {
    System.out.println(teams);
    return "result";
}
@RequestMapping("/caseTwo")
public String caseTwo(@RequestParam("team") String[] teams) {
    System.out.println(Arrays.asList(teams));
    return "result";
}

③表单数据正好对应一个实体类

<form action="emp/save" method="post">
    姓名:<input type="text" name="empName"/><br/>
    年龄:<input type="text" name="empAge"/><br/>
    工资:<input type="text" name="empSalary"/><br/>
    <input type="submit" value="保存"/>
</form>

实体类:

public class Employee {
    private Integer empId;
    private String empName;
    private int empAge;
    private double empSalary;
    ……

直接使用和表单对应的实体类类型接收

@RequestMapping("/caseThree")
public String caseThree(Employee employee) {
    System.out.println(employee);
    return "result";
}

④表单对应的实体类包含级联属性

public class Student {
  private Integer studentId;
  private String studentName;
  private School school;
  private List<Subject> subjectList;
  private Subject[] subjectArray;    
  private Set<Teacher> teacherSet;      
  private Map<String,String> scoreMap;
  {
   //在各种常用数据类型中,只有Set类型需要提前初始化
        //并且要按照表单将要提交的对象数量进行初始化
        //Set类型使用非常不便,要尽可能避免使用Set
    teacherSet = new HashSet<>();
    teacherSet.add(new Teacher());
    teacherSet.add(new Teacher());
    teacherSet.add(new Teacher());
  }

handler方法

@RequestMapping("/get/param/multi/value")
  public String getParamOneNameMultiValue(@RequestParam("team") List<String> teamList) {        
    for (String team : teamList) {
      System.out.println(team);
    }       
    return "target";
  }
  @RequestMapping("/get/param/entity")
  public String getParamEntity(Employee employee) {       
    System.out.println(employee);       
    return "target";
  }
  //@RequestMapping("/get/param/entity")
  public String getParamEntityParam(@RequestParam("empName") String empName) {        
    System.out.println("empName="+empName);       
    return "target";
  }
  @RequestMapping("/get/param/fuza")
  public String getParamFuza(Student student) {
    System.out.println("StudentId="+student.getStudentId());
    System.out.println("StudentName="+student.getStudentName());
    System.out.println("SchoolId="+student.getSchool().getSchoolId());
    System.out.println("SchoolName="+student.getSchool().getSchoolName());
    List<Subject> subjectList = student.getSubjectList();
    for (Subject subject : subjectList) {
      System.out.println("科目名称="+subject.getSubjectName());
    }
    Subject[] subjectArray = student.getSubjectArray();
    for (Subject subject : subjectArray) {
      System.out.println("科目名称="+subject.getSubjectName());
    }
    Set<Teacher> teacherSet = student.getTeacherSet();
    for (Teacher teacher : teacherSet) {
      System.out.println("老师姓名="+teacher.getTeacherName());
    }
    Map<String, String> scoreMap = student.getScoreMap();
    Set<String> keySet = scoreMap.keySet();
    for (String key : keySet) {
      String value = scoreMap.get(key);
      System.out.println(key+":"+value);
    }
    return "target";
  }

提交数据的表单

<form action="${pageContext.request.contextPath }/get/param/fuza" method="post">
    学生编号:<input type="text" name="studentId" value="22" /><br/>
    学生姓名:<input type="text" name="studentName" value="tom" /><br/>
    <!-- getSchool().setSchoolId() -->
    学校编号:<input type="text" name="school.schoolId" value="33" /><br/>
    学校名称:<input type="text" name="school.schoolName" value="at" /><br/>
    科目1名称:<input type="text" name="subjectList[0].subjectName" value="理论" /><br/>
    科目2名称:<input type="text" name="subjectList[1].subjectName" value="倒库"/><br/>
    科目3名称:<input type="text" name="subjectList[2].subjectName" value="路考"/><br/>
    科目4名称:<input type="text" name="subjectArray[0].subjectName" value="撞人"/><br/>
    科目5名称:<input type="text" name="subjectArray[1].subjectName" value="防碰瓷"/><br/>
    科目6名称:<input type="text" name="subjectArray[2].subjectName" value="追尾"/><br/>
    老师姓名:<input type="text" name="teacherSet[0].teacherName" value="卡卡西"/><br/>
    老师姓名:<input type="text" name="teacherSet[1].teacherName" value="伊鲁卡"/><br/>
    老师姓名:<input type="text" name="teacherSet[2].teacherName" value="大蛇丸"/><br/>
    考试成绩:<input type="text" name="scoreMap['shuxue']" value="25" /><br/>
    考试成绩:<input type="text" name="scoreMap['yuwen']" value="16" /><br/>
    考试成绩:<input type="text" name="scoreMap['yingyu']" value="7" /><br/>
    考试成绩:<input type="text" name="scoreMap['lol']" value="100" /><br/>
    考试成绩:<input type="text" name="scoreMap['dota']" value="300" /><br/>
    <input type="submit" value="提交"/>
  </form>
  <br/><br/>
  <form action="${pageContext.request.contextPath }/get/param/entity" method="post">
    <!-- private Integer empId; -->
    编号:<input type="text" name="empId"/><br/>
    <!-- private String empName; -->
    姓名:<input type="text" name="empName"/><br/>
    <!-- private Integer empAge; -->
    年龄:<input type="text" name="empAge"/><br/>
    <!-- private Double empSalary; -->
    工资:<input type="text" name="empSalary"/><br/>
    <input type="submit" value="提交"/>
  </form>
  <br/><br/>
  <form action="${pageContext.request.contextPath }/get/param/multi/value" method="post">
    请选择你最喜欢的球队:<br/>
    <input type="checkbox" name="team" value="German"/>德国<br/>
    <input type="checkbox" name="team" value="Brazil"/>巴西<br/>
    <input type="checkbox" name="team" value="Italian"/>意大利<br/>
    <input type="checkbox" name="team" value="China"/>中国<br/>
    <input type="checkbox" name="team" value="Korea"/>韩国<br/>
    <input type="submit" value="提交"/>
  </form>

web.xml配置,解决字符乱码

<!-- 在SpringMVC环境下对请求和响应过程强制使用UTF-8字符集进行编码、解码 -->
  <filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
      <param-name>forceEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

页面跳转控制

1.转发指令

@RequestMapping("/testForward")
public String testForward() {
    return "forward:/target.jsp";
}

forward:/target.jsp

表示方法执行完成后转发到/target.jsp。想一想有了视图解析器拼接字符串指定转发页面之后forward是否多余呢?

2.重定向指令

@RequestMapping("/testRedirect")
public String testRedirect() {
    return "redirect:/target.jsp";
}

redirect:/target.jsp

表示方法执行完成后重定向到/target.jsp。这里重定向中使用的路径和我们以前的写法不同,没有以Web应用名称开头,这是因为SpringMVC会替我们加上。

3.使用原生对象完成转发

@RequestMapping("/testForward")
public void testForward2(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    request.getRequestDispatcher("/target.jsp").forward(request, response);
}

你看,使用原生request对象执行转发后,handler方法的返回值就必须是void,意思是我们自己指定了响应方式,不需要SpringMVC再进行处理了。一个请求只能有一个响应,不能在handler方法里面给一个,然后SpringMVC框架再给一个。

4.使用原生对象完成重定向

@RequestMapping("/testRedirect")
public void testRedirect2(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    response.sendRedirect(request.getContextPath()+"/target.jsp");
}

使用原生response对象执行重定向后,handler方法的返回值同样需要设置为void,原因同上。

相关文章
|
7月前
|
安全 Java Ruby
我尝试了所有后端框架 — — 这就是为什么只有 Spring Boot 幸存下来
作者回顾后端开发历程,指出多数框架在生产环境中难堪重负。相比之下,Spring Boot凭借内置安全、稳定扩展、完善生态和企业级支持,成为构建高可用系统的首选,真正经受住了时间与规模的考验。
556 2
|
8月前
|
XML JSON Java
Spring框架中常见注解的使用规则与最佳实践
本文介绍了Spring框架中常见注解的使用规则与最佳实践,重点对比了URL参数与表单参数的区别,并详细说明了@RequestParam、@PathVariable、@RequestBody等注解的应用场景。同时通过表格和案例分析,帮助开发者正确选择参数绑定方式,避免常见误区,提升代码的可读性与安全性。
|
6月前
|
安全 前端开发 Java
《深入理解Spring》:现代Java开发的核心框架
Spring自2003年诞生以来,已成为Java企业级开发的基石,凭借IoC、AOP、声明式编程等核心特性,极大简化了开发复杂度。本系列将深入解析Spring框架核心原理及Spring Boot、Cloud、Security等生态组件,助力开发者构建高效、可扩展的应用体系。(238字)
|
6月前
|
前端开发 Java 微服务
《深入理解Spring》:Spring、Spring MVC与Spring Boot的深度解析
Spring Framework是Java生态的基石,提供IoC、AOP等核心功能;Spring MVC基于其构建,实现Web层MVC架构;Spring Boot则通过自动配置和内嵌服务器,极大简化了开发与部署。三者层层演进,Spring Boot并非替代,而是对前者的高效封装与增强,适用于微服务与快速开发,而深入理解Spring Framework有助于更好驾驭整体技术栈。
|
6月前
|
消息中间件 缓存 Java
Spring框架优化:提高Java应用的性能与适应性
以上方法均旨在综合考虑Java Spring 应该程序设计原则, 数据库交互, 编码实践和系统架构布局等多角度因素, 旨在达到高效稳定运转目标同时也易于未来扩展.
474 8
|
7月前
|
监控 Kubernetes Cloud Native
Spring Batch 批处理框架技术详解与实践指南
本文档全面介绍 Spring Batch 批处理框架的核心架构、关键组件和实际应用场景。作为 Spring 生态系统中专门处理大规模数据批处理的框架,Spring Batch 为企业级批处理作业提供了可靠的解决方案。本文将深入探讨其作业流程、组件模型、错误处理机制、性能优化策略以及与现代云原生环境的集成方式,帮助开发者构建高效、稳定的批处理系统。
744 1
|
9月前
|
安全 Java 微服务
Java 最新技术和框架实操:涵盖 JDK 21 新特性与 Spring Security 6.x 安全框架搭建
本文系统整理了Java最新技术与主流框架实操内容,涵盖Java 17+新特性(如模式匹配、文本块、记录类)、Spring Boot 3微服务开发、响应式编程(WebFlux)、容器化部署(Docker+K8s)、测试与CI/CD实践,附完整代码示例和学习资源推荐,助你构建现代Java全栈开发能力。
905 1
|
8月前
|
Cloud Native Java API
Java Spring框架技术栈选和最新版本及发展史详解(截至2025年8月)-优雅草卓伊凡
Java Spring框架技术栈选和最新版本及发展史详解(截至2025年8月)-优雅草卓伊凡
1495 0
|
9月前
|
前端开发 Java API
Spring Cloud Gateway Server Web MVC报错“Unsupported transfer encoding: chunked”解决
本文解析了Spring Cloud Gateway中出现“Unsupported transfer encoding: chunked”错误的原因,指出该问题源于Feign依赖的HTTP客户端与服务端的`chunked`传输编码不兼容,并提供了具体的解决方案。通过规范Feign客户端接口的返回类型,可有效避免该异常,提升系统兼容性与稳定性。
649 0
|
9月前
|
缓存 安全 Java
第五章 Spring框架
Spring IOC(控制反转)通过工厂模式管理对象的创建与生命周期,DI(依赖注入)则让容器自动注入所需对象,降低耦合。常见注解如@Component、@Service用于声明Bean,@Autowired用于注入。Bean默认单例,作用域可通过@Scope配置,如prototype、request等。Spring通过三级缓存解决循环依赖问题,但构造函数循环依赖需用@Lazy延迟加载。AOP通过动态代理实现,用于日志、事务等公共逻辑。事务通过@Transactional实现,需注意异常处理及传播行为。
141 0
下一篇
开通oss服务