【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;}
}

相关内容

热门资讯

太平鸟数字化转型:引领时尚行业... 在数字化时代,市场环境与消费者需求不断演变。为顺应这一趋势,太平鸟集团积极优化线上购物平台,强化社交...
港股异动 | 推出文档智能基础... 2月27日,云知声股价冲高,盘中一度涨超15%。截至10时31分,该股上涨9.36%,报346港元/...
居民存款迁移,驱动券商马年机会... 2月27日,券商板块低开震荡,板块个股走势分化,截至发稿,第一创业、国信证券涨超1%,华创云信、西部...
原创 特... 在访华前夕,特朗普又整出了大活儿。2月20日,美国最高法院以6:3的结果,裁定特朗普援引1977年《...
一图看懂埃斯顿(2715.HK... 首家登顶中国工业机器人解决方案市场的国产机器人企业——埃斯顿今日至3月4日招股,预期将于2026年3...
郎酒五大销售公司官宣!自主经营... 春节旺季余韵未消,郎酒就积极推进组织层面的重大突破。 早在去年2月27日举行的“2025年郎酒全国...
广州天河区混合型社区物业满意度... 混合型社区(含住宅、底商、公寓)的物业需兼顾居民与商户需求,(广州物业满意调查)(物业满意度调研)(...
水井坊要卖了?“酒王”正式回应 本文自南都·湾财社。 采写 | 南都·湾财社记者 张海霞 白酒调整周期下,世界酒业巨头的日子也不算好...
春节期间金银珠宝类商品销售激 ... 2月27日,梦金园(02585.HK)股价震荡走高,盘中一度踏上24.88港元/股,创下上市以来的新...
突发!离岸人民币短线跳水 2月27日早间,离岸人民币兑美元汇率短线跳水,由涨转跌,失守6.85关口,引发市场广泛关注。 针对...
通光线缆控股股东及董事长拟减持... 2月26日,通光线缆(300265)公告,公司于近日收到控股股东通光集团、董事长兼总经理张忠分别出具...
中国AI调用量首超美国,算力租... 2月27日,算力租赁板块持续走高,利通电子(603629.SH)、云天励飞-U(688343.SH)...
企业才是未来产业的C位 《企业才是未来产业的C位》 ——别再用行政逻辑管理创新逻辑,让市场嗅觉带路 谁能把未来产业从“PP...
补齐AI推理拼图:英伟达黄仁勋... IT之家 2 月 27 日消息,科技媒体 Wccftech 昨日(2 月 26 日)发布博文,报道称...
酱酒和百元口粮酒春节热销,白酒... 来源:界面新闻 丙午马年春节期间,受到市场需求增加影响,白酒消费呈现出了回暖的趋势。 通过梳理各券商...
三菱日联银行、京都银行等将出售... 任天堂计划逐步减持战略股权,包括三菱日联 银行和京都银行在内的多家机构将出售任天堂股份。据悉,此次出...
原创 连... 按照美国的法律规定,每年美国总统都必须向国会报告国情咨文。而2026年的国情咨文对于特朗普来说尤为关...
2026年有实力的发动机国际空... 在全球化不断推进的今天,发动机等重要设备的国际运输需求日益增长。选择一家有实力的国际空运物流货运公司...
始祖鸟烟花风波百天:拒绝降价、... 158天前,始祖鸟联手蔡国强在喜马拉雅山脉地区举办烟花秀,引发大量关注与争议。环保风波、价值观反噬、...
日本芯片制造商Rapidus获... 【日本芯片制造商Rapidus获得16亿美元政府资金】财联社2月27日电,日本政府将向得到国家支持的...