首页 > 编程语言 > 详细

SpringMVC

时间:2021-02-18 15:17:13      阅读:24      评论:0      收藏:0      [点我收藏+]

SpringMVC

SSM: mybatis + Spring + SpringMVC MVC 三层架构

MVC: 模型(Model)、视图(View)、控制器(Contrlooer)的简写,是一种软件设计规范

  • MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。
  • 是将业务逻辑、数据、显示分离的方法来组织代码。
  • MVC主要作用是降低了视图与业务逻辑间的双向偶合。
  • MVC不是一种设计模式,MVC是一种架构模式。当然不同的MVC存在差异。
  • Model(模型):数据模型,提供要展示的数据,因此包含数据和行为,可以认为是领域模型或 JavaBean组件(包含数据和行为),不过现在一般都分离开来:Value Object(数据Dao) 和 服务层 (行为Service)。也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务。
  • View(视图):负责进行模型的展示,一般就是我们见到的用户界面,客户想看到的东西。 Controller(控制器):接收用户请求,委托给模型进行处理(状态改变),处理完毕后把返回的模型
  • 数据返回给视图,由视图负责展示。 也就是说控制器做了个调度员的工作。

最典型的MVC就是JSP + servlet + javabean的模式。

技术分享图片

回顾Servlet

新建maven 父工程

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.liu</groupId>
    <artifactId>SpringMVC</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
        <module>springmvc-01-servlet</module>
    </modules>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.12.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>
</project>

建立一个Moudle:springmvc-01-servlet , 添加Web app的支持!

导入servlet 和 jsp 的 jar 依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>SpringMVC</artifactId>
        <groupId>com.liu</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springmvc-01-servlet</artifactId>

    <dependencies>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
        </dependency>
    </dependencies>
</project>

HelloServlct

package com.liu.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取参数
        String method = req.getParameter("method");
        if (method.equals("add")) {
            req.getSession().setAttribute("msg", "执行了Add方法");
        }
        if (method.equals("delete")) {
            req.getSession().setAttribute("msg", "执行了delete方法");
        }

        //调用业务层

        //视图转发活重定向
        req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">

    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>com.liu.servlet.HelloServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>15</session-timeout>
    </session-config>
</web-app>

MVC框架要做哪些事情

  • 将url映射到java类或java类的方法 .
  • 封装用户提交的数据 .
  • 处理请求-----调用相关的业务处理--封装响应数据 .
  • 将响应的数据进行渲染 . jsp / html 等表示层数据 .

常见服务器端MVC 框架:

  • struts、Spring MVC、ASP.NET MVC、Zend Framework、JSF;

常见 前端MVC框架:

  • vue、angularjs、react、backbone;由MVC演化出了
  • 另外一些模式如:MVP、MVVM……

什么是SpringMVC?

概述:

  • Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架。

  • 查看官方文档:https://docs.spring.io/spring/docs/5.2.0.RELEASE/spring-framework-reference/web.html#spring-web

  • SpringMVC的特点

    • 轻量级,简单易学
    • 高效 , 基于请求响应的MVC框架
    • 与Spring兼容性好,无缝结合
    • 约定优于配置
    • 功能强大:RESTful、数据验证、格式化、本地化、主题等 6. 简洁灵活
  • Spring的web框架围绕DispatcherServlet [ 调度Servlet ] 设计。 DispatcherServlet的作用是将请求分发到不同的处理器。从Spring 2.5开始,使用Java 5或者以上版本的

  • 用户可以采用基于注解形式进行开发,十分简洁;

  • SpringMVC, 简单 , 便捷 , 易学 , 天生和Spring无缝集成(使用SpringIoC和Aop) , 使用约定优于 配置 . 能够进行简单的junit测试 . 支持Restful风格 .异常处理 , 本地化 , 国际化 , 数据验证 , 类型转换 , 拦 截器 等等......

中心控制器

  • Spring的web框架围绕DispatcherServlet设计。 DispatcherServlet的作用是将请求分发到不同的处理器。从Spring 2.5开始,使用Java 5或者以上版本的用户可以采用基于注解的controller声明方式。
  • Spring MVC框架像许多其他MVC框架一样, 以请求为驱动 , 围绕一个中心Servlet分派请求及提供其他功能,DispatcherServlet是一个实际的Servlet (它继承自HttpServlet 基类)。

技术分享图片

SpringMVC的原理如下所示

  • 当发起请求时被前置的控制器拦截到请求,根据请求参数生成代理请求,找到请求对应的实际控制器,控制器处理请求,创建数据模型,访问数据库,将模型响应给中心控制器,控制器使用模型与视图渲染视图结果,将结果返回给中心控制器,再将结果返回给请求者。
    -技术分享图片

SpringMVC执行原理

技术分享图片

简要分析执行流程

  • DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。
  1. 我们假设请求的url为 : http://localhost:8080/SpringMVC/hello
    1. 如上url拆分成三部分:
    2. http://localhost:8080服务器域名
    3. SpringMVC部署在服务器上的web站点
    4. hello表示控制器
    5. 通过分析,如上url表示为:请求位于服务器localhost:8080上的SpringMVC站点的hello控制器。
  2. HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler。
  3. HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器,如上url被查找控制器为:hello。
  4. HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。
  5. HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。
  6. Handler让具体的Controller执行。
  7. Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。
  8. HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。
  9. DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名。
  10. 视图解析器将解析的逻辑视图名传给DispatcherServlet。
  11. DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图。
  12. 最终视图呈现给用户。

