Java学习笔记08 ── SpringMVC(处理静态资源、处理JSON、文件上传和文件下载、拦截器)

处理静态资源

在SpringMVC中加载静态资源(例如js、css、图片)等会出现失败,这里就需要来处理一下这些静态资源。这里有两个servlet,一个是默认的servlet(DefaultServlet),另外一个是开发人员配置的servlet。我们需要配置使请求过来了以后先经过因此DispatcherServlet处理请求,找该请求是否有相对应的处理器,有则处理,无则交给DefaultServlet处理。只需要在SpringMVC的配置文件中加上下面的内容即可。

            <!--解决静态资源的问题-->
            <mvc:default-servlet-handler/>
            <mvc:annotation-driven />

处理JSON

1.加入jar包
jackson-annotations-2.1.5.jar
jackson-core-2.1.5.jar
jackson-databind-2.1.5.jar
2.在返回json数据的方法上加上@ResponseBody注解,就会自动将返回的数据转换成json。

    @RequestMapping(value = "testJSON")
    @ResponseBody
    public Collection<Employee> testJSON(){
        Collection<Employee> all = dao.getAll();
        return all;
    }

3.在jsp中进行对json数据进行处理。这里就将数据生成一个表格

  $(function () {
        $("#btn").click(function () {
            $.ajax({
                url:"testJSON",
                type:"get",
                dataType:"json",
                success:function (data) {

                    var tb = "<table>";
                    tb += "<tr><th>id</th><th>lastName</th><th>email</th><th>gender</th><th>departmentName</th></tr>";
                    for(var i in data){
                        var emp = data[i];
                        tb += "<tr><td>"+emp.id+"</td><td>"+emp.lastName+"</td><td>"+emp.email+"</td><td>"+emp.gender+"</td><td>"+emp.department.departmentName+"</td></tr>";
                    }

                    tb += "</table>";
                    $("body").append(tb);
                }
            })
        })
      });

文件下载和文件上传

文件下载

首先取到文件所在的绝对路径,然后创建一个输入流,将文件读入,这里要一次性读到所有的字节,可用available()方法来获取当前流的大小。然后指定协议头和状态,最后将ResponseEntity对象返回即可。在IDEA中文件是在web目录下的。

    @RequestMapping("down")
    public  ResponseEntity<byte[]> down(HttpSession session) throws Exception{
        String realPath = session.getServletContext().getRealPath("img");
        String finalPath = realPath + File.separator + "1111.png";
        FileInputStream is = new FileInputStream(finalPath);
        byte[] bytes = new byte[is.available()];
        is.read(bytes);
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Disposition", "attachment;filename=zzz.png");
        HttpStatus status = HttpStatus.OK;

        ResponseEntity<byte[]> entity = new ResponseEntity<>(bytes, headers, status);
        return entity;
    }

文件上传

1.首先创建一个上传的表单,注意要加上enctype=“multipart/form-data”

<form action="up" method="post" enctype="multipart/form-data">
    <input type="file" name="uploadFile">
    <input type="submit">
</form>

2.在SpringMVC的xml中配置一下文件解析

    <!--处理文件上传,id必须为multipartResolver-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--设置文件解析的编码,与页面的一致-->
        <property name="defaultEncoding" value="UTF-8"></property>
        <!--设置上传文件的最大的大小-->
        <property name="maxInMemorySize" value="102400"></property>
    </bean>

3.实现功能,是通过MultipartResolver 来实现的,创建一个MultipartResolver 类型的参数即可,参数名要与表单中的name保持一致

 @RequestMapping("up_old")
    public String up_old(MultipartFile uploadFile,HttpSession session) throws IOException {
        //获取文件名称
        String fileName = uploadFile.getOriginalFilename();
        String finalPath = session.getServletContext().getRealPath("img")+File.separator+fileName;
        System.out.println(finalPath);
        //获取输入流
        InputStream is = uploadFile.getInputStream();
        //创建一个输出流写到文件
        FileOutputStream os = new FileOutputStream(finalPath);

        int i = 0;
        byte[] bytes = new byte[1024];

        while ((i= is.read(bytes))!= -1 ){
            os.write(bytes,0,i);
        }
        is.close();
        os.close();
        return "success";

    }

@RequestMapping("up")
    public String up(MultipartFile uploadFile,HttpSession session) throws IOException {
        String fileName = uploadFile.getOriginalFilename();
        String finalFileName = UUID.randomUUID()+fileName.substring(fileName.lastIndexOf("."));
        String finalPath = session.getServletContext().getRealPath("img")+File.separator+finalFileName;
        System.out.println(finalPath);
        File file = new File(finalPath);
        uploadFile.transferTo(file);
        return "success";

    }

拦截器

使用步骤

1.首先创建一个类,实现HandlerInterceptor接口,然后重写拦截器的三个方法。preHandle()是在代码执行之前
postHandle()是在代码执行之后,有异常不执行
afterCompletion()也是在代码执行之后,不过有没有异常都执行

@Component
public class FirstInterceptor implements HandlerInterceptor
{
    @Override
    public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
        System.out.println("First:preHandle");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("First:postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("First:afterCompletion");
    }
}

2.在XML文件中进行配置拦截器

    <mvc:interceptors>
        <!--默认拦截所有请求-->
        <bean class="com.glq.interceptor.FirstInterceptor"></bean>
        <bean class="com.glq.interceptor.SencondInterceptor"></bean>

        <!--自定义拦截方式-->
        <!--<mvc:interceptor>-->
            <!--<bean></bean>-->
        <!--要拦截的请求-->
            <!--<mvc:mapping path=""/>-->
        <!--不拦截的请求-->
            <!--<mvc:exclude-mapping path=""></mvc:exclude-mapping>-->
        <!--</mvc:interceptor>-->
    </mvc:interceptors>

多个拦截器的执行顺序

有多个拦截器都执行的话会有一个顺序问题,我们这里以两个拦截器为例子。这里preHandle若返回true就会继续执行,返回false就不在执行。

true true

当两个都为true的时候两个拦截器都会正常工作,执行的结果是preHandle()按照顺序执行,postHandle()、afterCompletion()按照相反的顺序执行。
在这里插入图片描述

false false

只有第一个的preHandle()方法会执行
在这里插入图片描述

false true

和false false一样,也是只有第一个的preHandle()方法会执行
在这里插入图片描述

true false

会执行第一个的preHandle()和afterCompletion(),还执行第二个的preHandle().
在这里插入图片描述

执行顺序总结

当有多个拦截器时,
* preHandle:按照拦截器数组的正向顺序执行
* postHandle:按照拦截器数组的反向顺序执行
* afterCompletion:按照拦截器数组的反向顺序执行
*
* 当多个拦截器的preHandle有不同的值时
* 第一个返回false,第二个返回false:只有第一个preHandle会执行
* 第一个返回true,第二个返回false:两个(全部)拦截器的preHandle都会执行 但是(全部)postHandle都不会执行,而afterCompletion只有第一个(返回false的拦截器之前的所有afterCompletion)会执行
* 第一个返回false,第二个返回true:只有第一个的preHandle会执行



今天的内容到此结束,谢谢大家的观看,如有错误请指正,谢谢!CSDN记录成长!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值