【SSM框架 三】SpringMVC
admin
2024-03-17 23:35:32
0

文章目录

  • 三、SpringMVC
    • 1、回顾MVC
    • 2、初始springMVC
    • 3、使用注解开发
    • 4、Controller总结
      • 4.1 实现controller接口方式(不建议使用)
      • 4.2 使用注解实现
    • 5、RestFul风格
      • 5.1 传统方式操作资源
      • 5.2 使用RestFul操作资源
    • 6、重定向和转发
    • 7、接收请求参数及回显
      • 7.1 处理提交数据
      • 7.2 数据显示到前端
    • 8、乱码问题
    • 9、JSON
      • 9.1 响应直接返回字符串
      • 9.2 解析工具jackson
      • 9.3 返回的json数据乱码解决
      • 9.4 几种类型值的返回
      • 9.5 解析工具fastjson
    • 10、SSM整合
      • 10.1 搭建框架
      • 10.2 DAO层
      • 10.2 Service层
      • 10.3 Spring整合Dao
      • 10.4 Spring整合Sevice
      • 10.5 SpringMVC
      • 10.6 Controller层
      • 10.6 编写页面
    • 11、AJAX
      • 11.1 简介
      • 11.2 Ajax异步加载数据
      • 11.3 Ajax验证用户名
    • 12、拦截器
      • 12.1 介绍
      • 12.2 登录权限验证(拦截)
    • 13、文件上传和下载
      • 13.1 文件上传
      • 13.2 文件下载

三、SpringMVC

1、回顾MVC

MVC:模型(dao,service) 视图(jsp) 控制(servlet)

  1. 用户发送请求
  2. Servlet接收用户请求数据,并调用对应的业务逻辑方法
  3. 业务处理完毕,返回更新后的数据给Servlet
  4. Servlet转向jsp,由jsp来渲染页面
  5. 响应给前端更新后的页面

职责分析

1. Controller:控制器- 取得表单数据- 调用业务逻辑- 转向指定页面
2. Model:模型- 业务逻辑- 保存数据的状态
3. View:视图- 显示页面 

2、初始springMVC

我们可以将springMVC中使用的所有bean注册到spring中

Spring的web框架围绕DispatcherServlet设计,DispatcherServlet它的作用是将请求分发到不同的处理器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YzlFUPG8-1670147240885)(D:\Java\Markdown\java学习笔记\05第五阶段:SSM框架.assets\image-20221124150719846.png)]

1.导入依赖

org.springframeworkspring-webmvc5.3.23


javax.servletjstl1.2

  1. 配置dispatcherServlet

web.xml


springmvcorg.springframework.web.servlet.DispatcherServletcontextConfigLocationclasspath:springmvc-servlet.xml1springmvc/

3.编写spring的配置文件

springmvc-servlet.xml




4.编写Controller

