1 前言

在史上最简单的 Spring MVC 教程(五、六、七、八)等四篇博文中,咱们已经分别实现了“人员列表”的显示、添加、修改和删除等常见的增、删、改、查功能。接下来,也就是在本篇博文中,咱们在继续实现新的功能,即:上传图片和显示图片。

2 注解示例 - 上传及显示图片

老规矩,首先给出项目结构图:

2.1 显示图片

第一步:修改 web.xml 文件,拦截所有的 URL

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"><!-- 配置 Spring 框架 --><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:beans.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- 配置 DispatcherServlet,对所有后缀为action的url进行过滤 --><servlet><servlet-name>action</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!-- 修改 Spring MVC 配置文件的位置和名称 --><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:springmvc-servlet.xml</param-value></init-param></servlet><servlet-mapping><servlet-name>action</servlet-name><url-pattern>/</url-pattern>  <!-- 拦截所有的 URL --></servlet-mapping><welcome-file-list> <welcome-file>index.jsp</welcome-file></welcome-file-list></web-app>

第二步:修改 springmvc-servlet.xml 文件,增加静态资源的管理

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-3.2.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.2.xsd "><!-- 声明注解开发方式 --><mvc:annotation-driven/><!-- 静态资源的管理 --><mvc:resources location="/upload/" mapping="/upload/**"/><!-- 包自动扫描 --><context:component-scan base-package="spring.mvc.controller"/><!-- 内部资源视图解析器,前缀 + 逻辑名 + 后缀 --><bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/pages/"/><property name="suffix" value=".jsp"/></bean>
</beans>

第三步:修改 web 目录下的 index.jsp 页面,增加跳转链接及显示图片

<%--Created by IntelliJ IDEA.User: 维C果糖Date: 2017/1/29Time: 21:25To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><meta http-equiv="content-type" content="text/html; charset=UTF-8"><title>Spring MVC</title>
</head>
<body>
This is my Spring MVC!<br><a href="${pageContext.request.contextPath}/person/all.action">显示人员列表</a><img src="${pageContext.request.contextPath}/upload/SoCuteCat.jpg">
</body>
</html>

在完成以上步骤后,启动 tomcat 服务器,默认访问 http://localhost:8080/springmvc-annotation/,页面如下所示:

然后,点击“显示人员列表”,将访问 http://localhost:8080/springmvc-annotation/person/all.action,页面如下所示:

额外提示:在大型网站的框架中,常见的配置是动态资源和静态资源分别解析,主要有两种选择,分别是

  • 第一种:Apache + tomcats(集群)
  • 第二种:Nginx + tomcats(集群)

其中,Apache 和 Nginx 是负责负载均衡,即平均分配资源,同时用它们来解析静态资源,例如 JavaScript、CSS 和 Image 等;tomcat 集群负责动态资源的解析,例如 jsp 和 action 等。至于为什么会衍生出用 Nginx 代替 Apache 的第二种方案,主要是因为 Nginx 的处理速度是 Apache 的 100 倍。

2.2 上传图片

第一步:修改实体类(Person),添加图片存储路径的字段

package spring.mvc.domain;/*** Created by 维C果糖 on 2017/1/30.*/public class Person {private Integer id;private String name;private Integer age;private String photoPath;  // 图片存储路径public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}public String getPhotoPath() {return photoPath;}public void setPhotoPath(String photoPath) {this.photoPath = photoPath;}@Overridepublic String toString() {return "Person{" +"id=" + id +", name='" + name + '\'' +", age=" + age +'}';}
}

第二步:修改控制器(PersonController)中的 updatePersonList 方法

package spring.mvc.controller;import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import spring.mvc.domain.Person;
import spring.mvc.service.PersonService;import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;/*** Created by 维C果糖 on 2017/1/26.*/@Controller
public class PersonController {@ResourcePersonService ps;    // 注入 service 层@RequestMapping(value = "/person/all")public String findAll(Map<String, Object> model) {     // 声明 model 用来传递数据List<Person> personList = ps.findAll();model.put("personList", personList);              // 通过这一步,JSP 页面就可以访问 personListreturn "/person/jPersonList";                    // 跳转到 jPersonList 页面}@RequestMapping("/person/toCreatePersonInfo")public String toCteatePersonInfo() {  // 跳转新增页面return "/person/jPersonCreate";}@RequestMapping("/person/toUpdatePersonInfo")public String toUpdatePersonInfo(Integer id, Model model) {  // 跳转修改页面Person p = ps.get(id);             // 获得要修改的记录,重新设置页面的值model.addAttribute("p", p);         // 将数据放到 responsereturn "/person/jPersonUpdate";}@RequestMapping("/person/updatePersonList")public String updatePersonList(HttpServletRequest request, Person p, @RequestParam("photo") MultipartFile photeFile) throws IOException {  // 更新人员信息if (p.getId() == null) {ps.insert(p);   // 调用 Service 层方法,插入数据} else {String dir = request.getSession().getServletContext().getRealPath("/") + "/upload/";String fileName = photeFile.getOriginalFilename();                  // 原始的文件名String extName = fileName.substring(fileName.lastIndexOf("."));     // 扩展名fileName = fileName.substring(0, fileName.lastIndexOf(".")) + System.nanoTime() + extName;     // 防止文件名冲突FileUtils.writeByteArrayToFile(new File(dir + fileName), photeFile.getBytes());                // 写文件到 upload 目录p.setPhotoPath("/upload/" + fileName);ps.update(p);   // 调用 Service 层方法,更新数据}return "redirect:/person/all.action";        // 转向人员列表 action}@RequestMapping("/person/deleteById")public String deleteById(Integer id) {  // 删除单条记录ps.deleteById(id);return "redirect:/person/all.action";        // 转向人员列表 action}@RequestMapping("/person/deleteMuch")public String deleteMuch(String id) {  // 批量删除记录for (String delId : id.split(",")) {ps.deleteById(Integer.parseInt(delId));}return "redirect:/person/all.action";        // 转向人员列表 action}
}

