JavaEE企业级应用开发教程实验十一Spring MVC的高级功能

实验十一:Spring MVC的高级功能

一、实验目的

1.熟悉Spring MVC异常的统一处理

2.掌握自定义拦截器的使用

3.掌握文件上传和文件下载操作

二、实验内容

1.简单异常处理器、自定义异常处理器、异常处理注解、拦截器的配置实现

2.文件上传、文件下载应用

三、实验步骤

1.简单异常处理器、自定义异常处理器、异常处理注解、拦截器的配置实现

(1)简单异常处理器

① 创建ExceptionController.java类

在src\main\java文件夹中创建com\sun\controller文件夹,并创建ExceptionController类

package com.sun.controller;
导入相关包......
public class ExceptionController {
    @RequestMapping("/showNullPointer")
    public void showNullPointer(){
        ArrayList<Object>list=null;
        System.out.println(list.get(2));
    }
    @RequestMapping("/showIOException")
    public void showIOException() throws IOException{
        FileInputStream in=new FileInputStream("JavaWeb.xml");
    }
    @RequestMapping("/showArithmetic")
    public void showArithmetic(){
        int c=1/0;
    }
}

② 配置spring-mvc.xml

在src\main\resources文件夹中创建spring-mvc.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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <context:component-scan base-package="com.sun.controller"/>
    <mvc:annotation-driven/>
    <mvc:resources mapping="/js/**" location="/js/"/>
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <property name="exceptionMappings">
            <props>
                <prop key="java.lang.NullPointerException">
                    nullPointerExp.jsp
                </prop>
                <prop key="IOException">IOExp.jsp</prop>
            </props>
        </property>
        <property name="defaultErrorView" value="defaultExp.jsp"></property>
        <property name="exceptionAttribute" value="exp"></property>
    </bean>
</beans>

③ 创建nullPointerExp.jsp

在src\main\webapp文件夹中创建nullPointerExp.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>空指针异常处理页面</title>
</head>
<body>
空指针异常处理页面----${exp}
</body>
</html>

④ 创建IOExp.jsp

在src\main\webapp文件夹中创建IOExp.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>IO异常处理页面</title>
</head>
<body>
IO异常处理页面-----${exp}
</body>
</html>

⑤ 创建defaultExp.jsp

在src\main\webapp文件夹中创建defaultExp.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>默认异常处理页面</title>
</head>
<body>
默认异常处理页面-----${exp}
</body>
</html>

运行结果:

启动项目后在浏览器输入http://localhost:8090/sy_ch11/showNullPointer

启动项目后在浏览器输入http://localhost:8090/sy_ch11/showIOException

启动项目后在浏览器输入http://localhost:8090/sy_ch11/showArithmetic

(2)自定义异常处理器

① 创建自定义异常类

在src\main\java文件夹中创建com\sun\exception文件夹,并创建自定义异常类

package com.sun.exception;
public class MyException extends Exception{
    private String message;
    public MyException(String message) {
        super(message);
        this.message = message;
    }
    @Override
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
}

② 修改ExceptionController.java类

在ExceptionController.java类中添加

@RequestMapping("/addData")
public void addData() throws MyException {
    throw new MyException("新增数据异常!");
}

③ 创建自定义异常处理器

在src\main\java\com\sun\controller文件夹下创建创建MyExceptionHandler类

package com.sun.controller;
导入相关包....
@Controller
public class MyExceptionHandler implements HandlerExceptionResolver {
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        String msg;
        if (ex instanceof MyException) {
            msg = ex.getMessage();
        } else {
            Writer out = new StringWriter();
            PrintWriter s = new PrintWriter(out);
            ex.printStackTrace(s);
            String sysMsg = out.toString();
            msg = "网络异常!";
        }
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("msg", msg);
        modelAndView.setViewName("error.jsp");
        return modelAndView;
    }
}

④ 创建异常处理页面

在src\main\webapp文件夹下创建error.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>异常处理页面</title>
</head>
<body>
${msg}
</body>
</html>

运行结果:

启动项目后在浏览器输入http://localhost:8090/sy_ch11/showNullPointer

启动项目后在浏览器输入http://localhost:8090/sy_ch11/addData

(3)异常处理注解

① 创建异常处理器

在src\main\java\com\sun\controller文件夹下创建ExceptionAdvice

package com.sun.controller;
导入相关包....
@Controller
public class ExceptionAdvice {
    @ExceptionHandler(MyException.class)
    public ModelAndView doMyException(MyException ex) throws IOException {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("msg", ex.getMessage());
        modelAndView.setViewName("error.jsp");
        return modelAndView;
    }
    @ExceptionHandler(Exception.class)
    public ModelAndView doOtherException(Exception ex) throws IOException {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("msg", "网络异常!");
        modelAndView.setViewName("error.jsp");
        return modelAndView;
    }
}

运行结果:

启动项目后在浏览器输入http://localhost:8090/sy_ch11/showNullPointer

启动项目后在浏览器输入http://localhost:8090/sy_ch11/addData

(4)拦截器的配置实现

① 创建实体类

在src\main\java文件夹下创建com\sun\pojo文件夹,并创建User类

