SpringMVC完整学习!!!

1.楔子

1.1、了解MVC

MVC:

  • M:Model(模型),对应dao层和service层,模型,相当于实体类,其分为两类: 一类称为数据承载 Bean:实体类,专门用户承载业务数据的,如 Student、User 等 一类称为业务处理 Bean:指 Service 或 Dao 对象,专门用于处理用户提交请求的。
  • 拓展:在实际项目中可能会遇到某些属性过于繁杂的实体类,而在某些地方使用的时候只需要使用到其中少数几个属性,此时可以重新设计一个实体类,一般这种实体类我们叫做:
    • pojo:完整的实体类
    • vo:view对象,一般用于前端页面和控制层之间
    • dto:数据传输对象
  • V:View(视图),对应jsp,视图,与用户进行交互
  • C:Controller(控制),对应controller层(servlet),用于接收并且处理用户的请求,然后响应给用户

最典型的MVC:jsp+servlet+javabean!!

Model1 and Model2:

  • Model1:在这个时代,虽然也是使用了MVC,但是总的来说只分为了两层,一层是View层和Controller层合二为一,也就是JSP,JavaBean则作为Model层单独存在。这样的话,就会显得JSP极其臃肿,耦合度很高,不符合低耦合的原则。
  • Model2:这个时代可以说完全实现了MVC模式,在Model1的基础上,Model2扩展了Servlet,将控制逻辑放在Servlet中,让它来做Controller的工作,从而减少了JSP的负担。在Model2模式中,JSP只负责显示页面,生成动态网页;Servlet负责流程的控制,处理各种请求;JavaBeans则负责业务逻辑,以及对数据库的操作。

1.2、MVC框架的主要功能

  1. 将用户的url请求映射到java的类的方法上
  2. 封装用户提交的数据
  3. 处理请求–调用相关的业务处理–封装响应的数据
  4. 将响应的数据进行渲染在jsp/html层表示数据

补充:

  • 常见的服务器端MVC框架:Structs1和2,SpringMVC,ASP.NET MVC,Zend Franmework,JSF
  • 常见的前端MVC框架:Vue,angularjs,react,backbone
  • 由MVC演化出来的其他模式:MVP,MVVM等等

2.初识SpringMVC

​ Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。

2.1、为什么要学习SpringMVC

SpringMVC的优点:

  1. 轻量级,简单易学
  2. 高效,基于请求响应的MVC
  3. 可以支持各种视图技术,而不仅仅局限于JSP;
  4. 可以与Spring框架无缝集成(如IoC容器、AOP等);
  5. 清晰的角色分配:前端控制器(dispatcherServlet) , 请求到处理器映射(handlerMapping), 处理器适配器(HandlerAdapter), 视图解析器(ViewResolver)。

2.2、了解SpringMVC

​ Spring的模型-视图-控制器(MVC)框架是围绕一个 DispatcherServlet来设计的,这个Servlet会把请求分发给各个处理器,并支持可配置的处理器映射、视图渲染、本地化、时区与主题渲染等,甚至还能支持文件上传。

SpringMVC运行原理:

SpringMVC完整学习!!!
  • 流程说明: (1)客户端(浏览器)发送请求,直接请求到 DispatcherServlet。 (2)DispatcherServlet 根据请求信息调用 HandlerMapping,解析请求对应的 Handler(也就是我们平常说的 Controller 控制器)。 (3)解析到对应的 Handler后,开始由 HandlerAdapter 适配器处理。 (4)HandlerAdapter 会根据 Handler 来调用真正的处理器开处理请求,并处理相应的业务逻辑。 (5)处理器处理完业务后,会返回一个 ModelAndView 对象,Model 是返回的数据对象,View 是个逻辑上的 View。 (6)ViewResolver 会根据逻辑 View 查找实际的 View。 (7)DispaterServlet 把返回的 Model 传给 View(视图渲染)。 (8)把 View 返回给请求者(浏览器)