第三步:在 jPersonUpdate.jsp 中添加 Spring 框架的标签,并重新配置 form 表单

<%--Created by IntelliJ IDEA.User: 维C果糖Date: 2017/1/30Time: 18:00To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="sf" %>
<html>
<head><meta http-equiv="content-type" content="text/html; charset=UTF-8"><title>PersonList</title>
</head>
<body><!-- 其中,modelAttribute 属性用于接收设置在 Model 中的对象,必须设置,否则会报 500 的错误 -->
<sf:form enctype="multipart/form-data"action="${pageContext.request.contextPath}/person/updatePersonList.action"modelAttribute="p"method="post"><sf:hidden path="id"/><div style="padding:20px;">修改人员信息</div><table><tr><td>姓名:</td><td><sf:input path="name"/></td></tr><tr><td>年龄:</td><td><sf:input path="age"/></td></tr><tr><td>图片:</td><td><input type="file" name="photo" value=""/></td></tr><tr><td colspan="2"><input type="submit" name="btnOK" value="保存"/></td></tr></table>
</sf:form></body>
</html>

第四步:修改 jPersonList.jsp 页面,添加头像显示栏

<%--Created by IntelliJ IDEA.User: 维C果糖Date: 2017/1/30Time: 18:20To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core"   prefix="c" %>
<html>
<head><meta http-equiv="content-type" content="text/html; charset=UTF-8"><title>PersonList</title><script language="JavaScript">/*** 批量提交方法*/function deleteMuch() {document.forms[0].action = "${pageContext.request.contextPath}/person/deleteMuch.action";document.forms[0].submit();  <!-- 手动提交 -->}</script>
</head>
<body><form method="post"><div style="padding:20px;"><h2>人员列表</h2></div><div style="padding-left:40px;padding-bottom: 10px;"><a href="/springmvc-annotation/person/toCreatePersonInfo.action">新增</a>   <!-- 跳转路径 --><a href="#" onclick="deleteMuch()">批量删除</a>   <!-- 调用 JavaScript --></div><table border="1"><tr><td>选择</td><td>头像</td><td>编号</td><td>姓名</td><td>年龄</td><td>操作</td></tr><c:forEach items="${personList}" var="p"><tr><td><input type="checkbox" name="id" value="${p.id}"/></td><td><img src="${pageContext.request.contextPath}${p.photoPath}"/></td><td>${p.id}</td><td>${p.name}</td><td>${p.age}</td><td><a href=/springmvc-annotation/person/toUpdatePersonInfo.action?id=${p.id}>修改</a><a href=/springmvc-annotation/person/deleteById.action?id=${p.id}>删除</a></td></tr></c:forEach></table></form></body>
</html>