Controller 及 RestFul

什么是Controller?

  • 控制器复杂提供访问应用程序的行为,通常通过接口定义或注解定义两种方法实现。
  • 控制器负责解析用户的请求并将其转换为一个模型。
  • 在Spring MVC中一个控制器类可以包含多个方法
  • 在Spring MVC中,对于Controller的配置方式有很多种

实现Controller接口

  • Controller是一个接口,在org.springframework.web.servlet.mvc包下,接口中只有一个方法;

  •   //实现该接口的类获得控制器功能 public interface Controller {
      //处理请求且返回一个模型与视图对象
          ModelAndView handleRequest(HttpServletRequest var1, HttpServletResponse var2) throws Exception;
      }
    
  •   @Component   组件
      @Service     service
      @Controller controller
      @Repository  
    

RequestMapping

@RequestMapping

  • @RequestMapping注解用于映射url到控制器类或一个特定的处理程序方法。可用于类或方法上。 用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。
  • 为了测试结论更加准确,我们可以加上一个项目名测试 myweb
  • 只注解在方法上面

RestFul 风格

概念

  • Restful就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格。基于这个风格设 计的软件可以更简洁,更有层次,更易于实现缓存等机制。

功能

  • 资源:互联网所有的事物都可以被抽象为资源
  • 资源操作:使用POST、DELETE、PUT、GET,使用不同方法对资源进行操作。 分别对应 添加、 删除、修改、查询。
  • 传统方式操作资源 :通过不同的参数来实现不同的效果!方法单一,post 和 get
  • 使用RESTful操作资源 : 可以通过不同的请求方式来实现不同的效果!如下:请求地址一样,但是功能 可以不同!
  • 在Spring MVC中可以使用 @PathVariable 注解,让方法参数的值对应绑定到一个URI模板变量 上。

method属性指定请求类型

  • 用于约束请求的类型,可以收窄请求范围。指定请求谓词的类型如GET, POST, HEAD, OPTIONS, PUT,PATCH, DELETE, TRACE等

  • Spring MVC 的 @RequestMapping 注解能够处理 HTTP 请求的方法, 比如 GET, PUT, POST, DELETE 以 及 PATCH。

  • 所有的地址栏请求默认都会是 HTTP GET 类型的。

  • 方法级别的注解变体有如下几个: 组合注解

  •   @GetMapping
      @PostMapping
      @PutMapping
      @DeleteMapping
      @PatchMapping
    
  • @GetMapping 是一个组合注解,它所扮演的是 @RequestMapping(method =RequestMethod.GET) 的一个快捷方式。

Spring 结果跳转方式

  • 设置ModelAndView对象 , 根据view的名称 , 和视图解析器跳到指定的页面 .

  • 页面 : {视图解析器前缀} + viewName +{视图解析器后缀}

  •   <!-- 视图解析器 -->
      <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
      id="internalResourceViewResolver">
        <!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/" /> <!-- 后缀 -->
        <property name="suffix" value=".jsp" />
      </bean>
    
  •   public class ControllerTest1 implements Controller {
          public ModelAndView handleRequest(HttpServletRequest httpServletRequest,
      HttpServletResponse httpServletResponse) throws Exception {
          //返回一个模型视图对象
          ModelAndView mv = new ModelAndView(); 
          mv.addObject("msg","ControllerTest1");
          mv.setViewName("test");
          return mv;
            } 
      }
    

ServletAPI

  • 通过设置ServletAPI , 不需要视图解析器 .

    • 通过HttpServletResponse进行输出

    • 通过HttpServletResponse实现重定向

    • 通过HttpServletResponse实现转发

    •   @Controller
        public class ResultGoTest {
            @RequestMapping("/result/t1")
            public void test1(HttpServletRequest req, HttpServletResponse rsp)
                    throws IOException {
                rsp.getWriter().println("Hello,Spring BY servlet API");
            }
        
            @RequestMapping("/result/t2")
            public void test2(HttpServletRequest req, HttpServletResponse rsp)
                    throws IOException {
                rsp.sendRedirect("/index.jsp");
            }
        
            @RequestMapping("/result/t3")
            public void test3(HttpServletRequest req, HttpServletResponse rsp)
                    throws Exception {
                //转发
                req.setAttribute("msg", "/result/t3");
                req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req, rsp);
            }
        }
      

SpringMVC

通过SpringMVC来实现转发和重定向 - 无需视图解析器;

package com.liu.controller;

public class TestController {
    @Controller
    public class ResultSpringMVC {
        @RequestMapping("/rsm/t1")
        public String test1() {
            //转发
            return "/WEB-INF/jsp/index.jsp";
        }

        @RequestMapping("/rsm/t2")
        public String test2() {
            //转发二
            return "forward:/WEB-INF/jsp/index.jsp";
        }

        @RequestMapping("/rsm/t3")
        public String test3() { 
            //重定向
            return "redirect:/WEB-INF/jsp/index.jsp";
        }
    }
}

数据处理