总结:SpringMVC运行流程大体上可以分为四步!!

  • 第一步:用户发起请求后DispatcherServlet 通过处理器映射器将请求的url进行分析得到对应的处理器然后告诉给DispatcherServlet
  • 第二步:DispatcherServlet 将分析好的结果交给处理器适配器,适配器通过结果找到对应的处理器处理请求,然后将结果封装返回给适配器,适配器再将对象返回给DispatcherServlet
  • 第三步:DispatcherServlet从得到的数据中将其中的视图信息交给视图解析器,视图解析器将信息进行解析得到一个具体的视图页面并将其返回给DispatcherServlet
  • 第四步:DispatcherServlet根据解析好的结果找到对应的视图然后将数据渲染到页面上,然后将该页面响应给用户

3.入门项目初体验!

  1. 创建一个maven项目,导入相关依赖

    javax.servlet
    javax.servlet-api
    4.0.1
    provided

    org.springframework
    spring-webmvc
    5.3.9

    junit
    junit
    4.12

    org.aspectj
    aspectjweaver
    1.6.8

  1. 添加Web框架,配置Tomcat
    SpringMVC完整学习!!!
  2. 配置web.xml文件,注册DispatcherServlet(前端控制器)

        dispatcherServlet
        org.springframework.web.servlet.DispatcherServlet

            contextConfigLocation
            classpath:springmvc.xml

        1

        dispatcherServlet

        /

  1. 编写springmvc.xml配置文件

  1. 在controller包下编写一个helloSpringMVC!
@Controller
public class HelloSpringMVC {
    @RequestMapping("/hello")//配置请求访问的路径
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        ModelAndView mv=new ModelAndView();
        mv.addObject("msg","helloSpringMVC");
        mv.setViewName("hello");//配置跳转页面
        return mv;
    }
}
  1. 在WEB-INF包下新建一个jsp包,在里面编写hello.jsp

    你好

${msg}

  1. 启动服务器,运行测试!

总结:完成一个SpringMVC的几个主要步骤

  1. 配置web.xml文件,注册DispatcherServlet
  2. 编写springmvc.xml配置文件,配置映射器,适配器以及视图解析器
  3. 注:不过在实际业务中我们是通过注解的方式,不需要我们自己去配置适配器以及映射器,我们只需要配置视图解析器以及开启注解扫描和即可
  4. 编写对应的处理器,也就是我们的controller
  5. 编写对应的视图页面也就是jsp
  6. 注:一般我们需要完成的部分也就是三和四

4.Controller详解

实现一个Controller的方式有多种,其中两种是实现Controller接口和@Controller注解的方式

4.1、Controller接口实现

​ 注:相对于使用注解的方式而言,使用该方式有以下几个不同的地方

  • 需要自己配置处理器映射器以及处理器适配器
  • 需要类去实现Controller接口,并且实现里面的方法
  • 需要在配置文件中去注册bean

具体实现:

  • 配置处理器映射器以及处理器适配器

  • 实现Controller接口
public class Study implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ModelAndView mv=new ModelAndView();
        mv.addObject("msg","helloSpringMVC");
        mv.setViewName("hello");
        return mv;
    }
}
  • 在配置文件中去注册bean

总结:

​ 该方式是比较老的实现方式,而且相对而言比较麻烦,需要自己去配置处理器映射器以及处理器适配器,并且还需要我们去自己注册bean,所以不推荐使用该方式!!

4.2、@Controller注解实现

​ 注:相对于接口的方式而言,使用该方式有以下几个不同的地方

  • 只需要开启包扫描以及支持
  • 使用@Controller注解标识类
  • 使用@RequestMapping注解为方法配置映射路径

具体实现:

  • 开启包扫描以及支持

  • @Controller注解
@Controller
public class HelloSpringMVC {
}
  • @RequestMapping注解映射路径
@RequestMapping("/hello")//配置请求访问的路径
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
    ModelAndView mv=new ModelAndView();
    mv.addObject("msg","helloSpringMVC");
    mv.setViewName("hello");//配置跳转页面
    return mv;
}