package com.sun.pojo;
public class User {
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    private String username;
    private String password;
}

② 创建控制器类

在src\main\java\com\sun\controller文件夹下创建创建控制器UserController类

package com.sun.controller;
导入相关包.....
@Controller
public class UserController {
    @RequestMapping("/main")
    public String toMainPage() {
        return "main";
    }
    @RequestMapping("/tologin")
    public String toLoginPage() {
        return "login";
    }
    @RequestMapping("/orderinfo")
    public String orderinfo() {
        return "orderinfo";
    }
    @RequestMapping("/login")
    public String login(User user, Model model, HttpSession session) {
        String username = user.getUsername();
        String password = user.getPassword();
        if (username != null && username.equals("sunhaaonan") && password != null && password.equals("123456")) {
            session.setAttribute("USER_SESSION", user);
            return "main";
        }
        model.addAttribute("msg", "用户名或密码错误,请重新登录!");
        return "login";
    }
    @RequestMapping("/logout")
    public String logout(HttpSession session) {
        session.invalidate();
        return "redirect:tologin";
    }
}

③ 创建拦截器

在src\main\java文件夹下创建com\sun\interceptor文件夹,并创建拦截器 LoginInterceptor

package com.sun.intercepto;
导入相关包.....
public class LoginInterceptor extends HandlerInterceptorAdapter {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String uri = request.getRequestURI();
        if (uri.indexOf("/login") >= 0) {
            return true;
        }
        HttpSession session = request.getSession();
        if (session.getAttribute("USER_SESSION") != null) {
            return true;
        }
        request.setAttribute("msg", "您还没有登录,请先登录!");
        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
        return false;
    }
}

④ 配置spring-mvc.xml

在spring-mvc.xml文件中添加

<context:component-scan base-package="com.sun.controller"/>
<mvc:annotation-driven/>
<mvc:resources mapping="/js/**" location="/js/"/>

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <property name="suffix" value=".jsp"/>
</bean>
<mvc:interceptors>
    <bean class="com.sun.interceptor.LoginInterceptor"/>
</mvc:interceptors>

⑤ 创建main.jsp

在src\main\webapp\WEB-INF文件夹下创建jsp文件夹,并创建main.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>后台系统</title>
</head>
<body>
    <li>您好:${ USER_SESSION.username }</li>
    <li><a href="${ pageContext.request.contextPath }/logout">退出</a></li>
    <li><a href="${ pageContext.request.contextPath }/orderinfo">订单信息</a></li>
</body>
</html>

⑥ 创建login.jsp

在src\main\webapp\WEB-INF\jsp文件夹下创建login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>用户登录</title>
</head>
<body>
    <form action="${pageContext.request.contextPath }/login" method="POST">
        <div>${msg}</div>
        用户名:<input type="text" name="username"/><br/>
        密  码:<input type="password" name="password"/><br/>
        <input type="submit" value="登录"/>
</form>
</body>
</html>

⑦ 创建orderinfo.jsp

在src\main\webapp\WEB-INF\jsp文件夹下创建orderinfo.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>订单信息</title>
</head>
<body>
    您好:${ USER_SESSION.username }
    <a href="${ pageContext.request.contextPath }/logout">退出</a>
    <table border="1" width="80%">
        <tr align="center">
            <td colspan="2">订单id:D001</td>
        </tr>
        <tr align="center">
            <td>商品Id</td>
            <td>商品名称</td>
         </tr>
        <tr align="center">
            <td>P001</td>
            <td>三文鱼</td>
        </tr>
        <tr align="center">
            <td>P002</td>
            <td>红牛</td>
        </tr>
    </table>
</body>
</html>

运行结果:

启动项目后在浏览器输入http://localhost:8090/sy_ch11/main

启动项目后在浏览器输入http://localhost:8090/sy_ch11/orderinfo

不填写任何信息点击“登录”:

登录后:

点击“订单信息”

点击“退出”:

2.文件上传、文件下载应用

(1)搭建文件上传和下载的环境

① 在项目的pom.xml中引入相关依赖

<dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.4</version>
    </dependency>
    <dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.2</version>
</dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.2</version>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.9.0</version>
    </dependency>

② 配置spring-mvc.xml

<bean id="multipartResolver" class="org.springframework.

web.multipart.commons.CommonsMultipartResolver">
    <property name="defaultEncoding" value="UTF-8"/>
    <property name="maxUploadSize" value="2097152"/>
</bean>

(2)实现文件上传功能

① 文件存放准备

在webapp文件夹下创建名为files文件夹,用于存放上传成功的文件和上传成功的文件记录。上传成功的记录文件中的数据以JSON格式存放。在files文件夹中创建files.json记录文件

② 创建资源类

在src\main\java\com\sun\pojo文件夹中创建与file.json内容对应的资源类Resource

package com.sun.pojo;
public class Resource {
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    private String name;
    public Resource(){}
    public Resource(String name){
        this.name=name;
    }
}

③ 创建工具类

在src\mian\java文件夹中,创建文件夹com\sun\utils并创建工具类JSONFileUtils

