springmvc

Posted xue_yun_xiang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springmvc相关的知识,希望对你有一定的参考价值。

一、跨域请求

域:由ip/域名:端口组成,就是提供一个网络服务

localhost:8080 一个域
​ 127.0.0.1:8080 一个域
​ 10.8.163.53:8080 一个域
localhost:8085 一个域
以上都不是同一个域

什么是跨域请求?

就是在一个域下的服务/网页 通过Ajax等工具访问 另外一个 域下的请求 就是跨域,tomcat服务器为了保证安全,默认情况下不允许跨域请求

在这里插入图片描述

第一步:在loalhost:8080 创建服务,允许跨域

/**
 * 跨域请求
 */
@RestController
@CrossOrigin(origins = "http://localhost:8085") //允许另外一个域对应的网页中ajax 访问 注意最后不要加
// /标记在类上 表明当类下所有的处理器都允许 http://localhost:8085下 的界面发起跨域请求
public class CrossOriginController {


    @RequestMapping("/findStudentById")
    public Student findStudentById(int id){

        Student student = new Student();
        student.setSex("F");
        student.setId(id);
        student.setName("XXX");

        return student;
    }

}

第二步:另一域中 localhost:8085 创建html 发起跨域请求

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script src="/js/jquery-3.3.1.js"></script>
</head>
<body>

<button onclick="getStudentById()">获取学生 id=1</button>

<script>

    /*
    * 此时   $.ajax  请求 和  当前  html/crossorgin.html 处于同一域下
    * http://localhost:8080/findStudentById?id=1    html/crossorgin.html 处于同一域下
    *
    *
    *
    *  */
    function getStudentById(){
        $.ajax({
            url:"http://localhost:8080/findStudentById?id=1",
            type:'get',//
            success:function (data) {

                alert(data)
            },
            error:function () {
                alert("服务器错误")
            },
            dataType:'json'
        })
    }
</script>
</body>
</html>

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

二、文件上传下载

文件上传

使用表单上传

多数文件上传都是通过表单形式提交给后台服务器的,因此,要实现文件上传功能,就需要提供一个文件上传的表单,而该表单必须满足以下3个条件:
-form表单的method属性设置为post;
-form表单的enctype属性设置为multipart/form-data;
-提供的文件上传输入框。

<!--
    上传文件
           1.method="post"
           2.enctype="multipart/form-data"
           3.<input type="file" name="file">
-->
<form action="/xx" method="post" enctype="multipart/form-data">
    
    文件名:<input type="text" name="filename"><br>
    文件:<input type="file" name="file">
    
    <input type="submit" value="上传">
    
</form>

处理器接收文件

当form表单的enctype属性为multipart/form-data时,浏览器就会采用二进制流来处理表单数据,服务器端就会对文件上传的请求进行解析处理。Spring MVC通过MultipartResolver实现文件上传功能。MultipartResolver是一个接口对象,需要通过它的实现类CommonsMultipartResolver来完成文件上传工作。

1、导入依赖


    <!--文件上传依赖-->
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.3</version>
    </dependency>

2、在springmvc-servlet.xml 添加

 <!--
           配置文件大小 字节   <property name="maxUploadSize" value="1024000000"></property>
           编码格式          <property name="defaultEncoding" value="utf-8"></property>
           
           id 必须为 multipartResolver
    -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">

        <property name="defaultEncoding" value="utf-8"></property>
        <property name="maxUploadSize" value="1024000000"></property>
    </bean>

3、接收文件

/**
     * 接收文件
     *
     *  List<MultipartFile> file 对应 form <input type="file" name="file">
     * @param filename
     * @param file
     * @return
     */
    @RequestMapping("/fileUpload")
    @ResponseBody  // 返回json 字符串
    public String fileUpload(String filename, List<MultipartFile> files) throws IOException {

        System.out.println("filename = " + filename);

        if (files==null || files.size()==0){

            return "error";
        }

        for (MultipartFile multipartFile:files){

            File rootFile = new File("c:/java2102");

            if (!rootFile.exists()){// 如果文件不存在
                rootFile.mkdirs(); // 创建文件夹
            }

            // 得到文件上传的名字
           String realName =   multipartFile.getOriginalFilename();
            // UUID.randomUUID().toString() 唯一字符串 防止文件 被覆盖
            //  File.separator  /
            File file = new File("c:/java2102"+File.separator + UUID.randomUUID().toString() +realName);
           // 将接收到的文件保存到本地磁盘
            multipartFile.transferTo(file);
        }

        return "success";
    }

文件下载

在后台使用Spring MVC提供的ResponseEntity类型对象完成文件下载,使用它可以很方便的定义返回的HttpHeaders对象和HttpStatus对象,通过对这两个对象的设置,即可完成下载文件时所需的配置信息。

