hander参数映射

当我们要实现一个登陆功能时:

  • 创建一个用于处理登录请求的Servlet
  • 实现doget等其他http方法(一些情况可能根据业务需要限制请求方法)
  • 从request对象中取出数据
  • 处理编码
  • 验证参数是否符合要求
  • 对参数数据类型进行转换(需要时)
  • 开始业务逻辑处理(登录)
  • 可能需要操作session来完成
  • 组织响应给数据,可能是html可能是json,
  • 异常处理
  • Header与cookie的处理

整个SpringMVC其实就是帮我们对上面的操作进行封装,当然了SpringMVC也提供了更多的功能。

hander方法的特殊参数

在handler方法中我们可以添加一下参数,用于获取一些特殊的对象:

  • HttpServletRequest,HttpServletResponse
  • HttpSession
  • Model
  • ModelMap

model 是框架帮我们创建好的的Model对象,若使用该参数作为返回的model,则需要修改方法返回值为String用于指定视图名称;

比如:

//model参数
@RequestMapping("/courseList2.action")public String courseList(Model model) {model.addAttribute("courses", courseService.selectCourseList());return "courses.jsp";}//model、HttpSession、HttpSession、HttpServletResponse参数,@RequestMapping("/courseList3.action")public String courseList(ModelMap model, HttpSession session,HttpSession request,HttpServletResponse response) {System.out.println(request);System.out.println(response);System.out.println(session.getId());model.addAttribute("courses", courseService.selectCourseList());return "courses.jsp";}

请求参数映射

在handler方法中添加与前台参数名称和类型匹配的参数,框架会自动解析参数传入handler方法中;

比如:

我们要修改课程信息的功能,首先要获取原始信息,而界面只需将对应的name和参数一致即可:

@RequestMapping("/edit.action")
public String edit(Model model,Integer id) {Course course = courseService.selectCourseByID(id);model.addAttribute("course",course);return "edit.jsp";
}

支持的参数类型:

整形:Integer、int
字符串:String
单精度:Float、float
双精度:Double、double
布尔型:Boolean、boolean

@RequestParam

当前后台参数名称不匹配时可以@RequestParam注解进行自定义映射;

注解参数:

  • value,name 两者都代表前台参数名称
  • requerd 该参数是否必须
  • defaultValue 参数默认值

比如:

上面就是将id赋值给iid,默认值为1.

@RequestMapping("/edit.action")
public String edit(Model model,@RequestParam(value = "id",defaultValue = "1") Integer iid) {Course course = courseService.selectCourseByID(iid);model.addAttribute("course",course);return "edit.jsp";
}

注意:参数类型可以是基础类型也可以是包装类型,建议使用包装类型,这样可以保证为获取到参数时不会因为null无法转换为基础类型而导致的异常;

edit.jsp:

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head></head>
<form action="updateCourse.action" method="post"><input name="id" value="${course.id}" hidden="hidden"/><input name="name" value="${course.name}"/><input name="teachName" value="${course.teachName}"/><%--    <input name="startTime" type="date" value='<fmt:formatDate value="${course.startTime}" pattern="yyyy-MM-dd"/>'/>--%><input name="score" type="number" value="${course.score}"/><input name="hours" type="number" value="${course.hours}"/><input type="submit">
</form>
<body>
</body>
</html>

映射到实体类

当参数个数非常多时上面的方法就显得麻烦了,SpringMVC支持将参数映射到一个实体类;

在handler方法中添加任意类型实体类作为参数; 同样的只有参数名称和实体属性一致时才能映射成功;

比如修改功能:

@RequestMapping("/updateCourse.action")
public String update(Course course) {courseService.updateCourse(course);return "/courseList.action";
}

乱码过滤器

出现了中文乱码问题,请求方法为post, 只需要在request中设置编码方式即可,但是此时参数已经被框架解析了,我们在handler中通过request设置以及不生效了,所以我们需要在请求到达SpringMVC之前就进行处理,这就用到过滤器了;

好消息是SpringMVC以及提供了过滤器,我们只需要配置到web.xml中即可:

<!--    编码过滤器--><filter><filter-name>encodingFilter</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>forceResponseEncoding</param-name><param-value>true</param-value></init-param></filter><filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>
<!--    编码过滤器 END-->

需要注意的是,该过滤器只对post生效,如果是get乱码则还是需要修改tomcat的server.xml或是通过代码从ISO-8859-重新编码为UTF-8:

String username = request.getParameter("username");
username = new String(username.getBytes("iso8859-1"), "utf-8"); //重新编码

参数类型转换

我们将edit.jsp中的开课标签取消注释,然后测试会发现系统给出了400异常,查看控制台可以看到以下信息:

意思是框架无法将String类型的请求参数转换为需要的Date类型,这就需要,这是因为日期格式多种多样,每个地区不同,所以这需要我们自己来实现转换;

编写转换器

实现convert接口即可作为转换器,该接口的两个两个泛型表示输入源类型和输出目标类型;

public class StringToDateConverter implements Converter<String, Date> {@Overridepublic Date convert(String s) {SimpleDateFormat sm = new SimpleDateFormat("yyyy-MM-dd");try {return sm.parse(s);} catch (ParseException e) {e.printStackTrace();}return null;}
}

mvc配置:

<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"><property name="converters"><set><bean class="com.kkb.converter.StringToDateConverter"/></set></property>
</bean>
<mvc:annotation-driven conversion-service="conversionService"/>
使用注解

使用@DateTimeFormat可以实现上面xml相同的配置:

public class Course {private Integer id;private String name;private String teachName;@DateTimeFormat(pattern = "yyyy-MM-dd")private Date startTime;
}

注意:注解作用在实体类对应的属性上,且配置文件必须添加下面这句:

<mvc:annotation-driven>

包装类型映射

当需要将参数映射到实体类的关联对象中时,也称为包装类型;

例如:在课程对象中有一个用户对象,表示这是某个用户的课程;前台需要同时传递课程对象的属性,和用户对象的属性,后台就需要要用一个包装类型来接收,即一个包装了用户对象的课程对象; 再说的简单点,即课程对象中包含一个用户对象;

在前台需要指出关联对象的属性名称,如: user.name

实体:

public class Course {private Integer id;private String name;private String teachName;private Date startTime;private Integer score;private Integer hours;private User user;//新添加的User类属性}

setter 和getter方法自行填补。

handler:

@RequestMapping("/updateCourse.action")
public String update(Course course) {courseService.updateCourse(course);return "/courseList.action";
}

jsp:

<form action="updateCourse.action" method="post"><input name="id" value="${course.id}" hidden="hidden"/><input name="name" value="${course.name}"/><input name="teachName" value="${course.teachName}"/><input name="startTime" type="date" value='<fmt:formatDate value="${course.startTime}" pattern="yyyy-MM-dd"/>'/><input name="score" type="number" value="${course.score}"/><input name="hours" type="number" value="${course.hours}"/><input name="user.username"/>  <!-- 新添加的参数--><input type="submit">
</form>

数组参数映射

一些情况下,某一参数可能会有多个值,例如要进行批量删除操作,要删除的id会有多个,那就需要将参数映射到一个数组中;HttPServletRequest原本就支持获取数组参数,SpringMVC仅是帮我们做了一个类型转换;

1.修改页面添加多选框:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
</head>
<body>
<form action="deleteCourses"><table border="1"><tr><th>选择</th><th>名称</th><th>讲师</th><th>开课日期</th><th>学分</th><th>课时</th><th>操作</th></tr><c:forEach items="${courses}" var="course"><tr><td><input type="checkbox" name="ids" value="${course.id}"></td><td>${course.name}</td><td>${course.teachName}</td><td><fmt:formatDate value="${course.startTime}" pattern="yyyy-MM-dd"/></td><td>${course.score}</td><td>${course.hours}</td><td><a href="editCourse?id=${course.id}">修改</a></td></tr></c:forEach></table><input type="submit" value="批量删除">
</form>
</body>
</html>

2、handler方法:

@RequestMapping("/deleteCourses")
public String deleteCourses(Integer[] ids){courseService.deleteCourses(ids);return "/getCourses";
}

3.service方法:

public void deleteCourses(Integer[] ids) {for (Integer id : ids){courseMapper.deleteByPrimaryKey(id);}
}

List映射

当请求参数包含多个对象的属性数据,是需要使用list来接收,通常用在批量修改批量添加等;

list映射要求参数名称为对象属性[下标].属性名称,同时handler中使要用包装类型来接收;

以下是实现一个批量修改课程信息的功能;

1.修改页面中的td,使得每一个td都可以编辑:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
</head>
<body>
<form action="deleteCourses" id="fm"><table border="1"><tr><th>选择</th><th>名称</th><th>讲师</th><th>开课日期</th><th>学分</th><th>课时</th><th>操作</th></tr><c:forEach items="${courses}" var="course" varStatus="status"><tr><td><input type="checkbox" name="ids" value="${course.id}"></td><td><input value="${course.name}" name="courses[${status.index}].name"/></td><td><input value="${course.teachName}" name="courses[${status.index}].teachName"/></td><td><input value='<fmt:formatDate value="${course.startTime}" pattern="yyyy-MM-dd"/>' name="courses[${status.index}].startTime"/></td><td><input value="${course.score}" name="courses[${status.index}].score"/></td><td><input value="${course.hours}" name="courses[${status.index}].hours"/></td><input hidden="hidden" name="courses[${status.index}].id" value="${course.id}"><td><a href="editCourse?id=${course.id}">修改</a></td></tr></c:forEach></table><input type="submit" value="批量删除"><input type="button" οnclick='function updates() {document.getElementById("fm").action = "updateCourses"document.getElementById("fm").submit()}updates()' value="批量修改">
</form>
</body>
</html>

2.包装类型:

public class RequestDTO{//用于接收参数列表的listprivate List<Course> courses;public List<Course> getCourses() {return courses;}public void setCourses(List<Course> courses) {this.courses = courses;}public RequestDTO(List<Course> courses) {this.courses = courses;}
}

3.handler方法:

@RequestMapping("/updateCourses")
public String updateCourses(RequestPack data){courseService.updateCourses(data.getCourses());return "/getCourses";
}

4.service方法:

public void updateCourses(List<Course> courses) {for (Course course:courses){courseMapper.updateByPrimaryKey(course);}
}

强调:list只能映射到包装类型中,无法直接映射到handler参数上

错误案例:

@RequestMapping("/updateCourses")
public String updateCourses(RequestPack data, ArrayList<Course> courses){courseService.updateCourses(data.getCourses());return "/getCourses";
}

文件上传

文件上传是web项目中非常常见的需求,SpringMVC使用了apache开源的两个库用于处理文件上传,所以在编写代码前我们需要先导入下面两个依赖包:

<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency><dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>

假设需要实现一个上传图片的功能,需要现在数据库中添加一个字段用于存储图片的路径,同时不要忘记修改pojo以及mapper文件,使之与数据库字段对应.

1.页面增加input 用于提交文件,并修改表单的enctype为multipart/form-data

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head></head>
<form action="updateCourse" method="post" enctype="multipart/form-data"><input name="id" value="${course.id}" hidden="hidden"/>名称:<input name="name" value="${course.name}"/><br/>讲师:<input name="teachName" value="${course.teachName}"/><br/><input name="startTime" type="date" value='<fmt:formatDate value="${course.startTime}" pattern="yyyy-MM-dd"/>'/><br/>学分:<input name="score" type="number" value="${course.score}"/><br/>课时:<input name="hours" type="number" value="${course.hours}"/><br/><c:if test="${course.pic != null}"><img src="${pageContext.servletContext.contextPath}${course.pic}" style="width: 100px;height: 100px"></c:if>图片:<input name="picFile" type="file"/><br/> <!-- 新增input--><br/><input type="submit"></form>
<body>
</body>
</html>

2.在mvc配置文件中添加multipart解析器,(页面上传文件都是以,multipart编码方式)

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>

3.handler方法中添加MultipartFile类型的参数

@RequestMapping("/updateCourse")
public String updateCourse(Course course, MultipartFile picFile) throws IOException {/**** 1.获得文件,取出文件后缀* 2.生成唯一标识,* 3.写入文件到指定路径* 4.存储文件路径到数据库*/System.out.println(picFile.getName());String suffix = picFile.getOriginalFilename().substring(picFile.getOriginalFilename().lastIndexOf("."));String fileName = UUID.randomUUID() + suffix;String basepath = "D:/java_file/SSMUseDemo/src/main/webapp/image/" + filename;picFile.transferTo(new File(basepath));course.setPic("/images/"+fileName);courseService.update(course);return  "/getCourses";
}

注意:实际开发中都是存储到文件服务器,不会放在项目里

4.静态资源处

若web.xml中DispatcherServlet的URLmapping 为/ 则还需要在SpringMVC中添加静态资源配置

<!--开启注解 -->
<mvc:annotation-driven />
<!-- 配置静态资源 -->
<mvc:resources mapping="/images/**" location="/images/"/>
<!--当请求地址为/images/开头时(无论后面有多少层目录),作为静态资源 到/images/下查找文件-->

若URLMapping为*.action 或类似其他的时则无需处理,因为Tomcat会直接查找webapp下的资源,不会交给DispatcherServlet

但是上面会有问题,就是上传的时候,无法及时显示,因为在项目中文件增加了,需要重新编译,建议location设置一个外部路径,或使用下面的方法配置资源路径

在tomcat里配置:

请求限制

一些情况下我们可能需要对请求进行限制,比如仅允许POST,GET等…

RequestMapping注解中提供了多个参数用于添加请求的限制条件