第五步:在 springmvc-servlet.xml 中配置“文件上传视图解析器”

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:mvc="http://www.springframework.org/schema/mvc"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-3.2.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.2.xsd "><!-- 声明注解开发方式 --><mvc:annotation-driven/><!-- 静态资源的管理 --><mvc:resources location="/upload/" mapping="/upload/**"/><!-- 包自动扫描 --><context:component-scan base-package="spring.mvc.controller"/><!-- 内部资源视图解析器,前缀 + 逻辑名 + 后缀 --><bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"><property name="prefix" value="/WEB-INF/pages/"/><property name="suffix" value=".jsp"/></bean><!-- 文件上传视图解析器,其名字必须为 multipartResolver --><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><property name="maxUploadSize" value="10485760"/>   <!-- 限制页面上传文件最大为 10M --></bean>
</beans>

在完成以上步骤后,启动 tomcat 服务器,然后访问 http://localhost:8080/springmvc-annotation/person/all.action,页面如下所示:

然后,以编号为 0 的记录为例,进行测试,点击“修改”,页面如下所示:

接下来,点击“选择文件”,进而选择咱们想要设置为头像的图片,点击“保存”,页面如下所示:

至此,图像的上传及显示功能,全部实现成功。


———— ☆☆☆ —— 返回 -> 史上最简单的 Spring MVC 教程 <- 目录 —— ☆☆☆ ————

史上最简单的 Spring MVC 教程(九)相关推荐

  1. 史上最简单的Spring Security教程(十九):AccessDecisionVoter简介及自定义访问权限投票器

    为了后续对 AccessDecisionManager 的介绍,我们先来提前对 AccessDecisionVoter 做个简单的了解,然后,在捎带手自定义一个 AccessDecisionVoter ...

  2. microsoftsql新建登录用户登录失败_史上最简单的Spring Security教程(九):自定义用户登录失败页面...

    生活中肯定存在这样的场景,在登录某个网站时,难免会忘记密码,或是验证码输入错误,造成多次尝试.所以,有必要适度的提醒用户,到底是什么原因造成了登录失败,如用户名密码不正确.验证码错误等等.由于 Spr ...

  3. 史上最简单的Spring Security教程(二十八):CA登录与默认用户名密码登录共存详细实现及配置

    ​在前面的文章中,我们自定义了一些CA登录相关的类,如 CertificateAuthorityAuthenticationToken.CertificateAuthorityAuthenticati ...

  4. 史上最简单的Spring Security教程(八):用户登出成功LogoutSuccessHandler高级用法

    ​大多数业务场景下,自定义登出成功页面也满足不了一些要求,更别提默认的登出成功页面.这时候,就需要别的方案支持,幸运的是,Spring Security 框架还真就非常贴心的提供了这样一个接口 Log ...

  5. 史上最简单的spark系列教程 | 完结

    <史上最简单的spark系列教程>系列: 与其说是教程不如说是改良后的个人学习笔记|| 教程参考自:<spark官方文档>,<spark快速分析>,<图解Sp ...

  6. 2010年史上最简单的做母盘教程

    2010年史上最简单的做母盘教程 辛苦了两个小时才把教程写完....写得不好大家多多包涵 其实做母盘是一件十分简单的事,只要大家敢去试就能成功的,这教程只给小白看的,老鸟路过指点一下. 本人是珠海信佑 ...

  7. 如何在 CSDN 中增加博客访问量 史上最简单的博客教程 学会之后博客访问量直线上升。

    蹭热度 如何蹭是问题.下面分几点 你发布的有关技术是什么 你发布的是否是别人发布过的东西 你发布的东西在别人是怎样搜索的. 其实重点在流量,也就是点击.点击到位了,无论你文章来自哪里,或者说抄自哪里, ...

  8. php后端mvc框架,GitHub - Tokyo-Lei/Amaya: 史上最简单的PHP MVC框架!首先你了解MVC和COMPOSER就行!...

    Amaya PHP Framework 基于Composer完成的MVC框架,自从有了依赖变成史上最最最简单的MVC! 此框架依赖第三方库: Medoo 数据库 twig 模版引擎 whoops 调式 ...

  9. 史上最简单的Git入门教程

    1. 版本控制系统简介 1.1 何为版本控制 版本控制最主要的功能就是追踪文件的变更.它将什么时候.什么人更改了文件的什么内容等信息忠实地了已录下来.每一次文件的改变,文件的版本号都将增加.除了记录版 ...

最新文章

  1. 【ZZ】编程能力层次模型
  2. VISP视觉库框架结构与使用入门
  3. php和python哪个工资高-python和php哪个更有前景
  4. 安卓手机管理器_电脑文件快速搜索有everything,那手机呢?
  5. 2018-2019-2 20165212《网络攻防技术》Exp5 MSF基础应用
  6. 最简单的Asp.Net 2.0 TreeView的Checkbox级联操作
  7. Android开发中,怎样调用摄像机拍照以及怎样从本地图库中选取照片
  8. H桥和NMOS,PMOS理解
  9. libcef-Vs2017-下载编译第一个libcef3项目
  10. 计算机设备管理没有打印机,win7电脑的设备和打印机选项无法打开怎么办?
  11. python输入球的半径_python程序设计:输入球体半径r,计算球体的体积和表面积
  12. C++语言程序设计(第4版)郑莉练习
  13. Windows 10 使用小鹤双拼
  14. Spark rdd之sortBy
  15. Win2008 r2 远程桌面授权已过期的解决办法
  16. java对excel的操作
  17. JS检测是否有企业微信应用程序
  18. 使用scala将数据写入linux上的MongoDB数据库
  19. Schrodinger 功能模块简介
  20. 卸载自装python

热门文章

  1. 修改注册表,加快开机速度
  2. git提交报错: vue-cli-service lint found some errors. Please fix them and try committing again
  3. 项目经理的商务指南系列之四:认识谈判(不做传声筒,不做顶门闩,进退之策,进退之法,有机事者必有机心)
  4. Java程序员入门技术大全V1(十三) -- 开发工具之设计工具
  5. BPR实施中常用的五大手法
  6. 如何从零开始学计算机的英语单词,如何把英语从零开始
  7. 正雅GS隐形牙套,减少拔牙概率
  8. raspberry zero w 系统安装及ssh配置
  9. Docker 使用超详细 (精通级)
  10. 如何在字符串中加入回车换行,tab字符 关于字符串处理