注:RequestMapping注解的用法
– 用在类上的时候,表示访问该类下方法的时候,需要在路径上加上类上配置的路径
– 用在方法上的时候,表示访问该方法的路径

总结:

​ 使用注解的方式非常的简便,并且这也是我们最常用的方式,只需要我们使用@Controller注解标识类以及@RequestMapping注解配置路径即可,非常推荐!!

5.拓展:RestFul风格

5.1、什么是RestFul风格

Restful风格指的是网络应用中就是资源定位和资源操作的风格。不是标准也不是协议。

  • Rest即Representational State Transfer的缩写,可译为”表现层状态转化”。
  • Restful风格最大的特点为:资源、统一接口、URI和无状态。
  • 这种风格设计的软件,可以更简洁,更有层次,更易于实现缓存等机制。

5.2、RestFul风格特点

RestFul风格与传统的风格的差异:

  • 传统风格:传统风格只有post和get两种方式,在具体的增删改查中是通过请求的不同的类或者方法去判别到底是属于哪一种操作,并且传递请求参数的时候使用的是问号,例如:
http://localhost:8080/select?a=1    查询,参数为a=1
  • RestFul风格:RestFul风格对于增删改查都有对应的方式,只需要使用相应的方式就可知道是哪种操作,对应关系为:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源,例如:
@RequestMapping(path = “/query/{a}”,method = RequestMethod.GET)
该注解等价于
@GetMapping(path = “/query/{a}”)

http://localhost:8080/query/1    这也是查询,参数为a=1

注:不同的方式都用对应的注解:@GetMapping、@PostMapping、@PutMapping、@DeleteMapping相当于简写了代码 @PathVariable:将URL请求路径参数映射到方法参数中,例如:

http://localhost:8080/query/1
public String query(@PathVariable int a)

在使用的时候,路径中的参数1会自动映射到方法的参数a中

5.3、小结

​ 简单来理解的话RestFul风格就是请求路径相同,但根据不同的参数、请求方式不同而执行不同的方法,产生的结果也不同,而这也是当下比较流行的一种风格,推荐!!

6.SpringMVC结果跳转方式

6.1、原生servlet方式

​ 也就是使用原生的转发和重定向方式进行跳转,极不推荐!!

6.2、SpringMvc方式

SpringMVC本身也具有两种情况,一种是带有视图解析器,一种是不带视图解析器

  1. 不带视图解析器:
  2. 请求转发(默认):
public String test1(Model model){
    model.addAttribute("msg1","请求转发");
    return "forward:WEB-INF/jsp/hello.jsp";
}
  1. 重定向:
public String test1(Model model){
    model.addAttribute("msg1","请求转发");
    return "redirect:/index.jsp";
}
  1. 带视图解析器:
  2. 请求转发(默认):
public String test1(Model model){
    model.addAttribute("msg1","请求转发");
    return "forward:hello";
}
  1. 重定向:
public String test1(Model model){
    model.addAttribute("msg1","请求转发");
    return "redirect:/hello";
}
+ 注:在使用重定向的时候需要注意路径的问题

总结:视图解析器本质上就相当于一个字符串的拼接,同时可以在路径前指定使用转发还是重定向!!

7.SpringMVC数据处理

7.1、接收请求参数

7.1.1、当参数为基本类型或者String类型:

  1. 当前端传过来的参数和方法的参数名相同:
http://localhost:8080/m1/t1?name=xiaoye

public String test1(Model model,String name)

此时,可以直接接收参数。
2. 当前端传过来的参数和方法的参数名不相同:

http://localhost:8080/m1/t1?username=xiaoye

public String test1(Model model,String name)

此时不能直接接收参数,需要使用@RequestParam注解指定名称

public String test1(Model model,@RequestParam("username") String name)

注·:一般而言建议不管名字是否相同都使用注解!!