在这里插入图片描述

 /**
     * 文件下载
     * @param filename
     * @return
     * @throws IOException
     */
    @RequestMapping("/downloadFile")
    public ResponseEntity<byte[]> downloadFile(String filename,HttpServletRequest request) throws Exception {


        File file = new File("c:/java2102"+File.separator +filename);

        HttpHeaders headers = new HttpHeaders();

        // 设置下载的文件名称
        // 对应文件名称重编码  让浏览器识别
        headers.setContentDispositionFormData("attachment",getFilename(request,filename));
        // 通知浏览器以下载的形式 打开文件
        //浏览器以 二进制文件流 下载文件
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);


//        (@Nullable T body,
//        @Nullable MultiValueMap<String, String> headers, Object status
        return new ResponseEntity<>(FileUtils.readFileToByteArray(file),headers, HttpStatus.OK);
    }

解决中文文件名乱码问题:

 /**
     * 根据浏览器的不同进行编码设置,返回编码后的文件名
     */
    public String getFilename(HttpServletRequest request,
                              String filename) throws Exception {
        // IE不同版本User-Agent中出现的关键词
        String[] IEBrowserKeyWords = {"MSIE", "Trident", "Edge"};
        // 获取请求头代理信息
        String userAgent = request.getHeader("User-Agent");
        for (String keyWord : IEBrowserKeyWords) {
            if (userAgent.contains(keyWord)) {
                //IE内核浏览器,统一为UTF-8编码显示
                return URLEncoder.encode(filename, "UTF-8");
            }
        }
        //火狐等其它浏览器统一为ISO-8859-1编码显示
        return new String(filename.getBytes("UTF-8"), "ISO-8859-1");
    }

拦截器

拦截器:就是springmvc可以拦截过滤前端的请求,和过滤器的作用一样,但是拦截器只对经过Dispathcher的请求有效

拦截器 过滤器 Aop:抽取公共代码 拦截 过滤 鉴权
事务:只能用aop

springmvc 拦截器的实现:

第一种方式:通过实现HandlerInterceptor接口,或继承HandlerInterceptor接口的实现类(如HandlerInterceptorAdapter)来定义。

第一种方式: 通过实现WebRequestInterceptor接口,或继承WebRequestInterceptor接口的实现类来定义。

示例

1、实现HandlerInterceptor接口

/**
 * 继承HandlerInterceptor 实现 拦截器
 *
 *
 */
public class CustomerInterceptor implements HandlerInterceptor {

    @Override// 在处理器之前调
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        System.out.println("CustomerInterceptor ----preHandle 请求前");


        String idStr = request.getParameter("id");

        if (idStr!=null){
            int id = Integer.valueOf(idStr);

            if (id>0){ // 如果大于放行
                return true;
            }
        }

        // 拦截
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("被拦截了");
        return false;


    }

    @Override// 处理器 响应请求后
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

        System.out.println("CustomerInterceptor ----postHandle 处理器响应请求后");
    }

    @Override //整个 请求响应成功之后调用  渲染成功之后
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

        System.out.println("CustomerInterceptor ----afterCompletion 处理器响应前端完成渲染成功  后");
    }
}
public class MyInterceptor1 implements HandlerInterceptor {

    @Override// 在处理器之前调
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        System.out.println("MyInterceptor1 ----preHandle 请求前");


    // 放行
        return true;


    }

    @Override// 处理器 响应请求后
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

        System.out.println("MyInterceptor1 ----postHandle 处理器响应请求后");
    }

    @Override //整个 请求响应成功之后调用  渲染成功之后
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

        System.out.println("MyInterceptor1 ----afterCompletion 处理器响应前端完成渲染成功  后");
    }
}

声明拦截器

  <!--
        配置拦截器

        拦截器的顺序有 声明标签的顺序决定:越靠上越优先
    -->
    <mvc:interceptors>
        <!--  声明一个全局拦截器 对所有的请求 进行拦截-->
       <!-- <bean class="com.qfedu.filter.CustomerInterceptor"></bean>-->
        
        <mvc:interceptor>
            <!-- 配置局部拦截器 只对部分
             /student/** 拦截
             忽略    /student/findAllStudent
             -->
            <mvc:mapping path="/student/**"/>
            <mvc:exclude-mapping path="/student/findAllStudent"/>
            <bean class="com.qfedu.filter.MyInterceptor1"></bean>
        </mvc:interceptor>

        <mvc:interceptor>
            <!-- 局部拦截器  三者之间有顺序规定 必须先
              <mvc:mapping
              <mvc:exclude-mapping
               <bean
            -->
            <mvc:mapping path="/findStudentById"/>
            <bean class="com.qfedu.filter.CustomerInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

拦截器顺序优先级

在这里插入图片描述

以上是关于springmvc的主要内容,如果未能解决你的问题,请参考以下文章

springmvc 分页查询的简单实现

Spring Rest 文档。片段生成时 UTF-8 中间字节无效 [重复]

Spring MVC 教程

spring 国际化 js怎么设置

AngularJS ——ngResourceRESTful APIs 使用

第二周作业