美文网首页
史上最简单的 Spring MVC 教程(九)

史上最简单的 Spring MVC 教程(九)

作者: 李序锴 | 来源:发表于2018-01-19 16:31 被阅读0次

    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/javaee http://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/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/context http://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/29 Time: 21:25 To 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;
        }
    
        @Override
        public 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 {
        @Resource
        PersonService ps;    // 注入 service 层
    
        @RequestMapping(value = "/person/all")
        public String findAll(Map<String, Object> model) {     // 声明 model 用来传递数据
            List<Person> personList = ps.findAll();
            model.put("personList", personList);              // 通过这一步,JSP 页面就可以访问 personList
            return "/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);         // 将数据放到 response
            return "/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/30 Time: 18:00 To 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/30 Time: 18:20 To 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/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/context http://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 教程(九)

          本文链接:https://www.haomeiwen.com/subject/rhoooxtx.html