文章目录
1. SpringMVC
- 重点:SpringMvc的执行流程
- MVC:模型,视图,控制器
1.1 学习springMVC的必要性
- 轻量级,简单易学
- 高效,基于请求响应的MVC框架
- 与Spring兼容性好,无缝结合
- 约定优于配置
- 功能强大,RestFul,数据验证,格式化,本地化,主题等
- 简单灵活
1.2 核心DispatcherServlet
- 作用:DispatcherServlet的作用是将请求分发到不同的处理器。Spring2.5开始可以使用注解实现,十分简洁。
- 继承关系
- SpringMvc的原理:
当发起请求时被前端控制器拦截到请求,根据请求参数生成代理请求,找到请求对应的实际控制器 ,控制器处理请求,创建数据模型,访问数据库,将模型响应给中心控制器,控制器使用模型与视图渲染视图结果,将结果返回给中心控制器,在将结果响应给请求者。
- SpringMVC执行原理
- HandlerMapping:处理器映射,DispatcherServlet调用HandlerMapping根据请求url查找Handler
- HandlerExecution表示具体的Handler,根据url查找控制器,将解析后的信息传递给DispatcherServlet
- HandlerAdapter:处理器适配器,按照特定的规则执行Handler
- Handler让具体的Controller执行
- Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView
- HandlerAdapter将视图和模型传DispacherServlet,DispacherServlet调用视图解析器ViewResolver解析逻辑视图名,将结果返回给DispacherServlet
- DispacherServlet根据视图解析器解析的视图结果,调用具体视图,将渲染的视图返回给用户。
1.3 第一个SpringMVC程序
- 新建maven模块
- 导入依赖springMVC依赖
- 配置web.xml,注册DispatcherServlet
<?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">
<!-- 注册DispatcherServlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- 绑定springmvc-servlet配置文件-->
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<!-- 设置启动级别,web应用启动servlet立即加载-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
- 配置tomcat:注意:将WEB_INF下的lib包的jar一起打包
- 配置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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 注册处理器映射器-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!-- 注册处理器适配器-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!-- 配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean id="/login" class="com.wu.controller.LoginController"/>
</beans>
- 实现Controller接口
public class LoginController implements Controller {
public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("msg", "登录信息");
modelAndView.setViewName("login");
return modelAndView;
}
}
1.4 控制器Controller
- 控制器复杂提供访问应用程序的行为,通常通过接口定义或注解定义两种方式实现
- 控制器复杂解析用户的请求并将其转化为模型。
1.5 基于注解的Controller
- 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 http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 2.使用注解-->
<!-- 注解扫描-->
<context:component-scan base-package="com.wu.controller"/>
<!-- 使用默认的servlet处理器-->
<mvc:default-servlet-handler/>
<!-- 开启注解驱动-->
<mvc:annotation-driven/>
<!-- 配置视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
- Controller
@Controller
public class LoginAnnoController {
@RequestMapping("/login")
public String login(Model model){
model.addAttribute("msg","登录哈哈");
return "login";
}
}
1.6 Restful风格
@GetMapping("/{a}/{b}")
public String restful(@PathVariable int a, @PathVariable int b,Model model){
model.addAttribute("msg","restful:"+(a+b)+"");
return "login";
}
@PostMapping("/{a}/{b}")
public String restfulPost(@PathVariable int a, @PathVariable int b,Model model){
model.addAttribute("msg","restfulPOST:"+(a+b)+"");
return "login";
}
作用:
- 简洁:使用注解绑定变量
- 高效:可以使用缓存
- 安全:前端参数不可见
2. 转发和重定向
@GetMapping("/{a}/{b}")
public String restful(@PathVariable int a, @PathVariable int b,Model model){
model.addAttribute("msg","restful:"+(a+b)+"");
return "redirect:/index.jsp";
}
@PostMapping("/{a}/{b}")
public String restfulPost(@PathVariable int a, @PathVariable int b,Model model){
model.addAttribute("msg","restfulPOST:"+(a+b)+"");
// 默认/是转发,forward:可以省略
return "forward:/WEB-INF/jsp/login.jsp";
}
注意:重定向无法直接访问到WEB-INF目录下的资源,需要在Controller中进行处理
3.接受请求参数绑定和数据回显
- 前端参数绑定:@RequestParam(“username”)
@GetMapping("/test")
// @RequestParam("username"):前端请求参数绑定
public String reserve(@RequestParam("username") String name,Model model){
model.addAttribute("msg",name);
return "login";
}
- 如果不使用@RequestParam绑定参数前端传递参数必须和后端的参数名相同。
- 将前端传递的参数封装为对象,前端传递对象数据,前端传递的参数名必须与对象的成员变量相同
@GetMapping("/user")
public String UserData(User user,Model model){
model.addAttribute("msg",user);
return "login";
}
- Model,ModelMap,ModelAndView
- Model:只要几个方法适合存储数据,简化操作
- ModelMap:继承了LinkedMap,除了实现了自身方法,继承了LinkedMap的方法和特征
- ModelAndView:在存储数据的同时,可以设置返回的逻辑视图,进行控制展示层的跳转。
4. 乱码问题解决
1.url请求传递参数乱码:过滤器解决:在web.xml中配置过滤器
<!--配置解决中文乱码的过滤器-->
<filter>
<filter-name>characterEncodingFilter</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>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2.json字符串乱码:springmvc.xml配置
- 方法一:在controller接收参数时,对参数进行转码
@RequestMapping(value = "/json",produces = "application/json; charset=utf-8")
- 方法二:springMvc配置文件中设置JSON数据转换(推荐)
<!-- 处理请求返回json字符串的乱码问题 -->
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 注解请求映射
默认是ISO-88859-1,避免乱码这里设置为UTF-8 -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value="text/html;charset=UTF-8" />
</bean>
<!-- 启动JSON格式的配置,自动将格式转换成JSON格式,不需要其他类 -->
<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="supportedMediaTypes" value="application/json;charset=UTF-8" />
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
5.java对象转化为json字符串传递给前端
方式一:.jackson:注意spring版本与jackson版本兼容问题
- 导入jar:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
测试代码:
//@RestController:类下的所有方法不会进行视图解析,返回字符串
//@ResponseBody:作用与方法,方法返回字符串
@RestController
public class JsonController {
@GetMapping(value = "/json")
public String test() throws JsonProcessingException {
User user = new User(1, "杨幂", 45);
return new ObjectMapper().writeValueAsString(user);
}
}
方式二:faskjson
1.导入jar:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
2.测试:
@GetMapping("/faskjson")
public String test2(){
User user = new User(1, "沈腾", 66);
return JSON.toJSONString(user);
}
3.SSM框架整合
- 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">
<!-- Spring的监听器,加载spring核心配置-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- DispatcherServlet-->
<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.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>encodingFilter</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>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 过期时间-->
<session-config>
<session-timeout>15</session-timeout>
</session-config>
</web-app>
- 接口:
public interface BookMapper {
int addBook(Book book);
int deleteBookById(@Param("id") int id);
int updateBookById(Book book);
Book queryBookById(@Param("id")int id);
List<Book> queryAllBooks();
List<Book> queryByName(String name);
}
- 实体类Book:
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Book {
private int bookID;
private String bookName;
private int bookCounts;
private String detail;
}
- BookMapper.xml:
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wu.dao.BookMapper">
<insert id="addBook" parameterType="Book">
insert into books values (null,#{bookName},#{bookCounts},#{detail})
</insert>
<delete id="deleteBookById" parameterType="int">
delete from books where bookID=#{id}
</delete>
<update id="updateBookById" parameterType="book">
update books set bookName=#{bookName},bookCounts=#{bookCounts},detail=#{detail} where bookID=#{bookID}
</update>
<select id="queryBookById" parameterType="int" resultType="book">
select * from books where bookID=#{id}
</select>
<select id="queryAllBooks" resultType="book">
select * from books
</select>
<select id="queryByName" parameterType="String" resultType="book">
select * from books where bookName like concat("%",#{bookName},"%")
</select>
</mapper>
- mybatis-config.xml:
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--特别注意:
MyBatis中的配置,不但有类型限制,还有顺序限制
必须按照:<properties>、<settings>、<typeAliases>、<typeHandlers>、…顺序排放。-->
<configuration>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!-- 每一个Mapper.xml都需要在Mybatis核心配置文件中注册-->
<typeAliases>
<package name="com.wu.pojo"/>
</typeAliases>
</configuration>
- spring-dao.xml:spring整合mybatis配置文件:
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config></context:annotation-config>
<!-- 扫描包下的注解,排除Controler层-->
<context:component-scan base-package="com.wu">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 加载外部配置文件-->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 数据源-->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="${jdbc.url}"/>
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 引用数据源-->
<property name="dataSource" ref="dataSource"/>
<!-- 绑定mybatis配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!-- 绑定mapper接口的配置文件-->
<property name="mapperLocations" value="classpath:mapper/*Mapper.xml"/>
</bean>
<!-- 配置dao接口扫描包,动态实现Dao接口可以注入到spring容器中,
MapperScannerConfigurer将扫描basePackage所指定的包下的所有接口类(包括子类),
如果它们在SQL映射文件中定义过,则将它们动态定义为一个Spring Bean,这样,我们在Service中就可以直接注入映射接口的bean-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 注入sqlSessionFactory-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!-- 要扫描的包-->
<property name="basePackage" value="com.wu.dao"/>
</bean>
<!-- 声明式事务-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据源-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- aop事务支持-->
</beans>
- springmvc.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 http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 1.注解驱动-->
<mvc:annotation-driven/>
<!-- 2.开启组件扫描-->
<context:component-scan base-package="com.wu.controller"/>
<!-- 3.开放静态资源访问权限-->
<mvc:default-servlet-handler/>
<!-- 4.视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
- 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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="spring-dao.xml"/>
<import resource="springmvc.xml"/>
</beans>
- service接口:
public interface BookService {
int addBook(Book book);
int deleteBookById(@Param("id") int id);
int updateBookById(Book book);
Book queryBookById(@Param("id")int id);
List<Book> queryAllBooks();
List<Book> queryByName(String name);
}
- Service实现类:
@Setter
@Service
public class BookServiceImpl implements BookService {
@Autowired
private BookMapper bookMapper;
public int addBook(Book book) {
return bookMapper.addBook(book);
}
public int deleteBookById(int id) {
return bookMapper.deleteBookById(id);
}
public int updateBookById(Book book) {
return bookMapper.updateBookById(book);
}
public Book queryBookById(int id) {
return bookMapper.queryBookById(id);
}
public List<Book> queryAllBooks() {
return bookMapper.queryAllBooks();
}
public List<Book> queryByName(String name) {
return bookMapper.queryByName(name);
}
- Controller:
import java.util.List;
@Controller
public class BookController {
@Autowired
private BookService bookService;
@GetMapping("/allbooks")
public String test(Model model, @ModelAttribute("msgbook") String msgbook){
List<Book> books= bookService.queryAllBooks();
model.addAttribute("msg",books);
model.addAttribute("msgbook",msgbook);
return "allBooks";
}
@GetMapping("/toaddBook")
public String toaddBook(){
return "addBook";
}
@PostMapping("/addBook")
public String addBook(Book book, RedirectAttributes model){
int x = bookService.addBook(book);
if (x>0){
model.addAttribute("msgbook","添加成功!");
}else {
model.addAttribute("msgbook","添加失败");
}
return "redirect:/allbooks";
}
@GetMapping("/toUpdate")
public String toUpdate(int id,Model model){
Book book = bookService.queryBookById(id);
model.addAttribute("book",book);
return "updateBook";
}
@PostMapping("/updateBook")
public String updateBook(Book book){
bookService.updateBookById(book);
return "redirect:/allbooks";
}
@GetMapping("/delete")
public String delete(int id){
bookService.deleteBookById(id);
return "redirect:/allbooks";
}
@PostMapping("/queryByName")
public String queryByName( String bookName,Model model){
List<Book> book = bookService.queryByName(bookName);
if (book!=null){
model.addAttribute("msg",book);
}
return "allBooks";
}
1.AJAX
- 登录功能前端用户名密码校验
login.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>login</title>
<script src="/static/js/jquery-3.5.1.js"></script>
<script>
function a() {
$.post({
url:"/login",
data:{"name":$("#name").val()},
success:function (data) {
if (data.toString()=="ok"){
$("#userInfo").css("color","green");
}else {
$("#userInfo").css("color","red");
}
$("#userInfo").html(data);
}
})
}
function b() {
$.post({
url:"/login",
data:{"password":$("#pwd").val()},
success:function (data) {
if (data.toString()=="ok"){
$("#pwdInfo").css("color","green");
}else {
$("#pwdInfo").css("color","red");
}
$("#pwdInfo").html(data);
}
})
}
</script>
</head>
<body>
<p>
用户名:<input type="text" id="name" onblur="a()">
<span id="userInfo"></span>
</p>
<p>
密码:<input type="password" id="pwd" onblur="b()">
<span id="pwdInfo"></span>
</p>
</body>
</html>
2.后端:
@RequestMapping("/login")
public String login(String name,String password) {
String msg="";
if (name!=null){
if ("wu".equals(name)){
msg="ok";
}else {
msg="用户名错误";
}
}
if (password!=null){
if ("123".equals(password)){
msg="ok";
}else {
msg="密码错误";
}
}
return msg;
}
2.拦截器(aop)
- 过滤器:
- servlet规范的一部分,任何Javaweb工程均可使用
- 在web.xml中配置/*拦截所有访问资源Filter
- 拦截器:
- SpringMVC框架特有的,只会拦截访问控制器的方法,如果访问静态资源则不会拦截。
- 自定义拦截器:实现HandlerInterceptor接口
public class MyInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("拦截前");
return true;
}
}
springmvc.xml配置:
<!-- 拦截器配置-->
<mvc:interceptors>
<mvc:interceptor>
<!-- 拦截所有请求-->
<mvc:mapping path="/**"/>
<bean class="com.wu.controller.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
作用:一般用于对登录权限拦截
3.文件上传和下载
- 导入jar:
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
- 配置springmvc.xml的上传文件配置
<!-- 文件上传配置-->
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
<!-- 请求编码格式,必须和jsp的pageEncoding的属性一致,以便正确读取表单内容,默认ISO-8859-1-->
<property name="defaultEncoding" value="utf-8"/>
<!-- 上传文件大小限制,单位字节10485760=10M-->
<property name="maxUploadSize" value="10485760"/>
<property name="maxInMemorySize" value="40960"/>
</bean>
- Controller层:2种上传文件方式
@PostMapping("/upload")
public String fileUpload(@RequestParam("file")CommonsMultipartFile file, HttpServletRequest request) throws IOException {
// 获取文件名
String originalFilename = file.getOriginalFilename();
// 如果文件名为空,直接返回首页
if ("".equals(originalFilename)){
return "redirect:/index.jsp";
}
System.out.println("上传文件名:"+originalFilename);
// 上传路径保存设置
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 os = new FileOutputStream(new File(realPath, originalFilename));
// 保存上传文件
int len=0;
byte[] buffer=new byte[1024];
while ((len=is.read(buffer))>0){
os.write(buffer,0,len);
os.flush();
}
os.close();
is.close();
return "redirect:/index.jsp";
}
@PostMapping("/upload2")
public String upload2(@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";
}
4.文件下载:
@RequestMapping("/download")
@ResponseBody
public String download(HttpServletResponse response,HttpServletRequest request) throws IOException {
String path=request.getServletContext().getRealPath("WEB-INF/img");
String fileName="a.png";
// 设置响应头
response.reset();//设置页面不缓存,清空缓存
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);
System.out.println(file);
// 读入文件
BufferedInputStream bf = new BufferedInputStream(new FileInputStream(file));
// 写出文件
ServletOutputStream os = response.getOutputStream();
int len=0;
byte[] bufffer=new byte[1024];
while ((len=bf.read(bufffer))!=-1){
os.write(bufffer,0,len);
}
os.close();
bf.close();
return "下载完成";
}
注意:文件上传下载优化
- 上传文件放在WEB-INF目录下,浏览器不能直接访问,安全性较高
- 限制文件上传的大小,springmvc.xml文件配置
- 指定上传文件的类型,后端通过文件后缀分别处理