7.1.2、当参数为对象类型

  1. 通过对应的实体类接收:
  2. 实体类:
public class User {
    private int id;
    private String name;
    private int age;
}
  • 前端请求:
http://localhost:8080/m1/t2?name=xiaoye&id=2&age=20
  • 接收参数:
@RequestMapping("/t2")
public String test2(User user){
    System.out.println(user);
    return "hello";
}

此时参数可以指定匹配到user对象的每个字段上。
– 注:如果参数名和对象的字段名不匹配,那么对象对应属性值就接收不到参数,就会为空!!
2. 通过Map接收:

@RequestMapping("/t2")
public String test2(@RequestParam Map map){
    for (Map.Entry entry : map.entrySet()) {
        System.out.println(entry.getKey() + entry.getValue());
    }
    return "hello";
}

注:在使用map接收参数的时候,接收post请求,用的是@RequestBody,而接收get请求用的是@RequestParam。

7.2、数据回显前端

7.2.1、通过ModelAndView

public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
    ModelAndView mv=new ModelAndView();
    mv.addObject("msg","helloSpringMVC");
    mv.setViewName("hello");
    return mv;
}

7.2.2、通过Model

public String test1(Model model){
    model.addAttribute("msg2","hello");
    return "hello";
}

7.2.3、通过ModelMap

@RequestMapping("/t3")
public String test3(){
    ModelMap map=new ModelMap();
    map.addAttribute("msg","xiaoye")
        return "hello";
}

三者的区别:

  • ModelAndView:可以在存储数据的同时设定逻辑视图
  • Model:方法相对于ModelMap较少,简化了新手对Model的理解,一般来说用它存储数据是足够了的
  • ModelMap:继承了LinkedHashMap,处理自身的一些方法外还拥有LinkedHashMap的方法和特性

8.SpringMVC乱码问题

问题:我们在前端到后端传输中文字符串时总是呢遇到乱码问题

解决:

  1. 简易解决:我们自己写一个简单的过滤器,然后注册到web.xml