  • value 请求地址
  • path 请求地址
  • method 请求方法
  • headers 请求头中必须包含指定字段
  • params 必须包含某个请求参数
  • consumes 接受的数据媒体类型 (与请求中的contentType匹配才处理)
  • produce 返回的媒体类型 (与请求中的accept匹配才处理)

案例:

@RequestMapping(value = "/editCourse",method = RequestMethod.POST,headers = {"id"},params = {"name"},consumes = {"text/plain"})

为了简化书写,MVC还提供了集合路径和方法限制的注解,包括常见的请求方法:

PostMapping
GetMapping
DeleteMapping
PutMapping如:
@PostMapping("/editCourse")

链接:SpringMVC返回类型

SpringMVC 参数映射与文件上传相关推荐

  1. SpringMVC数据校验、文件上传

    SpringMVC数据校验.文件上传 首先在此鸣谢所有本篇博客涉及技术给予我指导的导师,朋友! 目录: 1.文件上传流程: 2.数据校验: 3.本试验遇到的报错问题及解决办法: 4.Java文件源代码 ...

  2. SpringMVC处理Json、文件上传、拦截器

    SpringMVC处理Json.文件上传.拦截器 : 处理JSON 链接 http://repo1.maven.org/maven2/com/fasterxml/jackson/core/ 步骤 编写 ...

  3. java实现excel文件上传_java相关:SpringMVC下实现Excel文件上传下载

    java相关:SpringMVC下实现Excel文件上传下载 发布于 2020-6-21| 复制链接 摘记: 在实际应用中,经常会遇到上传Excel或者下载Excel的情况,比如导入数据.下载统计数据 ...

  4. springmvc 采用MultipartResolver进行文件上传

    springmvc 采用MultipartResolver解析文件上传请求,利用MultipartFile来进行接收文件,使服务器文件接收和保存变得异常方便. public interface Mul ...

  5. SpringMVC之CRUD和文件上传下载

    目录 一.CRUD(增删改查) 1.导入pom依赖 2.框架配置文件 3.web.xml 4.工具类(分页) 4.增删改查 二.图片上传 1.步骤 2.导pom依赖 3.springmvc-servl ...

  6. 初学SpringMVC,使用MVC进行文件上传

    最近在做一个文件上传的功能,走了不少弯路,话不多说,直接上代码: 导入各种jar包,首先是applicationContext.xml配置文件中: 1 <!-- 配置文件解析器 --> 2 ...

  7. SpringMVC +layui 实现多文件上传,附加进度条

    首先在进行文件上传操作的时候,你得对layui 中文件上传的一些参数先了解一下,不要网上复制粘贴,起码你要对layui 文件上传的必备参数做一些大致掌握,也是自己学习. (1) 首先你得引入layui ...

  8. springmvc二十八:springmvc使用common-fileUpload实现文件上传

    springmvcjar包  commons-fileupload-1.2.1,commons-io-1.3.2 前台: <form action="hello" metho ...

  9. JQuery与springmvc实现多个文件上传操作

    1. 导入JQuery相关JS文件 <script src="<@full_path path="js/jquery.js"/>" type= ...

最新文章

  1. 使用$.post和$.get向服务器发送请求
  2. php+数学计算公式,PHP数学计算函数总结
  3. 正则表达式入门之位置匹配
  4. 1592E - Скучающий Бакри
  5. VB输入文本文件实现右对齐
  6. Java UDP小结
  7. ajax 详解(GET,POST方式传输以其封装)
  8. JAVA收到网络报文的IP是::1,怎么回事?
  9. autocoder自动代码生成器_Spring Boot 集成MyBatis Plus代码生成器
  10. 算法:在有序的链表中删除掉所有重复的数据(包括重复本身的节点)Remove Duplicates from Sorted List II
  11. 按性别分类进行描述统计(SPSS操作)
  12. 网络 | 1.OSI七层模型各层常见协议
  13. 最新版!国内IT软件外包公司汇总~
  14. 在线网校教育平台的开发,题库的搭建必不可少
  15. 【黑客攻防技术宝典】第4章 解析应用程序
  16. python的Firebird驱动:FDB使用说明
  17. 解决winscp中普通用户无法上传、删除、移动文件
  18. ios开发app瘦身
  19. 【学术交流】计算机国际会议中proceedings,conference,paper,workshop,demo的都是什么意思
  20. 入秋这么穿,没人比你更优雅

热门文章

  1. 【数据结构】-大二数据结构与算法课程设计实训报告
  2. Atmel推出业内首款面向智能能源和自动化应用的IEEE 802.15.4g-2012双频段收发器
  3. 学计算机语言的最佳年龄,孩子学编程最佳年龄是几岁
  4. input 限制输入2位小数
  5. 利用JavaScript实现简单的点名表
  6. DRM系列(11)之VIV IOCTLS
  7. json数据和本地存储
  8. IAR修改工程名方法
  9. 闹市里的宁静一隅,乡村慢生活#观澜山水田园文化旅游园
  10. Ubuntu 14.04 安装Draftsight