处理提交数据

  • 提交的域名称和处理方法的参数名一致

  • 提交数据 : http://localhost:8080/hello?name=liunian

  • 处理方法 :

  •   @RequestMapping("/hello")
      public String hello(String name){
          System.out.println(name);
          return "hello";
      }
      输出 liunian
    
  • 提交的域名称和处理方法的参数名不一致

  • 提交数据 : http://localhost:8080/hello?username=liunian

  • 处理方法 :

  •   //@RequestParam("username") : username??交的域的名称 . @RequestMapping("/hello")
      public String hello(@RequestParam("username") String name){
          System.out.println(name);
          return "hello";
      }
      
      输出 liunian
    
  • 提交的是一个对象

  • 要求提交的表单域和对象的属性名一致 , 参数使用对象即可

  • 实体类

  •   @Data
      public class User {
          private int id;
      	  private String name; 	
          private int age; //构造
      }
    
  • 提交数据 : http://localhost:8080/mvc04/user?name=liunian&id=1&age=11

  • 处理方法 :

  •   @RequestMapping("/user")
      public String user(User user){
          System.out.println(user);
          return "hello";
      }
      
      如果使用对象的话,前端传递的参数名和对象名必须一致,否则就是null。
    

数据显示到前端

  • 第一种 : 通过ModelAndView

  •   package com.liu.controller;
      
      public class TestController {
          public class ControllerTest1 implements Controller {
              public ModelAndView handleRequest(HttpServletRequest httpServletRequest,
                                                HttpServletResponse httpServletResponse) throws Exception {
                  
                  //返回一个模型视图对象
                  ModelAndView mv = new ModelAndView();
                  mv.addObject("msg", "ControllerTest1");
                  mv.setViewName("test");
                  return mv;
              }
          }
      }
    
  • 第二种 : 通过ModelMap

  • modelMap 继承了LinkedHashMap,所以拥有了LinkedHashMap 的全部功能

  • model 是精简版,大部分使用了model

  •   package com.liu.controller;
      
      public class TestController {
          @RequestMapping("/hello")
          public String hello(@RequestParam("username") String name, ModelMap model) {
      //封装要显示到视图中的数据 //相当于req.setAttribute("name",name); 
              model.addAttribute("name", name);
              System.out.println(name);
              return "hello";
          }
      }
    
  • 第三种 : 通过Model

  •   package com.liu.controller;
      
      public class TestController {
          @RequestMapping("/ct2/hello")
          public String hello(@RequestParam("username") String name, Model model) {
              //封装要显示到视图中的数据 
              // 相当于req.setAttribute("name",name); 
              model.addAttribute("msg", name);
              System.out.println(name);
              return "test";
          }
      }
    

对比

  • Model 只有寥寥几个方法只适合用于储存数据,简化了新手对于Model对象的操作和理解;
  • ModelMap 继承了 LinkedMap ,除了实现了自身的一些方法,同样的继承 LinkedMap 的方法和特性;
  • ModelAndView 可以在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转。