package com.daban.controller;import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class HelloController implements Controller {@Overridepublic ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {ModelAndView mv = new ModelAndView();//业务代码mv.addObject("msg","这是响应的数据");//设置视图跳转mv.setViewName("hello");return mv;}
}

5.编写显示页面(jsp)

hello.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

Title


${msg}


6.启动tomcat测试

如果报404,检查一下编译输出目录out有没有lib包导出

3、使用注解开发

1.新建一个maven项目,导入web框架

2.编写web.xml


springmvcorg.springframework.web.servlet.DispatcherServletcontextConfigLocationclasspath:springmvc-servlet.xml1springmvc/

3.编写springmvc-servlet.xml




4.创建Controller

package com.daban.controller;import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;@Controller
public class HelloController {@RequestMapping("/hello")//请求路径public String hello(Model model){//封装数据model.addAttribute("msg","我是注解开发");return "hello";//返回的视图名字(跳转的视图)}
}

5.视图

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

Title


${msg}


注解扩展:

@Controller
@RequestMapping("/all")//如果给类加上该注解,则url变成http://localhost:8080/all/hello
@RestController//标识该类不会被视图解析器解析,返回的是一个字符串
public class HelloController {@RequestMapping("/hello")//请求路径public String hello(Model model){//封装数据model.addAttribute("msg","我是注解开发");return "hello";//返回的视图名字(跳转的视图)}
}

4、Controller总结

  • 控制器负责提供访问应用程序的行为,可以通过接口定义和注解定义两种方式实现
  • 控制器负责解析用户的请求,将其转换为模型
  • SpringMVC中的控制器可以包含多个方法

4.1 实现controller接口方式(不建议使用)

  1. web.xml配置DispatcherServlet
  2. springmvc-servlet.xml配置(处理器映射(省略),处理器适配器(省略),视图解析器)
  3. 创建类实现Controller接口,方法中封装数据,视图跳转
  4. springmvc-servlet.xml中注册控制器,注意注册控制器的id就是请求的路径
  5. 编写视图显示页面

4.2 使用注解实现

  1. web.xml配置DispatcherServlet
  2. springmvc-servlet.xml配置(扫描包,静态资源过滤,注解驱动生效,视图解析器)
  3. 创建类,使用@Controller注解标注该类是控制器
  4. 控制器中创建一个方法,该方法的返回值就是需要跳转的页面,参数为Model类型,使用参数封装数据
  5. 使用@RequestMapping(“/t2”)注解来设置该方法被请求的路径
  6. 编写视图显示页面

5、RestFul风格

概念:RestFul是一个资源定位及资源操作的风格,不是标准,也不是协议,是一种风格

5.1 传统方式操作资源

使用不同的地址,带不同的参数来实现

原始方式:http://localhost:8080/r?a=1&b=2

@Controller
public class RestFulTest {//http://localhost:8080/r?a=1&b=2@RequestMapping("/r")public String test(int a, int b , Model model){int res = a+b;model.addAttribute("msg","结果为:"+res);return "test1";}
}

5.2 使用RestFul操作资源

通过不同的请求方式实现,使用相同的地址实现不同的请求

更改后url:http://localhost:8080/r/1/2

@Controller
public class RestFulTest {//http://localhost:8080/r/1/2@RequestMapping("/r/{a}/{b}")public String test(@PathVariable int a, @PathVariable int b , Model model){int res = a+b;model.addAttribute("msg","结果为:"+res);return "test1";}
}

限定请求方式一

@Controller
public class RestFulTest {//http://localhost:8080/r/1/2@RequestMapping(value = "/r/{a}/{b}",method = RequestMethod.POST)public String test(@PathVariable int a, @PathVariable String b , Model model){String res = a+b;model.addAttribute("msg","结果为:"+res);return "test1";}
}

限定请求方式二

@GetMapping

@PostMapping

@PutMapping

@DeleteMapping

@PatchMapping

@Controller
public class RestFulTest {//http://localhost:8080/r/1/2@GetMapping("/r/{a}/{b}")public String test(@PathVariable int a, @PathVariable String b , Model model){String res = a+b;model.addAttribute("msg","结果为:"+res);return "test1";}
}

这样通过限定不同的请求方式,来使同一个地址,执行不同的方法

6、重定向和转发

return "forward:/login.jsp"; //转发到 根目录/login.jsp
return "forward:/login";     //转发到 根目录/login
return "redirect:/login.jsp";//重定向到  根目录/login.jsp
return "redirect:/login";    //重定向到  根目录/login
return "login.jsp";          //转发到,根目录/WEB-INF/jsp/login.jsp.jsp,错误用法
return "login";              //转发到  根目录/WEB-INF/jsp/login
@Controller
public class DispatcherTest {@RequestMapping("/d/t1")public String test3(Model model){model.addAttribute("msg","t3");//默认是转发,加上redirect:就是重定向return "redirect:/index.jsp";}
}

WEB-INF下的文件无法重定向

​ WEB-INF是安全目录,客户端无法访问,而重定向就相当于用户直接从客户端访问了的路径,自然就不可以啦,只有程序内部转发的时候才能转发到WEB-INF下的JSP

7、接收请求参数及回显

7.1 处理提交数据

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

    //http://localhost:8080/hello?name=123
    public String test3(String name,Model model){return "test1";
    }
    
  2. 提交域名称和处理方法的参数名不一致

    //http://localhost:8080/hello?name=123
    public String test3(@RequestParam("name") String username, Model model){return "test1";
    }
    
  3. 提交的是一个对象

    创建一个实体类,实体类的属性就是提交的参数

    //http://localhost:8080/hello?name=ss&age=12
    public String test3(User user, Model model){return "test1";
    }
    

如果使用对象的话,前端传递的参数名必须和实体类的属性名一致,否则会为null

7.2 数据显示到前端

  1. 使用ModelAndView

    可以在存储数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转

    public ModelAndView test3(ModelAndView mv){mv.addObject("msg","ModelAndView");mv.setViewName("test1");return mv;
    }
    
  2. 使用Model

    只有寥寥的几个方法,只适用于存储数据,简化操作

    public String test3(Model model){model.addAttribute("msg","信息");return "test1";
    }
    
  3. 使用ModelMap

    继承了LinkedMap,除了实现自身的一些方法,同样继承了LinkedMap的方法,操作更丰富

    public String test3(ModelMap map){map.addAttribute("msg","map");return "test1";
    }
    

8、乱码问题

加上过滤器,这里一定要注意"/“和”/*"的区别

/ :匹配所有请求,不会去匹配jsp页面
/* :匹配所有请求,包括jsp页面
encodingorg.springframework.web.filter.CharacterEncodingFilterencodingutf-8

encoding/*

9、JSON

json是js对象的字符串表示形式,它使用文本表示一个js对象信息,本质是一个字符串

var obj = {name:"zhangsan",age:12};//这是对象
var json ='{{name:"zhangsan",age:12}}'//这是json字符串

json和js对象互相转化

var obj1 = JSON.parse(json);//json字符串转js对象
var json1 = JSON.stringify(obj);//js对象转json字符串

9.1 响应直接返回字符串

@RestController //标识该类不会被视图解析器解析,返回的是一个字符串

@ResponseBody //标识该方法不会被视图解析器解析,返回的是一个字符串

9.2 解析工具jackson

对象使用toString输出样式

User{name='张三', age=12, sex='男'}

对象使用jackson转换成json字符串输出样式

{"name":"张三","age":12,"sex":"男"}
@Controller
public class UserController {@RequestMapping("/j1")@ResponseBodypublic String json() throws JsonProcessingException {User user = new User("张三",12,"男");ObjectMapper mapper = new ObjectMapper();String s = mapper.writeValueAsString(user);return s;}
}

9.3 返回的json数据乱码解决

后端响应给前端的字符串乱码解决

@RequestMapping(value = "/j1",produces = "application/json;charset=utf-8")

或这个spingmvc-servlet.xml文件中配置



9.4 几种类型值的返回

  1. 列表返回

    @Controller
    public class UserController {@RequestMapping("/j1")@ResponseBodypublic String json() throws JsonProcessingException {ArrayList list = new ArrayList<>();ObjectMapper mapper = new ObjectMapper();User user = new User("张三",12,"男");User user1 = new User("张三1",12,"男");User user2 = new User("张三2",12,"男");list.add(user);list.add(user1);list.add(user2);return mapper.writeValueAsString(list);}
    }返回值:[{"name":"张三","age":12,"sex":"男"},{"name":"张三1","age":12,"sex":"男"},{"name":"张三2","age":12,"sex":"男"}]
    
  2. 时间返回

    @Controller
    public class UserController {@RequestMapping("/j1")@ResponseBodypublic String json() throws JsonProcessingException {ObjectMapper mapper = new ObjectMapper();Date date = new Date();return mapper.writeValueAsString(date);}
    }返回值:1669365101815
    
    @Controller
    public class UserController {@RequestMapping("/j1")@ResponseBodypublic String json() throws JsonProcessingException {ObjectMapper mapper = new ObjectMapper();//设置一个我们喜欢的时间格式SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");//关闭ObjectMapper的自动转换时间格式功能mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);//设置使用自己的时间格式mapper.setDateFormat(dateFormat);Date date = new Date();return mapper.writeValueAsString(date);}
    }返回值:"2022-11-25 04:41:45"
    

9.5 解析工具fastjson

依赖

com.alibabafastjson2.0.19

//java对象转json字符串
String s = JSON.toJSONString(list);
System.out.println("java对象转json字符串(列表):"+s);
String us = JSON.toJSONString(user);
System.out.println("java对象转json字符串(对象):"+us);
//json字符串转Java对象
JSONObject javaObj = JSON.parseObject(us);
System.out.println("json字符串转Java对象:"+javaObj);
//java对象转json对象
JSONObject jsonObject = (JSONObject) JSON.toJSON(user1);
System.out.println("java对象转json对象:"+jsonObject);
//json对象转java对象
User user3 = JSON.toJavaObject(jsonObject, User.class);
System.out.println("json对象转java对象:"+user3);

10、SSM整合

10.1 搭建框架

  1. 创建一个数据库

    CREATE DATABASE `ssmbuild`;USE `ssmbuild`;
    DROP TABLE IF EXISTS `books`;CREATE TABLE `books`(`bookID`  INT(10) NOT NULL AUTO_INCREMENT COMMENT '书id',`bookName` VARCHAR(100) NOT NULL COMMENT '书名',`bookCounts` VARCHAR(11) NOT NULL COMMENT '数量',`detail` VARCHAR(200) NOT NULL COMMENT '描述',KEY `bookID` (`bookID`)
    )ENGINE INNODB DEFAULT CHARSET=utf8;INSERT INTO `books`(`bookID`,`bookName`,`bookCounts`,`detail`) 
    VALUES
    (1,'三国演义',10,'三国'),
    (2,'西游记',8,'孙悟空'),
    (3,'红楼梦',32,'贾府,林黛玉'),
    (4,'水浒传',6,'梁山好汉三结义'),
    (5,'三体',43,'科技之光'),
    (6,'射雕英雄传',98,'金庸大作');
    
  2. 创建一个Maven项目

    导入依赖

    
    junitjunit4.12
    
    
    mysqlmysql-connector-java5.1.47
    
    
    com.mchangec3p00.9.5.2
    
    
    javax.servletservlet-api2.5
    
    javax.servlet.jspjsp-api2.2
    
    javax.servletjstl1.2
    
    
    org.mybatismybatis3.5.11
    
    org.mybatismybatis-spring2.0.7
    
    
    org.springframeworkspring-webmvc6.0.0
    
    org.springframeworkspring-jdbc6.0.0
    
    
  3. 创建配置文件mybatis-config.xml

    
    
    
    
  4. 创建数据源database.properties

    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&useUnicode=true&characterEncoding=utf-8
    jdbc.username=root
    jdbc.password=123456
    
  5. 创建spring空配置文件ApplicationContext.xml

    
    
    

10.2 DAO层

  1. 创建books实体类

    package com.daban.pojo;public class Books {private int bookID;private String bookName;private String bookCounts;private String detail;public Books(int bookID, String bookName, String bookCounts, String detail) {this.bookID = bookID;this.bookName = bookName;this.bookCounts = bookCounts;this.detail = detail;}public int getBookID() {return bookID;}public void setBookID(int bookID) {this.bookID = bookID;}public String getBookName() {return bookName;}public void setBookName(String bookName) {this.bookName = bookName;}public String getBookCounts() {return bookCounts;}public void setBookCounts(String bookCounts) {this.bookCounts = bookCounts;}public String getDetail() {return detail;}public void setDetail(String detail) {this.detail = detail;}@Overridepublic String toString() {return "Books{" +"bookID=" + bookID +", bookName='" + bookName + '\'' +", bookCounts='" + bookCounts + '\'' +", detail='" + detail + '\'' +'}';}
    }
    
  2. 创建接口BookMapper.java

    package com.daban.dao;import com.daban.pojo.Books;
    import org.apache.ibatis.annotations.Param;import java.util.List;public interface BookMapper {//增加一本书int addBook(Books books);//删除一本书int deleteBookById(@Param("bookId") int id);//修改一本书int updateBook(Books books);//查询一本书Books queryBookById(@Param("bookId") int id);//查询全部书List queryAllBook();List queryBookByName(String bookName);
    }
    
  3. 创建接口映射文件BookMapper.xml

    
    
    insert into ssmbuild.books(bookName, bookCounts, detail)values (#{bookName},#{bookCounts},#{detail});delete from ssmbuild.books where bookID = #{bookId};update ssmbuild.booksset bookName = #{bookName},bookCounts=#{bookCounts},detail=#{detail}where bookID = #{bookID};
    
    
  4. 在mybatis配置文件中注册mapper

    
    
    

10.2 Service层

  1. 创建接口BookService.java

    package com.daban.service;import com.daban.pojo.Books;
    import java.util.List;public interface BookService {//增加一本书int addBook(Books books);//删除一本书int deleteBookById(int id);//修改一本书int updateBook(Books books);//查询一本书Books queryBookById(int id);//查询全部书List queryAllBook();List queryBookByName(String bookName);
    }
    
  2. 创建接口的实现类BookServiceImp.java

    package com.daban.service;import com.daban.dao.BookMapper;
    import com.daban.pojo.Books;import java.util.List;public class BookServiceImp implements BookService{//业务层调dao层private BookMapper bookMapper;public void setBookMapper(BookMapper bookMapper) {this.bookMapper = bookMapper;}@Overridepublic int addBook(Books books) {return bookMapper.addBook(books);}@Overridepublic int deleteBookById(int id) {return bookMapper.deleteBookById(id);}@Overridepublic int updateBook(Books books) {return bookMapper.updateBook(books);}@Overridepublic Books queryBookById(int id) {return bookMapper.queryBookById(id);}@Overridepublic List queryAllBook() {return bookMapper.queryAllBook();}@Overridepublic List queryBookByName(String bookName) {return bookMapper.queryBookByName(bookName);}}
    

10.3 Spring整合Dao

  1. 创建spring-dao.xml

    
    
    
    

10.4 Spring整合Sevice

  1. 创建spring-service.xml

    
    
    

10.5 SpringMVC

  1. 增加web支持

  2. 配置web.xml

    这里有一个兼容文件,在配置DispatcherServlet时报错,把spring-webmvc依赖版本改成5.3.23

    
    springmvcorg.springframework.web.servlet.DispatcherServletcontextConfigLocationclasspath:ApplicationContext.xml1springmvc/encodingorg.springframework.web.filter.CharacterEncodingFilterencodingutf-8encoding/*15
    
    
  3. 创建配置spring-mvc.xml

    
    
    
    
  4. 将spring配置文件统一到ApplicationContext中

    
    
    
    

10.6 Controller层

  1. 创建一个控制类BookController.java

    package com.daban.controller;import com.daban.pojo.Books;
    import com.daban.service.BookService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;import java.util.List;@Controller
    @RequestMapping("/book")
    public class BookController {@Autowired@Qualifier("BookServiceImp")private BookService bookService;//查询所有书籍@RequestMapping("/allBook")public String allBook(Model model){List books = bookService.queryAllBook();model.addAttribute("boos",books);return "allBook";}//跳转到新增书籍页面@RequestMapping("/addBookPage")public String toAddBookPage(){return "addBookPage";}//执行添加书籍@RequestMapping("/addBook")public String addBook(Books books){//System.out.println(books);bookService.addBook(books);return "redirect:/book/allBook";//return "allBook";}//跳转到书籍修改页@RequestMapping("/updateBookPage")public String toUpdateBookPage(int id,Model model){Books book = bookService.queryBookById(id);model.addAttribute("book",book);return "updateBookPage";}//执行修改书籍@RequestMapping("/updateBook")public String updateBook(Books books){System.out.println(books);bookService.updateBook(books);return "redirect:/book/allBook";}//删除数据@RequestMapping("/deleteBook")public String deleteBook(int id){bookService.deleteBookById(id);return "redirect:/book/allBook";}//查询书籍@RequestMapping("/queryBookByName")public String queryBook(String queryBookName,Model model){List books = bookService.queryBookByName("%"+queryBookName+"%");//System.out.println(books);if(books.size()==0){model.addAttribute("error","没有查到内容");}else{model.addAttribute("boos",books);}return "allBook";}
    }
    

10.6 编写页面

页面其实和Controller层同步写的

  1. 编写首页index.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    首页

    全部书籍

  2. 编写allbook.jsp

    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
    查询全部书籍
    
    
    

    书籍列表——————显示所有书籍

    书籍编号书籍名称书籍数量书籍描述操作
    ${book.bookID}${book.bookName}${book.bookCounts}${book.detail}修改  | 删除
  3. 编写addBookPage.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
    添加书籍
    
    
    

    添加书籍

  4. 编写updateBookPage.jsp

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
    修改书籍
    
    
    

    修改书籍

    <%-- 一定要注意这个隐藏的字段,没有id没办法修改--%>

11、AJAX

11.1 简介

他是一个在无需刷新网页的情况下,能够更新部分网页数据的技术

Ajax的核心是XMLHttpRequest对象(XHR)

jQuery提供了多个与ajax相关的方法

jQuery静态资源找不到问题

  • spring配置文件没有加这个语句,过滤静态资源使不经过servlet
  • 增加了静态资源后必须重新启动服务器
function a(){$.ajax({//请求地址url:"${pageContext.request.contextPath}/a2",//请求数据data:{"name":$("#username").val()},//成功回调函数,带返回数据data,这个参数是键值对success:function (data) {alert(data);console.log("执行的成功的回调函数");},//失败回调函数error:function () {console.log("执行的失败的回调函数");}})
}

11.2 Ajax异步加载数据

  • 实体类

    package com.daban.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;
    }
    
  • 控制层

    @RequestMapping("/a3")
    public List a3(){ArrayList userList = new ArrayList<>();userList.add(new User("张三",32,"男"));userList.add(new User("李四",12,"女"));userList.add(new User("王五",52,"男"));userList.add(new User("王留",22,"男"));return userList;
    }
    
  • 页面

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
    Title
    
    
    姓名年龄性别

11.3 Ajax验证用户名

  • 控制层

    @RequestMapping(value = "/a4",produces = "text/html;charset=utf-8")
    public String a4(String name){if(name.equals("ss")){return "OK";}elsereturn "用户名不存在";
    }
    
  • 页面

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    
    Title
    
    用户名:
    密码:

12、拦截器

12.1 介绍

SpringMVC的拦截器类似于servlet中的过滤器Filter

拦截器是AOP思想的具体应用,意思拦截器就是横切进去的

拦截器只会拦截访问控制器的方法,静态页面放行,自带静态资源过滤

自定义拦截器(实现HandlerInterceptor接口):

package com.daban.config;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("===========拦截前===========");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("===========拦截后===========");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("===========清理===========");}
}

在springmvc中配置拦截器,才能使用



12.2 登录权限验证(拦截)

控制器:

@RequestMapping("/login")
public String login(HttpSession session, String name, String pwd, Model model){//如果name或pwd为空,则说明是使用session越权登录,正常跳转//否则是正常登陆,需要验证用户名密码if(name==null || pwd==null){return "main";}else {if(name.equals("zj") && pwd.equals("123")){session.setAttribute("username",name);return "main";}else{model.addAttribute("msg","账号或密码错误");return "forward:/login.jsp";}}}
@RequestMapping("/logout")
public String logout(HttpSession session){session.removeAttribute("username");return "redirect:/login.jsp";
}

拦截器:

package com.daban.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 {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {HttpSession session = request.getSession();Object username = session.getAttribute("username");String name = request.getParameter("name");String pwd = request.getParameter("pwd");//如果name和pwd都不为空,则是正常登录,需要放行if (name!=null && pwd!=null){return true;}//如果name和pwd字段为空,则表示越权登陆,就需要判断是否有session//如果有session则放行,没session则重定向if(username!=null){return true;}else {response.sendRedirect("/login.jsp");}return false;}
}

13、文件上传和下载

要使用spring的上传功能,需要上下文中配置MultipartResolver

前端表单必须是post,enctype设置为multipart/form-data

表单属性enctype说明

  • application/x-www=form-urlencoded,默认方式,只处理表单中的value
  • multipart/form-data,以二进制流处理表单,把文件内容封装到请参数中,不会对字符编码
  • text/plain,除了把空格转换成+号外,其他字符不做编码,这种适合表单发邮件

13.1 文件上传

步骤:

  1. 导入文件上传的jar包

    commons-fileuploadcommons-fileupload1.4
    
    javax.servletjavax.servlet-api4.0.1
    
    
  2. 写提交页面

    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    $Title$
  3. spring配置文件中配置

    
    
    
    
  4. 写controller

    • 方法一

      package com.daban.controller;import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestParam;
      import org.springframework.web.multipart.commons.CommonsMultipartFile;import javax.servlet.http.HttpServletRequest;
      import java.io.File;
      import java.io.FileOutputStream;
      import java.io.IOException;
      import java.io.InputStream;@Controller
      public class FileController {//将表单中name属性为file的控件得到的文件封装成CommonsMultipartFile对象//批量上传,CommonsMultipartFile为数组即可//注意重点,CommonsMultipartFile必须加@RequestParam("file"),否则报空指针@RequestMapping("/upload")public String upload(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {//获取文件名String filename = file.getOriginalFilename();//如果文件为空,则直接回到首页System.out.println("文件名:"+filename);if("".equals(filename)){return "redirect:/index.jsp";}//上传路径保存设置String path = request.getServletContext().getRealPath("/upload");//如果路径不存在,创建一个File realPath = new File(path);if(!realPath.exists()){realPath.mkdir();}System.out.println("上传路径:"+realPath);InputStream is = file.getInputStream();FileOutputStream fos = new FileOutputStream(new File(realPath, filename));int len=0;byte[] buffer = new byte[1024];while ((len=is.read(buffer))!=-1){fos.write(buffer,0,len);fos.flush();}is.close();fos.close();return "redirect:/index.jsp";}
      }
      
    • 方法二

      package com.daban.controller;import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.RequestMapping;
      import org.springframework.web.bind.annotation.RequestParam;
      import org.springframework.web.multipart.commons.CommonsMultipartFile;import javax.servlet.http.HttpServletRequest;
      import java.io.File;
      import java.io.FileOutputStream;
      import java.io.IOException;
      import java.io.InputStream;@Controller
      public class FileController {//将表单中name属性为file的控件得到的文件封装成CommonsMultipartFile对象//批量上传,CommonsMultipartFile为数组即可//注意重点,CommonsMultipartFile必须加@RequestParam("file"),否则报空指针@RequestMapping("/upload")public String upload(@RequestParam("file")CommonsMultipartFile file, HttpServletRequest request) throws IOException {//获取文件名String filename = file.getOriginalFilename();//上传路径保存设置String path = request.getServletContext().getRealPath("/upload");//如果路径不存在,创建一个File realPath = new File(path);if(!realPath.exists()){realPath.mkdir();}//通过CommonsMultipartFile的方法直接写文件file.transferTo(new File(realPath+"/"+filename));return "redirect:/index.jsp";}
      }
      

13.2 文件下载

写controller

package com.daban.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.commons.CommonsMultipartFile;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;@Controller
public class FileController {@RequestMapping("/download")public String download(HttpServletRequest request, HttpServletResponse response) throws Exception {//要下载文件的地址String path = request.getServletContext().getRealPath("/upload");String fileName = "123.md";//设置响应头response.reset();//设置响应页面不缓存,清空bufferresponse.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);FileInputStream fis = new FileInputStream(file);OutputStream os = response.getOutputStream();byte[] buffer = new byte[1024];int len = 0;while ((len=fis.read(buffer))!=-1){os.write(buffer,0,len);os.flush();}os.close();fis.close();return null;}
}

相关内容

热门资讯

邮储银行行长芦苇兼任公司首席合... 5月26日,邮储银行发布董事会决议公告,邮储银行行长芦苇自2026年5月26日起兼任邮储银行首席合规...
我愿意二次到店吗?小店主理人交... 来源:滚动播报 (来源:上观新闻) 咖啡店主理人可以去餐饮店体验一天,感受烟火气和客流管理;手工...
原创 深... 当政策暖风遇上资产配置需求,深圳楼市正上演一场“热度与信心齐飞”的戏码!上周(5.18-5.24),...
被封千万网红大蓝卷土重来:拉人... 蓝鲸新闻5月26日讯(记者 赵凯)“朋友圈散布经济恐慌言论制造焦虑,拉人头设多级返利,数百人入局、累...
抖音商城618前六日数据:消费... “清凉经济”热度高:抖音商城618首阶段空气循环扇订单量同比增长348% 作者 I 钱游 报道 I ...
金华有闲置贵金属想变现该怎么挑... 当下闲置物品处置、短期资金周转的需求日渐普遍,市面上的相关服务机构水平参差不齐,不少有黄金回收需求的...
千亿市值芯片企业完成IPO辅导... 【大河财立方消息】5月26日,新三板挂牌企业宸芯科技股份有限公司(证券简称:宸芯科技)公告,收到青岛...
NBBOSS R1全球首发 重... 5月26日,信人智能旗下全球首款企业家专属AI决策伙伴NBBOSS AI决策机器人R1正式全球首发。...
NFC果汁配料表“水”排第一?... 随着气温升高,果汁进入消费旺季。然而很多果汁产品的标注却让消费者感到困惑。比如:有的标注“纯果汁”,...
存储牛市与全民狂热:韩国股市泡... 2026年5月的韩国,正经历一场史无前例的资本狂欢。自2025年4月触底以来,KOSPI指数在18个...
下架,召回!双汇子公司猪肉抗生... 近日,黑龙江省市场监督管理局网站发布关于食品安全监督抽检信息的通告(2026年第7期)。 其中,望奎...
换帅潮席卷白酒圈 白酒本轮人事变动频次之高、画像之多元,几乎超过了过去任何一个周期。 5月19日,“河北王”老白干酒宣...
4月意大利起泡酒猛增122.5... 近日,海关总署公布了2026年4月葡萄酒进口数据。其中,起泡酒表现尤为突出,进口量同比增长35.8%...
华为“韬定律”提振港股半导体股... 财联社5月26日讯(编辑 胡家荣)半导体产业链个股集体走强。截至发稿,华虹半导体(01347.HK)...
历史不会重演,但会惊人相似:中... 金价疯涨别乱买!复刻2015年走势,普通人记住3个保命妙招 最近逛商场,最大的感受就是黄金柜台太热闹...
商品标签被指涉嫌性暗示,盒马道... 近日,盒马旗下一款粉木耳产品因标签设计引发争议,不少网友吐槽该商品标签低俗,涉嫌性暗示。 25日晚...
东莞一上市公司董事会“换血”,... 近日,易事特集团股份有限公司发布《关于董事会完成换届选举及聘任高级管理人员、证券事务代表暨公司控制权...
做宠物食品,已经很难赚到钱了? 流量争夺战里没有赢家 撰文/ 黎炫岐 编辑/ 李觐麟 排版/ Annalee “它经济”,一个持续升...
2万亿美元!SpaceX上市前... “你想在早上醒来时觉得未来会很美好——而这正是成为太空文明的全部意义所在。它关乎相信未来,并认为未来...