public class EncodingFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        chain.doFilter(request,response);
    }
}

    encoding
    Lyu.com.filter.EncodingFilter

    encoding
    /*

  1. 中级解决:使用Spring提供的过滤器

    encoding
    org.springframework.web.filter.CharacterEncodingFilter

        encoding
        utf-8

    encoding
    /*

  1. 最终解决:使用大神编写的通用过滤器
public class GenericEncodingFilter implements Filter {
    @Override
    public void destroy() {
    }
    @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 init(FilterConfig filterConfig) throws ServletException {
    }
}
//自定义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 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 parameterMap = getParameterMap();
        String[] values = parameterMap.get(name);
        if (values == null) {
            return null;
        }
        return values[0]; // 取回参数的第一个值
    }
    //取所有值
    @Override
    public String[] getParameterValues(String name) {
        Map parameterMap = getParameterMap();
        String[] values = parameterMap.get(name);
        return values;
    }
}

记得在web.xml里注册!

9.JSON

9.1、JSON的简易学习

JSON:

  • JSON是一种轻量级的数据交换格式。
  • 采用完全独立于编程语言的文本格式来存储和表示数据。
  • 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。
  • 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

语法格式:

  • 数据在 名称/值对中
  • 数据由逗号 , 分隔
  • 使用斜杆来转义 * * 字符
  • 大括号 {} 保存对象
  • 中括号 [] 保存数组,数组可以包含多个对象

JOSN值:

  • 数字(整数或浮点数)
  • 字符串(在双引号中)
  • 逻辑值(true 或 false)
  • 数组(在中括号中)
  • 对象(在大括号中)
  • null

示例:

{ "age":30 ,"name":"菜鸟教程" , "url":"www.runoob.com","sites": [
    { "name":"菜鸟教程" , "url":"www.runoob.com" },
    { "name":"google" , "url":"www.google.com" },
    { "name":"微博" , "url":"www.weibo.com" }
],"flag":true,"runoob":null }

访问或者修改对象值:

  • 使用点号 .
  • 使用中括号[]
var myObj, x;
myObj = { "name":"runoob", "alexa":10000, "site":null };
x = myObj.name;
x = myObj["name"];

myObj.sites.site1 = "www.google.com";
myObj.sites["site1"] = "www.google.com";

删除对象值:

  • 使用 delete 关键字来删除 JSON 对象的属性
delete myObj.sites.site1;
delete myObj.sites["site1"]

JSON字符串和对象的转换:

  • 使用 JSON.parse() 方法将字符串转换为 JavaScript 对象。
{ "name":"runoob", "alexa":10000, "site":"www.runoob.com" }
var obj = JSON.parse('{ "name":"runoob", "alexa":10000, "site":"www.runoob.com" }');
  • 使用 JSON.stringify() 方法将 JavaScript 对象转换为字符串。
var obj = { "name":"runoob", "alexa":10000, "site":"www.runoob.com"};
var myJSON = JSON.stringify(obj);

9.2、JSON解析器

简单来说就是可以把字符串和json类型的字符串或者对象进行相互的转换!!

而在这里将介绍两种常用的JSON解析器的简单使用!

9.2.1JackJson

Jackson 优点:

  • 解析大文件的速度比较快;
  • 运行时占用的内存比较少,性能更佳;
  • API 很灵活,容易进行扩展和定制。

Jackson 的组成:

  • jackson-core,核心包,提供基于”流模式”解析的相关 API,包括 JsonPaser 和 JsonGenerator。
  • jackson-annotations,注解包,提供标准的注解功能;
  • jackson-databind ,数据绑定包,提供基于”对象绑定”解析的相关 API ( ObjectMapper ) 和基于”树模型”解析的相关 API (JsonNode)

  • 导入相关的依赖


    com.fasterxml.jackson.core
    jackson-core
    2.13.3

    com.fasterxml.jackson.core
    jackson-databind
    2.13.3

    com.fasterxml.jackson.core
    jackson-annotations
    2.13.3

  1. 使用 ObjectMapper Jackson 最常用的 API 就是基于”对象绑定” 的 ObjectMapper,它通过 writeValue 的系列方法将 Java 对象序列化为 JSON,并且可以存储成不同的格式。
  2. writeValueAsString(Object value) 方法,将对象存储成字符串
  3. writeValueAsBytes(Object value) 方法,将对象存储成字节数组
  4. writeValue(File resultFile, Object value) 方法,将对象存储成文件
@RequestMapping("/t4")
@ResponseBody
public String test4() throws JsonProcessingException {
    ObjectMapper mapper = new ObjectMapper();
    User user=new User(2,"小也",20);
    return mapper.writeValueAsString(user);
}

注:

SpringMVC完整学习!!!
– 如果返回的字符串在前端中文乱码,那么在配置文件里加入以下解决乱码的配置

补充:@ResponseBody和@RestController

  • @ResponseBody:用在方法上,此时方法不走视图解析器路线,而是直接将数据返回到页面
  • @RestController:用在类上,具备@Controller注解功能的同时,该类下所有的方法都不走视图解析器,同@ResponseBody注解一样

9.2.2FastJson

  1. 导入依赖

    com.alibaba
    fastjson
    2.0.10

  1. 常用的API
parseObject()//字符串转JSON对象
toJavaObject()//JSON对象转java对象
toJSONString()//java对象转JSON字符串
toJSON()//java对象转JSON对象
  1. 初识Ajax

  2. 概念:AJAX = Asynchronous JavaScript and XML,是一种用于创建快速动态网页的技术。AJAX 通过在后台与服务器进行少量数据交换,使网页实现异步更新。这意味着可以在不重载整个页面的情况下,对网页的某些部分进行更新。传统的网页(不使用 AJAX)如果需要更新内容,必须重载整个页面。

  3. Ajax的使用:
  4. 导js文件:使用jQuery就导入jQuery的js文件,使用vue就导入vue的文件

  1. 编写对应处理的Controller,返回消息或者字符串或者json格式的数据
response.getWriter().write("小明");//servlet中通过这个方式将数据返回给Ajax
  1. 编写Ajax:
    1. url:Controller请求
    2. data:键值对
    3. success:回调函数

       function a1() {
           $.post({
            url:"test1",
            data:{"name":"小明"},
            success:function (data){
                console.log(data);
                console.log($('#t1').innerText);
                $('#t1').val(data);
            }
        })}

  1. 给Ajax绑定事件:
    1. 点击:click

2. 失去焦点:onblur
3. 键盘弹起:keyup

注:如果想熟练的使用Ajax的话,还是需要大量的练习使用!!!

11.SpringMVC拦截器

11.1、什么是拦截器

​ SpringMVC的处理器拦截器,类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。 依赖于web框架,在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个 controller生命周期之内可以多次调用。

11.2、拦截器与过滤器的区别

过滤器(filter):

  • filter属于Servlet技术,只要是web工程都可以使用
  • filter主要对所有请求过滤
  • filter的执行时机早于Interceptor

拦截器(interceptor):

  • interceptor属于SpringMVC技术,必须要有SpringMVC环境才可以使用
  • interceptor通常对处理器Controller进行拦截
  • interceptor只能拦截dispatcherServlet处理的请求

11.3、自定义拦截器

重点:实现HandlerInterceptor接口!!!

  1. 新建项目,添加web框架支持
  2. 配置spring-nvc.xml文件
  3. 编写拦截器
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("拦截前=====================");
        return true;//相当于放行,false就不放行
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("拦截后=====================");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("清理=====================");
    }
}
  1. 在spring-mvc.xml配置拦截器

注:
– 可以配置多个拦截器,顺序按照配置的顺序拦截
– path:代表要拦截哪些请求,/,代表所有的文件夹,包括子文件夹
– 如果控制台中文乱码,可以配置tomcat的虚拟机选项添加
-Dfile.encoding=UTF-8**
– 一般只重写preHandle()方法,而后面两种一般只用来打印日志等等

12.SpringMVC文件上传

12.1、文件上传

  1. 导入依赖

    commons-fileupload
    commons-fileupload
    1.4

  1. 编写文件上传jsp

注:必须设置enctype=”multipart/form-data”
3. 在spring-mvc.xml配置文件上传解析器


  1. 编写controller
public String fileUpLoad(MultipartFile myfile, HttpServletRequest request){
    //1.得到本地服务目录的地址
    String path = request.getSession().getServletContext().getRealPath("upload");
    //2.判断该目录是否存在
    File file = new File(path);
    if(!file.exists()){
        file.mkdirs();
    }
    //3.把myfile保存到本低服务中某个文件下
    //UUID.randomUUID().toString()获取随机值 防止上传的文件名重复
    //getOriginalFilename获得上传的文件名 非getName方法
    String fileName = UUID.randomUUID().toString().replace("-","")
        +myfile.getOriginalFilename();
    File target = new File(path+"/"+fileName);
    try {
        myfile.transferTo(target);//把myfile转移到目标目录下
    } catch (IOException e) {
        e.printStackTrace();
    }
    return "";
}

Original: https://www.cnblogs.com/xiaoye-Blog/p/16565616.html
Author: 小也取不到名字
Title: SpringMVC完整学习!!!

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/621640/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 回溯法套路总结与应用

    概述 回溯法常用于遍历一个列表元素的所有所有子集,比如全排列问题。可以说深度优先搜索就是回溯法的一种特殊形式。该方法的时间复杂度比较大一般为O(N!),它不像动态规划存在重叠子问题…

    数据库 2023年6月11日
    088
  • django中的auth模块与admin后台管理

    1. auth模块 在创建完django项目之后,执行数据库迁移之后,数据库里会增加很多新表,其中有一张名为auth_user的表,当访问django自带的路由admin的时候,需…

    数据库 2023年6月14日
    089
  • 21浙比武

    可以将获得的windows镜像先挂载获取SAM和SYSTEM注册表文件,然后使用mimikatz 提取windows的密码ntml哈希值 <span class=”ne-te…

    数据库 2023年6月11日
    076
  • Mysql8设置允许root用户远程访问

    按照mysql8.0以前的方法修改报错 mysql> grant all privileges on *.* to ‘root’@’%’ identified by ‘PAS…

    数据库 2023年6月6日
    0111
  • 类的加载流程

    概述 什么是类加载呢? 我们知道一个Class文件编译完成之后是存在于磁盘的一个普通文件,如果想要执行,必然需要将 Class&#x6587;&#x4EF6;加载到…

    数据库 2023年6月11日
    075
  • 电脑卡.磁盘占用100% .解惑找不到Superfetch等服务问题

    公司电脑没有固态。磁盘io比较慢. 经常打满100% *1. 打开任务管理器发现是 一个叫system和DCFWinService的服务一直在占用磁盘读写 2. 解决方向. 禁用掉…

    数据库 2023年6月14日
    0679
  • 04-MySQL锁

    数据库锁 1、SQL语言包括那几个部分 SQL语言包括 数据定义(DDL)、数据操纵(DML)、数据控制(DCL)和数据查询(DQL)四个部分 2、每部分都有哪些操作关键词 数据定…

    数据库 2023年6月16日
    079
  • Go语言常见的并发模式

    Go语言常见的并发模式 并发不是并行 并发关注的是程序的设计层面,并发的程序也可以顺序执行,在多核CPU上才可能真正同时的运行,并行关注的是程序的运行层面,如GPU中对图像处理都会…

    数据库 2023年6月16日
    072
  • Java基础七—Java并发基础

    一个类在可以被多个线程安全调用时就是线程安全的。 线程安全不是一个非真即假的命题,可以将共享数据按照安全程度的强弱顺序分成以下五类: 不可变、绝对线程安全、相对线程安全、线程兼容和…

    数据库 2023年6月6日
    0251
  • JAVA oa 办公系统模块 设计方案

    1.模型管理 :web在线流程设计器、预览流程xml、导出xml、部署流程 2.流程管理 :导入导出流程资源文件、查看流程图、根据流程实例反射出流程模型、激活挂起 、自由跳转 3….

    数据库 2023年6月6日
    082
  • 17-二分查找

    * import java.util.Arrays; import java.util.Random; import java.util.Scanner; public class…

    数据库 2023年6月16日
    078
  • JDBC

    JDBC 一、JDBC概述 什么是JDBC? JDBC 是使用 Java 语言操作关系型数据库的一套 API。这套 API 是交由不同的数据库厂商实现的。我们利用 JDBC 编写操…

    数据库 2023年6月14日
    0106
  • 设计模式之工厂方法

    一、工厂方法:简单工厂违背了单一职责原则,而且不利于扩展,于是衍生了工厂方法模式,该模式能很好地解决对扩展开放、对修改关闭的需求。 二、实现思路 :对每一个对象都创建一个对应的工厂…

    数据库 2023年6月14日
    0115
  • centos 自己常用命令

    tar 1. 使用tar压缩文件 tar -zcvf test.tar.gz ./test/ 该命令表示压缩当前文件夹下的文件夹test,压缩后缀名为test.tar.gz 如果不…

    数据库 2023年6月11日
    081
  • MySQL中实现中文转拼音

    — 插入数据 INSERT INTO t_base_pinyin ( pin_yin_, code_ ) VALUES ( "a", 20319 ),( &q…

    数据库 2023年5月24日
    068
  • 有趣的BUG之Stack Overflow

    今天遇到一个很有意思的bug,当程序开发完成后打包到服务器运行,总是会出现栈溢出异常,经过排查发现,问题出现在一个接口上,但这个接口逻辑并不复杂,除了几局逻辑代码外和打印语句之外也…

    数据库 2023年6月6日
    087
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球