乱码问题

  • 乱码问题是在我们开发中十分常见的问题,也是让我们程序猿比较头大的问题!

  • 以前乱码问题通过过滤器解决 , 而SpringMVC给我们提供了一个过滤器 , 可以在web.xml中配置 .

  • 修改了xml文件需要重启服务器!

  •   <filter>
          <filter-name>encoding</filter-name>
          <filter-
      class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
          <init-param>
              <param-name>encoding</param-name>
              <param-value>utf-8</param-value>
          </init-param>
      </filter>
      <filter-mapping>
          <filter-name>encoding</filter-name>
          <url-pattern>/*</url-pattern>
      </filter-mapping>
    
  • 有些极端情况下.这个过滤器对get的支持不好 .

  • 处理方法 :

    • 修改tomcat配置文件 : 设置编码!

    •   <Connector URIEncoding="utf-8" port="8080" protocol="HTTP/1.1"
                   connectionTimeout="20000"
        redirectPort="8443" />
      
  • 自定义过滤器

  •   package com.liu.controller;
      
      import javax.servlet.*;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletRequestWrapper;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      import java.io.UnsupportedEncodingException;
      import java.util.Map;
      
      public class GenericEncodingFilter implements Filter {
          @Override
          public void init(FilterConfig filterConfig) throws ServletException {
      
          }
      
          @Override
          public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
              //处理response的字符编码
              HttpServletResponse myResponse = (HttpServletResponse) response;
              myResponse.setContentType("text/html;charset=UTF-8");
              // 转型为与协议相关对象
              HttpServletRequest httpServletRequest = (HttpServletRequest) request;
              // 对request包装增强
              HttpServletRequest myrequest = new MyRequest(httpServletRequest);
              chain.doFilter(myrequest, response);
          }
      
          @Override
          public void destroy() {
      
          }
      }
      
      //自定义request对象,HttpServletRequest的包装类
      class MyRequest extends HttpServletRequestWrapper {
          private HttpServletRequest request;
          //是否编码的标记
          private boolean hasEncode; //定义一个可以传入HttpServletRequest对象的构造函数,以便对其进行装饰
      
          public MyRequest(HttpServletRequest request) {
              super(request);// super必须写
              this.request = request;
          }
      
          @Override
          public Map getParameterMap() {
              // 先获得请求方式
              String method = request.getMethod();
              if (method.equalsIgnoreCase("post")) {
                  // post请求
                  try {
                      // 处理post乱码
                      request.setCharacterEncoding("utf-8");
                      return request.getParameterMap();
                  } catch (UnsupportedEncodingException e) {
                      e.printStackTrace();
                  }
              } else if (method.equalsIgnoreCase("get")) {
                  // get请求
                  Map<String, String[]> parameterMap = request.getParameterMap();
                  if (!hasEncode) { // 确保get手动编码逻辑只运行一次
                      for (String parameterName : parameterMap.keySet()) {
                          String[] values = parameterMap.get(parameterName);
                          if (values != null) {
                              for (int i = 0; i < values.length; i++) {
                                  try {
                                      // 处理get乱码
                                      values[i] = new String(values[i].getBytes("ISO-8859-1"), "utf-8");
                                  } catch (UnsupportedEncodingException e) {
                                      e.printStackTrace();
                                  }
                              }
                          }
                      }
                      hasEncode = true;
                  }
                  return parameterMap;
              }
              return super.getParameterMap();
          }
      
          @Override
          public String getParameter(String name) {
              Map<String, String[]> parameterMap = getParameterMap();
              String[] values = parameterMap.get(name);
              if (values == null) {
                  return null;
              }
              return values[0]; // 取回参数的第一个值
          }
      
          //取所有值
          @Override
          public String[] getParameterValues(String name) {
              Map<String, String[]> parameterMap = getParameterMap();
              String[] values = parameterMap.get(name);
              return values;
          }
      }
    
  •   <filter>
             <filter-name>encoding</filter-name>
             <filter-class>com.liu.controller.GenericEncodingFilter</filter-class>
         </filter>
         <filter-mapping>
             <filter-name>encoding</filter-name>
             <url-pattern>/*</url-pattern>
         </filter-mapping>
    

Json

什么是JSON?

  • JSON(JavaScript Object Notation, JS 对象标记) 是一种轻量级的数据交换格式,目前使用特别广 泛。

  • 采用完全独立于编程语言的文本格式来存储和表示数据。

  • 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。

  • 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

  • 在 JavaScript 语言中,一切都是对象。因此,任何JavaScript 支持的类型都可以通过 JSON 来表示,例 如字符串、数字、对象、数组等。看看他的要求和语法格式:

    • 对象表示为键值对,数据由逗号分隔
    • 花括号保存对象
    • 方括号保存数组
  • JSON 键值对是用来保存 JavaScript 对象的一种方式,和 JavaScript 对象的写法也大同小异,键/值对组 合中的键名写在前面并用双引号 "" 包裹,使用冒号 : 分隔,然后紧接着值:

  •   {"name": "lium"} 
      {"age": "3"}
      {"sex": "男"}
    

JSON 和 JavaScript 对象互转

  • 要实现从JSON字符串转换为JavaScript 对象,使用 JSON.parse() 方法:

    •   varobj=JSON.parse(‘{"a":"Hello","b":"World"}‘);
      
  • 要实现从JavaScript 对象转换为JSON字符串,使用 JSON.stringify() 方法:

    •   varjson=JSON.stringify({a:‘Hello‘,b:‘World‘});
      

Controller返回JSON数据

  • Jackson应该是目前比较好的json解析工具了

  • 当然工具不止这一个,比如还有阿里巴巴的 fastjson 等等。

  • 这里使用Jackson,使用它需要导入它的jar包;

  •   <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
      <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.12.1</version>
      </dependency>
    
  • 配置SpringMVC需要的配置

  • web.xml

  •   <?xml version="1.0" encoding="UTF-8"?>
      <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
               version="4.0">
          <!-- 配置 DispatchServlet -->
          <servlet>
              <servlet-name>springmvc</servlet-name>
              <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
              <init-param>
                  <param-name>contextConfigLocation</param-name>
                  <param-value>classpath:springmvc-servlet.xml</param-value>
              </init-param>
              <load-on-startup>1</load-on-startup>
          </servlet>
          <servlet-mapping>
              <servlet-name>springmvc</servlet-name>
              <url-pattern>/</url-pattern>
          </servlet-mapping>
          <filter>
              <filter-name>encoding</filter-name>
              <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
              <init-param>
                  <param-name>encoding</param-name>
                  <param-value>utf-8</param-value>
              </init-param>
          </filter>
          <filter-mapping>
              <filter-name>encoding</filter-name>
              <url-pattern>/*</url-pattern>
          </filter-mapping>
      </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: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
             https://www.springframework.org/schema/context/spring-context.xsd
             http://www.springframework.org/schema/mvc
             https://www.springframework.org/schema/mvc/spring-mvc.xsd">
          <!-- 自动扫包,让指定包下的注解生效,由IOC容器统一管理 -->
          <context:component-scan base-package="com.liu.controller"/>
          <mvc:default-servlet-handler/>
      
          <!-- json 乱码问题解决 -->
          <mvc:annotation-driven>
              <mvc:message-converters register-defaults="true">
                  <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                      <constructor-arg value="UTF-8"/>
                  </bean>
                  <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                      <property name="objectMapper">
                          <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                              <property name="failOnEmptyBeans" value="false"/>
                          </bean>
                      </property>
                  </bean>
              </mvc:message-converters>
          </mvc:annotation-driven>
      
          <!-- 视图解析器 -->
          <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
                id="internalResourceViewResolver">
              <!-- 前缀 -->
              <property name="prefix" value="/WEB-INF/jsp/"/>
              <!-- 后缀 -->
              <property name="suffix" value=".jsp"/>
          </bean>
      
          <!--    <bean name="/t1" class="com.liu.controller.ControllerTest1"/>-->
      </beans>
    
  • User的实体类,测试Controller

  •   package com.liu.pojo;
      
      import lombok.AllArgsConstructor;
      import lombok.Data;
      import lombok.NoArgsConstructor;
      
      @Data
      @AllArgsConstructor
      @NoArgsConstructor
      public class User {
          private String name;
          private int age;
          private String sex;
      }
      
    
  • 一个是@ResponseBody,一个是ObjectMapper对象,我们看下具体 的用法

  • 编写一个Controller;

  •   package com.liu.controller;
      
      import com.fasterxml.jackson.core.JsonProcessingException;
      import com.fasterxml.jackson.databind.ObjectMapper;
      import com.fasterxml.jackson.databind.SerializationFeature;
      import com.liu.pojo.User;
      import com.liu.utils.JsonUtils;
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.ResponseBody;
      import org.springframework.web.bind.annotation.RestController;
      
      import java.text.SimpleDateFormat;
      import java.util.ArrayList;
      import java.util.Date;
      import java.util.List;
      
      //@Controller  走视图解析器
      @RestController //不走视图解析器
      public class UserController {
      
          @RequestMapping(value = "/j1")
          public String json1() throws JsonProcessingException {
      
              ObjectMapper mapper = new ObjectMapper();
      
              User user = new User("lium", 3, "男");
              String s = mapper.writeValueAsString(user);
              return s;
          }
      
          @RequestMapping(value = "/j2")
          public String json2() throws JsonProcessingException {
      
              ObjectMapper mapper = new ObjectMapper();
      
              List<User> userList = new ArrayList<User>();
      
              User user1 = new User("lium1", 1, "男");
              User user2 = new User("lium2", 2, "女");
              User user3 = new User("lium3", 3, "男");
              User user4 = new User("lium4", 4, "女");
      
              userList.add(user1);
              userList.add(user2);
              userList.add(user3);
              userList.add(user4);
      
      //        String s = mapper.writeValueAsString(userList);
              return JsonUtils.getJson(userList);
          }
      
      
          @RequestMapping(value = "/j3")
          public String json3() throws JsonProcessingException {
      
      //        ObjectMapper mapper = new ObjectMapper();
      //        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
      //
      //        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
      //        mapper.setDateFormat(sdf);
              Date date = new Date();
      
      //        String s = mapper.writeValueAsString(date);
              return JsonUtils.getJson(date, "yyyy-MM-dd HH:mm:ss");
          }
      }
      
      我们需要设置一下他的编码格式为utf-8,以及它返回的类型; 
      通过@RequestMaping的produces属性来实现,修改下代码
        @RequestMapping(value="/j1",produces="application/json;charset=utf-8")
    

返回json字符串统一解决

  • 类上直接使用 @RestController ,这样子,里面所有的方法都只会返回 json 字符串了,不用再每一个都添加@ResponseBody !我们在前后端分离开发中,一般都使用 @RestController ,十分便捷

抽取为工具类

package com.liu.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import java.text.SimpleDateFormat;

public class JsonUtils {

    public static String getJson(Object object) {
        return getJson(object, "yyyy-MM-dd HH:mm:ss");
    }


    public static String getJson(Object object, String dateFormat) {
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);

        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        mapper.setDateFormat(sdf);
        try {
            return mapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
}

FastJson

fastjson.jar是阿里开发的一款专门用于Java开发的包,可以方便的实现json对象与JavaBean对象的转 换,实现JavaBean对象与json字符串的转换,实现json对象与json字符串的转换。实现json的转换方法 很多,最后的实现结果都是一样的。

<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.75</version>
</dependency>

fastjson 三个主要的类:

  • JSONObject 代表 json 对象
    • JSONObject实现了Map接口, 猜想 JSONObject底层操作是由Map实现的。
    • JSONObject对应json对象,通过各种形式的get()方法可以获取json对象中的数据,也可利用 诸如size(),isEmpty()等方法获取"键:值"对的个数和判断是否为空。其本质是通过实现Map 接口并调用接口中的方法完成的。
  • JSONArray 代表 json 对象数组
    • 内部是有List接口中的方法来完成操作的。
  • JSON 代表 JSONObject和JSONArray的转化
    • JSON类源码分析与使用
    • 仔细观察这些方法,主要是实现json对象,json对象数组,javabean对象,json字符串之间 的相互转化。
@RequestMapping(value = "/j4")
    public String json4() throws JsonProcessingException {

        List<User> userList = new ArrayList<User>();
        User user1 = new User("lium1", 1, "男");
        User user2 = new User("lium2", 2, "女");
        User user3 = new User("lium3", 3, "男");
        User user4 = new User("lium4", 4, "女");

        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
        userList.add(user4);

        String s = JSON.toJSONString(userList);

        return s;
    }

SpringMVC :Ajax 技术

  • AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
  • Ajax 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
  • Ajax 不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的Web应用程序的技 术。
  • 在 2005 年,Google 通过其 Google Suggest 使 A JAX 变得流行起来。Google Suggest能够自动帮 你完成搜索单词。
  • Google Suggest 使用 A JAX 创造出动态性极强的 web 界面:当您在谷歌的搜索框输入关键字时, JavaScript 会把这些字符发送到服务器,然后服务器会返回一个搜索建议的列表。
  • 传统的网页(即不用ajax技术的网页),想要更新内容或者提交一个表单,都需要重新加载整个网 页。
  • 使用ajax技术的网页,通过在后台服务器进行少量的数据交换,就可以实现异步局部更新。
  • 使用Ajax,用户可以创建接近本地桌面应用的直接、高可用、更丰富、更动态的Web用户界面。

jQuery.ajax

  • 纯JS原生实现Ajax我们不去讲解这里,直接使用jquery提供的,方便学习和使用,避免重复造轮 子,有兴趣的同学可以去了解下JS原生XMLHttpRequest ! Ajax的核心是XMLHttpRequest对象(XHR)。XHR为向服务器发送请求和解析服务器响应提供了接 口。能够以异步方式从服务器获取新数据。

  • jQuery 提供多个与 A JAX 有关的方法。

  • 通过 jQuery A JAX 方法,您能够使用 HTTP Get 和 HTTP Post 从远程服务器上请求文本、HTML、 XML 或 JSON – 同时您能够把这些外部数据直接载入网页的被选元素中。

  • jQuery 不是生产者,而是大自然搬运工。

  • jQuery Ajax本质就是 XMLHttpRequest,对他进行了封装,方便调用!

  •   jQuery.ajax(...)
        部分参数: url:请求地址
        	type:请求方式,GET、POST(1.9.0之后用method)
      		headers:请求头 data:要发送的数据
          contentType:即将发送信息至服务器的内容编码类型(默认: "application/x-www-form-urlencoded;charset=UTF-8")
          async:是否异步 timeout:设置请求超时时间(毫秒)
          beforeSend:发送请求前执行的函数(全局) complete:完成之后执行的回调函数(全局) success:成功之后执行的回调函数(全局) error:失败之后执行的回调函数(全局)
          accepts:通过请求头发送给服务器,告诉服务器当前客户端课接受的数据类型 dataType:将服务器端返回的数据转换成指定类型
          "xml": 将服务器端返回的内容转换成xml格式
          "text": 将服务器端返回的内容转换成普通文本格式
          "html": 将服务器端返回的内容转换成普通文本格式,在插入DOM中时,如果包含
          JavaScript标签,则会尝试去执行。
          "script": 尝试将返回值当作JavaScript去执行,然后再将服务器端返回的内容转换成
          普通文本格式
          "json": 将服务器端返回的内容转换成相应的JavaScript对象
          "jsonp": JSONP 格式使用 JSONP 形式调用函数时,如 "myurl?callback=?"
          jQuery 将自动替换 ? 为正确的函数名,以执行回调函数
    
  • 配置web.xml 和 springmvc的配置文件【记得静态资源过滤和注解驱动配 置上】

  •   <?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
             https://www.springframework.org/schema/context/spring-context.xsd
             http://www.springframework.org/schema/mvc
             https://www.springframework.org/schema/mvc/spring-mvc.xsd">
        
          <!-- 自动扫包,让指定包下的注解生效,由IOC容器统一管理 -->
          <context:component-scan base-package="com.liu.controller"/>
          <!--静态资源过滤-->
          <mvc:default-servlet-handler/>
          <mvc:annotation-driven/>
      
          <!-- 视图解析器 -->
          <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
                id="internalResourceViewResolver">
              <!-- 前缀 -->
              <property name="prefix" value="/WEB-INF/jsp/"/>
              <!-- 后缀 -->
              <property name="suffix" value=".jsp"/>
          </bean>
      </beans>
    

SpringMVC 拦截器

概述

  • SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。开 发者可以自己定义一些拦截器来实现特定的功能。
  • 过滤器与拦截器的区别:拦截器是AOP思想的具体应用。
  • 过滤器
    • servlet规范中的一部分,任何java web工程都可以使用
    • 在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截
  • 拦截器
    • 拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
    • 拦截器只会拦截访问的控制器方法, 如果访问的是jsp/html/css/image/js是不会进行拦截的

验证用户是否登录 (认证用户) 代码示例

  • 编写一个登陆页面 login.jsp

  •   <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
      <head>
          <title>登录页</title>
      </head>
      <body>
      <h1>登录页</h1>
      <form action="${pageContext.request.contextPath}/user/login" method="post">
          用户名:<input type="text" name="username">
          密码:<input type="text" name="password">
          <input type="submit" value="提交">
      </form>
      </body>
      </html>
      
    
  • 编写一个Controller处理请求

  •   package com.liu.controller;
      
      import org.springframework.stereotype.Controller;
      import org.springframework.ui.Model;
      import org.springframework.web.bind.annotation.RequestMapping;
      
      import javax.servlet.http.HttpSession;
      
      @Controller
      @RequestMapping("/user")
      public class LoginController {
      
          @RequestMapping("/main")
          public String main() {
              System.out.println("aaaaaaaaaaaa");
              return "main";
          }
      
          @RequestMapping("/goLogin")
          public String login() {
              System.out.println("bbbbbbbbbbbb");
              return "login";
          }
      
          @RequestMapping("/login")
          public String login(HttpSession session, String username, String password, Model model) {
              session.setAttribute("userLoginInfo", username);
              model.addAttribute("username", username);
              return "main";
          }
      
          @RequestMapping("/goOut")
          public String goOut(HttpSession session) {
              session.removeAttribute("userLoginInfo");
              return "login";
          }
      
      }
    
  • 编写一个登陆成功的页面 success.jsp

  •   <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
      <head>
          <title>首页</title>
      </head>
      <body>
      <h1>首页</h1>
      ${username}
      <p>
          <a href="${pageContext.request.contextPath}/user/goOut">注销</a>
      </p>
      </body>
      </html>
      
    
  • 在 index 页面上测试跳转!启动Tomcat 测试,未登录也可以进入主页!

  •   <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
      <head>
          <title>Title</title>
      </head>
      <body>
      <a href="${pageContext.request.contextPath}/user/goLogin">登录页</a>
      <a href="${pageContext.request.contextPath}/user/main">首页</a>
      </body>
      </html>
      
    
  • . 编写用户登录拦截器

  •   package com.liu.config;
      
      import org.springframework.web.servlet.HandlerInterceptor;
      
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import javax.servlet.http.HttpSession;
      
      public class LoginInterceptor implements HandlerInterceptor {
          @Override
          public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
              HttpSession session = request.getSession();
      
              if (request.getRequestURI().contains("goLogin")) {
                  return true;
              }
              if (request.getRequestURI().contains("login")) {
                  return true;
              }
      
      
              if (session.getAttribute("userLoginInfo") != null) {
                  return true;
              }
      
              request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
              return false;
          }
      }
      
    
  • 在Springmvc的配置文件中注册拦截器

  •   <?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
             https://www.springframework.org/schema/context/spring-context.xsd
             http://www.springframework.org/schema/mvc
             https://www.springframework.org/schema/mvc/spring-mvc.xsd">
          <!-- 自动扫包,让指定包下的注解生效,由IOC容器统一管理 -->
          <context:component-scan base-package="com.liu.controller"/>
          <mvc:default-servlet-handler/>
      
          <!-- json 乱码问题解决 -->
          <mvc:annotation-driven>
              <mvc:message-converters register-defaults="true">
                  <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                      <constructor-arg value="UTF-8"/>
                  </bean>
                  <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                      <property name="objectMapper">
                          <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                              <property name="failOnEmptyBeans" value="false"/>
                          </bean>
                      </property>
                  </bean>
              </mvc:message-converters>
          </mvc:annotation-driven>
      
          <!-- 视图解析器 -->
          <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
                id="internalResourceViewResolver">
              <!-- 前缀 -->
              <property name="prefix" value="/WEB-INF/jsp/"/>
              <!-- 后缀 -->
              <property name="suffix" value=".jsp"/>
          </bean>
      
          <!--拦截器配置-->
          <mvc:interceptors>
              <mvc:interceptor>
                  <!--包括这个请求下的所有请求-->
                  <mvc:mapping path="/**"/>
                  <bean class="com.liu.config.MyInterceptor"/>
              </mvc:interceptor>
              <mvc:interceptor>
                  <!--包括这个请求下的所有请求-->
                  <mvc:mapping path="/user/**"/>
                  <bean class="com.liu.config.LoginInterceptor"/>
              </mvc:interceptor>
          </mvc:interceptors>
      </beans>
    
  • web.xml

  •   <?xml version="1.0" encoding="UTF-8"?>
      <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
               version="4.0">
          <!-- 配置 DispatchServlet -->
          <servlet>
              <servlet-name>springmvc</servlet-name>
              <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
              <init-param>
                  <param-name>contextConfigLocation</param-name>
                  <param-value>classpath:applicationContext.xml</param-value>
              </init-param>
              <load-on-startup>1</load-on-startup>
          </servlet>
          <servlet-mapping>
              <servlet-name>springmvc</servlet-name>
              <url-pattern>/</url-pattern>
          </servlet-mapping>
          <filter>
              <filter-name>encoding</filter-name>
              <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
              <init-param>
                  <param-name>encoding</param-name>
                  <param-value>utf-8</param-value>
              </init-param>
          </filter>
          <filter-mapping>
              <filter-name>encoding</filter-name>
              <url-pattern>/*</url-pattern>
          </filter-mapping>
      </web-app>
    

文件上传和下载

  • 文件上传是项目开发中最常见的功能之一 ,springMVC 可以很好的支持文件上传,但是SpringMVC上 下文中默认没有装配MultipartResolver,因此默认情况下其不能处理文件上传工作。如果想使用Spring 的文件上传功能,则需要在上下文中配置MultipartResolver。

  • 前端表单要求:为了能上传文件,必须将表单的method设置为POST,并将enctype设置为 multipart/form-data。只有在这样的情况下,浏览器才会把用户选择的文件以二进制数据发送给服务器;

  • 对表单中的 enctype 属性做个详细的说明:

    • application/x-www=form-urlencoded:默认方式,只处理表单域中的 value 属性值,采用这种编 码方式的表单会将表单域中的值处理成 URL 编码方式。

    • multipart/form-data:这种编码方式会以二进制流的方式来处理表单数据,这种编码方式会把文 件域指定文件的内容也封装到请求参数中,不会对字符编码。

    • text/plain:除了把空格转换为 "+" 号外,其他字符都不做编码处理,这种方式适用直接通过表单 发送邮件。

    •   <form action="" enctype="multipart/form-data" method="post">
            <input type="file" name="file"/>
            <input type="submit">
        </form>
      
  • 一旦设置了enctype为multipart/form-data,浏览器即会采用二进制流的方式来处理表单数据,而对 于文件上传的处理则涉及在服务器端解析原始的HTTP响应。在2003年,Apache Software Foundation 发布了开源的Commons FileUpload组件,其很快成为Servlet/JSP程序员上传文件的最佳选择。

    • Servlet3.0规范已经提供方法来处理文件上传,但这种上传需要在Servlet中完成。
    • 而Spring MVC则提供了更简单的封装。
    • Spring MVC为文件上传提供了直接的支持,这种支持是用即插即用的MultipartResolver实现的。
    • Spring MVC使用Apache Commons FileUpload技术实现了一个MultipartResolver实现类: CommonsMultipartResolver。SpringMVC的文件上传还需要依赖Apache Commons FileUpload的组件。

上传

  <dependencies>
        <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.4</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>
    </dependencies>

applicationContext.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
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!-- 自动扫包,让指定包下的注解生效,由IOC容器统一管理 -->
    <context:component-scan base-package="com.liu.controller"/>
    <mvc:default-servlet-handler/>

    <!-- json 乱码问题解决 -->
    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="true">
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="UTF-8"/>
            </bean>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper">
                    <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                        <property name="failOnEmptyBeans" value="false"/>
                    </bean>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          id="internalResourceViewResolver">
        <!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!-- 后缀 -->
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--文件上传配置-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容, 默认为ISO-8859-1 -->
        <property name="defaultEncoding" value="utf-8"/> <!-- 上传文件大小上限,单位为字节(10485760=10M) -->
        <property name="maxUploadSize" value="10485760"/>
        <property name="maxInMemorySize" value="40960"/>
    </bean>
</beans>
  • CommonsMultipartFile 的 常用方法:
  • String getOriginalFilename():获取上传文件的原名 InputStream getInputStream():获取文件流
  • void transferTo(File dest):将上传文件保存到一个目录文件中

Controller

package com.liu.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.*;

@Controller
public class FileController {
    @RequestMapping("/upload")
    public String fileUpload(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
        //获取文件名 :file.getOriginalFilename();
        String uploadFileName = file.getOriginalFilename();
        //如果文件名为空,直接回到首页!
        if ("".equals(uploadFileName)) {
            return "redirect:/index.jsp";
        }
        System.out.println("上传文件名 : " + uploadFileName);
        //上传路径保存设置
        String path = request.getServletContext().getRealPath("/upload");

        //如果路径不存在,创建一个
        File realPath = new File(path);
        if (!realPath.exists()) {
            realPath.mkdir();
        }
        System.out.println("上传文件保存地址:" + realPath);
        InputStream is = file.getInputStream(); //文件输入流
        OutputStream os = new FileOutputStream(new File(realPath, uploadFileName)); //文件输出流
        //读取写出
        int len = 0;
        byte[] buffer = new byte[1024];
        while ((len = is.read(buffer)) != -1) {
            os.write(buffer, 0, len);
            os.flush();
        }
        os.close();
        is.close();
        return "redirect:/index.jsp";
    }

    /*
     * 采用file.Transto 来保存上传的文件 */
    @RequestMapping("/upload2")
    public String fileUpload2(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
        //上传路径保存设置
        String path = request.getServletContext().getRealPath("/upload");
        File realPath = new File(path);
        if (!realPath.exists()) {
            realPath.mkdir();
        }
        //上传文件地址 System.out.println("上传文件保存地址:"+realPath);
        //通过CommonsMultipartFile的方法直接写文件(注意这个时候)
        file.transferTo(new File(realPath + "/" + file.getOriginalFilename()));
        return "redirect:/index.jsp";
    }
}

文件下载

 @RequestMapping(value = "/download")
    public String downloads(HttpServletResponse response, HttpServletRequest request) throws Exception {
        //要下载的图片地址
        String path = request.getServletContext().getRealPath("/upload");
        String fileName = "qqq.jpg";
        //1、设置response 响应头
        response.reset(); //设置页面不缓存,清空buffer response.setCharacterEncoding("UTF-8"); //字符编码 response.setContentType("multipart/form-data"); //二进制传输数据 //设置响应头
        response.setHeader("Content-Disposition",
                "attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8"));
        File file = new File(path, fileName);
        //2、 读取文件--输入流
        InputStream input = new FileInputStream(file); //3、 写出文件--输出流
        OutputStream out = response.getOutputStream();
        byte[] buff = new byte[1024];
        int index = 0;
        //4、执行 写出操作
        while ((index = input.read(buff)) != -1) {
            out.write(buff, 0, index);
            out.flush();
        }
        out.close();
        input.close();
        return null;
    }

SpringMVC

原文:https://www.cnblogs.com/LiuMiao1128/p/14411356.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!