package com.sun.utils;
import org.apache.commons.io.IOUtils;
import java.io.FileInputStream;
import java.io.FileOutputStream;

public class JSONFileUtils {
    public static String readFile(String filepath) throws Exception {
        FileInputStream fis = new FileInputStream(filepath);
        return IOUtils.toString(fis);
    }
    public static void writeFile(String data, String filepath)
            throws Exception { FileOutputStream fos = new FileOutputStream(filepath);
        IOUtils.write(data, fos);
    }
}

④ 创建控制类

在src\main\java\com\sun\controller文件夹下创建控制类FileController

package com.sun.controller;
导入相关包.....
@Controller

public class FileController {
    @RequestMapping("/fileUpLoad")
    public String fileLoad(MultipartFile[] files, HttpServletRequest request) throws Exception {
        String path = request.getServletContext().getRealPath("/") + "files/";
        ObjectMapper mapper = new ObjectMapper();
        if (files != null && files.length > 0) {
            for (MultipartFile file : files) {
                String filename = file.getOriginalFilename();
                ArrayList<Resource> list = new ArrayList<>();
                String json = JSONFileUtils.readFile(path + "/files.json");
                if (json.length() != 0) {
                    list = mapper.readValue(json,
                            new TypeReference<List<Resource>>() {
                            });
                    for (Resource resource : list) {
                        if (filename.equals(resource.getName())) {
                            String[] split = filename.split("\\.");
                            filename = split[0] + "(1)." + split[1];
                        }
                    }
                }
                String filePath = path + filename;
                file.transferTo(new File(filePath));
                list.add(new Resource(filename));
                json = mapper.writeValueAsString(list);
                JSONFileUtils.writeFile(json, path + "/files.json");
            }
            request.setAttribute("msg", "(上传成功)");
            return "forward:fileload.jsp";
        }
        request.setAttribute("msg", "(上传失败)");
        return "forward:fileload.jsp";
    }
}

(3)实现获取文件列表功能

在控制类FileController中添加getFilesName()方法

@ResponseBody
@RequestMapping(value = "/getFilesName", produces = "text/html;charset=utf-8")
public String getFilesName(HttpServletRequest request, HttpServletResponse response) throws Exception {
    String path = request.getServletContext().getRealPath("/") + "files/files.json";
    String json = JSONFileUtils.readFile(path);
    return json;
}

(4)编写文件上传和下载页面

在webapp文件夹下创建fileload.jsp文件作为文件上传和下载页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>文件上传和下载</title>

<script src="${ pageContext.request.contextPath }/js/jquery-3.6.0.js"

type="text/javascript"></script>
</head>
<body>
    <table border="1">
        <tr>
            <td width="200" align="center">文件上传${msg}</td>
            <td width="300" align="center">下载列表</td>
        </tr>
        <tr>
            <td height="100">
                <form action="${pageContext.request.contextPath}/fileload" method="post" enctype="multipart/form-data">
                    <input type="file" name="files" multiple="multiple"><br/>
                    <input type="reset" value="清空"/>
                    <input type="submit" value="提交"/>
                </form>
            </td>
            <td id="files"></td>
        </tr>
    </table>
</body>
    <script>
        $(document).ready(function () {
            var url = "${pageContext.request.contextPath }/getFilesName";
            $.get(url, function (files) {
                var files = eval('(' + files + ')');
                for (var i = 0; i < files.length; i++) {
                    $("#files").append("<li><a href=${pageContext.request.contextPath }\\download?filename=" + files[i].name + ">" + files[i].name + "</a></li>");
                }
            })
        })
    </script>
</html>

运行结果:

启动项目后在浏览器输入http://localhost:8090/sy_ch11/fileload.jsp

单击“选择文件”按钮:

同时选择两个文件:

单击“打开”按钮:

单击“提交”按钮:

文件上传成功后查看项目files

双击打开files.json文件

(5)实现文件下载

① 对浏览器的编码方式进行设置

在控制类FileController中添加getFileName()方法

public String getFileName(HttpServletRequest request, String filename) throws Exception {
    BASE64Encoder base64Encoder = new BASE64Encoder();
    String agent = request.getHeader("User-Agent");
    if (agent.contains("Firefox")) {
        filename = "=?UTF-8?B?" + new String
                (base64Encoder.encode(filename.getBytes("UTF-8"))) + "?=";
    } else {
        filename = URLEncoder.encode(filename, "UTF-8");
    }
    return filename;
}

② 新增下载文件方法

在控制类FileController中添加fileDownload()方法
 

@RequestMapping("/download")
public ResponseEntity<byte[]> fileDownload(HttpServletRequest request, String filename) throws Exception {
    String path = request.getServletContext().getRealPath("/files/");
    filename = new String(filename.getBytes("ISO-8859-1"), "UTF-8");
    File file = new File(path + File.separator + filename);
    HttpHeaders headers = new HttpHeaders();
    filename = this.getFileName(request, filename);
    headers.setContentDispositionFormData("attachment", filename);
    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file), headers, HttpStatus.OK);
}

运行结果:

点击文件的超链接弹出对话框

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小孙同学1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值