学习资源:
b站:遇见狂神说
链接:https://www.bilibili.com/video/BV1aE41167Tu/?spm_id_from=333.999.0.0
1、第一个SpringMVC程序
maven依赖:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--配置DispatchServlet:springMVC的核心,作用是接收请求和响应结果,理解为控制器-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--DispatchServlet需要绑定springMVC的配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<!--启动级别:1-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--在springMVC中,/只匹配所有请求,不会匹配jsp页面,而/*会匹配所有请求以及jsp页面-->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
spring核心配置文件:
<?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">
<!--处理器映射器 HandlerMapping,根据请求的url来查找controller(我们定义的java类)-->
<!--BeanNameUrlHandlerMapping实现了接口HandlerMapping-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!--处理器适配器 HandlerAdapter,执行controller,最后返回一个ModelAndViews实例-->
<!--SimpleControllerHandlerAdapter实现了接口HandlerAdapter-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!--视图解析器 ViewResolver,根据ModelAndView实例来解析需要返回的视图,返回给控制器DispatcherServlet-->
<!--InternalResourceViewResolver实现了接口ViewResolver-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<!--前缀:获取请求路径的前缀(文件名前面的路径)-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀:获取请求路径的后缀(文件名后缀)-->
<property name="suffix" value=".jsp"/>
</bean>
<!--处理器映射器HandlerMapping根据客户端访问的url映射到指定的bean,根据bean的id对应的匹配相应的controller-->
<!--比如客户端访问 http://localhost:8080/hello HandlerMapping会拿到/hello,去和id对应上的bean,从而匹配相应的controller-->
<bean id="/hello" class="com.yang.controller.MyController" />
</beans>
WEB-INF下创建jsp文件夹,新进test.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
编写controller:
package com.yang.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 MyController implements Controller { // 实现Controller接口,表示该类是一个controller(控制器)
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
ModelAndView modelAndView = new ModelAndView();
// 测试数据
String result = "Hello,SpringMVC";
modelAndView.addObject("msg",result);
modelAndView.setViewName("test");
return modelAndView; // controller处理完业务后返回给视图解析器处理
}
}
最后项目打包使用Tomcat启动测试,访问 http://localhost:8080/hello
SpringMVC执行流程:
- 客户端发送请求(获取视图)
- 控制器(DispatcherServlet)收到请求,调用处理器映射器(HandlerMapping)
- 处理器映射器(HandlerMapping)找到对应的处理程序(通过xml配置或注解的方式查找)并返回给控制器(DispatcherServlet)
- 控制器(DispatcherServlet)调用处理器适配器(HandlerAdapter)匹配对应处理类(Controller)
- 处理类(Controller)处理一些业务后并生成了一个ModelAndViews实例返回给处理器适配器(HandlerAdapter)
- 处理器适配器(HandlerAdapter)将得到的结果返回给控制器(DispatcherServlet)
- 控制器(DispatcherServlet)将ModelAndViews实例传给视图解析器(ViewResolver)
- 视图解析器(ViewResolver)处理ModelAndViews实例后将实际的视图返回给控制器(DispatcherServlet)
- 控制器(DispatcherServlet)将视图返回给客户端
2、使用注解开发SpringMVC程序
web.xml配置:
<!--配置DispatchServlet:springMVC的核心,作用是接收请求和响应结果,理解为控制器-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--DispatchServlet需要绑定springMVC的配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<!--启动级别:1-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--在springMVC中,/只匹配所有请求,不会匹配jsp页面,而/*会匹配所有请求以及jsp页面-->
<url-pattern>/</url-pattern>
</servlet-mapping>
核心配置文件:
<?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">
<!--扫描包,并且交由spring管理-->
<context:component-scan base-package="com.yang.controller"/>
<!--使SpringMVC注解生效:该步骤替代了处理器映射器和处理器适配器-->
<mvc:annotation-driven/>
<!--让springMVC不处理静态资源-->
<mvc:default-servlet-handler/>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
jsp页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
controller:
package com.yang.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller // 注入到spring容器中
@RequestMapping("/hello") // 该类的所有方法下都以该路径开头
public class HelloController {
@RequestMapping("/springmvc") // 指定url,客户端访问http://localhost:8080/hello/springmvc会到此方法
public String hello(Model model){
model.addAttribute("msg","Hello,SpringMVC");
return "hello"; // 默认情况下会被视图解析器处理,这里会被解析为 /WEB-INF/jsp/hello.jsp
}
}
访问:http://localhost:8080/hello/springmvc
2.1、@Controller
- 使用了该注解的类,会被spring容器管理
- 使用该注释类后,该类会被当成一个控制器
- 在默认情况下,里面的方法方法如果返回值为String,并且资源下有对应的视图,那么就会被视图解析器处理
- 该控制器最终获取到视图解析器处理过的视图,返回给客户端
2.2、@RequestMapping
- 表示客户端的请求映射路径
- 该注解可以使用在类和方法上,可以同时作用在一个类上,以及该类的方法上
- 当类上使用该注解,那么访问该类下的所有方法都会以该类指定的映射路径进行开头
- 方法上使用该注解,则表示一个具体路径下的资源
2.3、@RequestMapping常用衍生注解
- @GetMapping
- @PostMapping
- @DeleteMapping
- @PutMapping
举例:@GetMapping相当于@RequestMapping(method=RequestMethod.GET)
总结:用衍生注解可以指定方法客户端访问的资源需要使用哪些请求方式
2.4、@responseBody
方法上用该注解后,表示返回数据,而不是一个视图资源,不会走视图解析器
3、SpringMVC实现转发和重定向
3.1、转发(只能是项目下的资源)
- 方法返回值为String
- 不能添加@responseBody注解
- 返回字符串前增加:forward:/转发地址
3.2、重定向(可以是项目外的资源)
- 方法返回值为String
- 不能添加@responseBody注解
- 返回字符串前增加:redirect:/重定向地址
3.3、转发和重定向细节
- 当不使用springmvc时(传统request,response):
- 转发只能是项目下的资源路径,默认转发路径是:访问地址(忽略了括了项目的上下文地址)/转发资源路径
- 重定向可以是项目外资路径,默认重定向路径是:访问地址/项目的上下文路径(需要手动加上)/重定向资源路径
- 当使用springmvc时:
- 可以不指定视图解析器了
- 转发可以项目下的所有资源路径,而重定向不可以访问/WEB-INF下的资源路径
- 重定向和转发的开始地址都一样了,重定向无需再指定项目的上下文路径
4、接收请求参数及返回数据
- 接收普通参数
- 接收对象类型
4.1、@RequestParam
@RequestParam:该注解的value值与客户端传递的参数名对应,表示接收客户端的请求的参数
4.2、接收普通参数
/**
* 前端请求时传递普通参数
*/
@GetMapping("/user/t1")
public String test01(@RequestParam("username") String name, Model model){
// 接收客户端传递的参数
// 当不指定@RequestParam注解时,保证后端接收到数据的前提是形参名与前端请求的参数名一致
System.out.println("客户端传递的参数为:" + name);
// 将数据通过视图返回给客户端
model.addAttribute("msg","服务器接收到请求参数" + name);
return "test";
}
4.3、接收对象类型
/**
* 前端请求参数是一个对象
*/
@GetMapping("/user/t2")
// 根据客户端传递参数匹配对象的属性名,如果属性名和参数名一致,则可以匹配
public String test02(User user, Model model){
System.out.println(user);
model.addAttribute("msg","接收到请求参数:" + user);
return "test";
}
5、乱码问题解决
web.xml:
<!--配置springmvc的乱码过滤器-->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
6、返回JSON类型
jackson依赖:
<!--jackson依赖-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.0</version>
</dependency>
User实体类:
package com.yang.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String name;
private Integer age;
}
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!--配置DispatchServlet:springMVC的核心,作用是接收请求和响应结果,理解为控制器-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--DispatchServlet需要绑定springMVC的配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<!--启动级别:1-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--在springMVC中,/只匹配所有请求,不会匹配jsp页面,而/*会匹配所有请求以及jsp页面-->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--配置springmvc的乱码过滤器-->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
spring核心配置文件:
<?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">
<!--扫描包,并且交由spring管理-->
<context:component-scan base-package="com.yang.controller"/>
<!--使SpringMVC注解生效:该步骤替代了处理器映射器和处理器适配器-->
<mvc:annotation-driven/>
<!--让springMVC不处理静态资源-->
<mvc:default-servlet-handler/>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
UserController:
package com.yang.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yang.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class UserController {
/**
* 返回单个对象
*/
@RequestMapping("/json/j1")
@ResponseBody // 添加该注解后,不会走视图解析器,表示返回只返回数据
public String testJSON01() throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
User user = new User(110, "汤姆", 20);
String jsonStr = objectMapper.writeValueAsString(user); // 将对象转为json串
return jsonStr;
}
}
6.1、springmvc解决json中文乱码问题
spring核心配置文件中设置:
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8"/>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="failOnEmptyBeans" value="false"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
6.2、@RestController和@ResponseBody
@ResponseBody:该注解使用在类的方法上,表示该方法只返回数据,不返回视图
@RestController:该注解使用在类上,功能相当于@Controller加上@ResponseBody,在类上使用该注解后,该类下的方法无需再定义@ResponseBody注解
UserController:
package com.yang.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yang.pojo.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@RequestMapping("/json/j1")
public String testJSON01() throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
User user = new User(110, "汤姆", 20);
String jsonStr = objectMapper.writeValueAsString(user); // 将对象转为json串
return jsonStr;
}
}
6.3、返回List类型和Map类型
UserController:
/**
* 返回map
*/
@RequestMapping("/json/j3")
public String testJSON03() throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
User user = new User(110, "汤姆", 20);
User user02 = new User(120, "史密斯", 30);
User user03 = new User(130, "杰克", 26);
Map<String,User> map = new HashMap<>();
map.put("u1",user);
map.put("u2",user02);
map.put("u3",user03);
String jsonStr = objectMapper.writeValueAsString(map);
return jsonStr;
}
/**
* 返回list
*/
@RequestMapping("/json/j2")
public String testJSON02() throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
User user = new User(110, "汤姆", 20);
User user02 = new User(120, "史密斯", 30);
User user03 = new User(130, "杰克", 26);
List<User> userList = new ArrayList<>();
userList.add(user);
userList.add(user02);
userList.add(user03);
String jsonStr = objectMapper.writeValueAsString(userList);
return jsonStr;
}
总结:
- 返回单个对象和返回map类型的json数据格式都是以"对象"的形式返回给客户端
- 返回list类型的json数据格式是以"数组"的形式返回给客户端
7、SSM整合
环境:
- jdk 1.8
- maven 3.8.1
- mysql 5.7.19
- tomcat 8.5.100
数据库准备:
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` INT(10) 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,'Java',1,'从入门到放弃'),
(2,'MySQL',10,'从删库到跑路'),
(3,'Linux',5,'从进门到进牢')
7.1、maven依赖
<!-- Spring 核心库 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.20</version>
</dependency>
<!--Spring-JDBC-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.20</version>
</dependency>
<!-- Spring MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.20</version>
</dependency>
<!--jackson依赖-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.0</version>
</dependency>
<!-- MyBatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<!-- MyBatis-Spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--spring-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
实体类:
package com.yang.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Books {
private Integer bookID;
private String bookName;
private Integer bookCounts;
private String detail;
}
dao层接口:
package com.yang.mapper;
import com.yang.pojo.Books;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface BooksMapper {
int addBook(Books book);
int deleteBookById(@Param("bookID") Integer id);
int updateBook(Books book);
Books queryBookById(@Param("bookID") Integer id);
List<Books> queryBookList();
}
mapper( resources目录下创建 mappers目录 ,用于存放所有mapper文件):
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.yang.mapper.BooksMapper">
<insert id="addBook" parameterType="Books">
insert into books (bookName,bookCounts,detail)
values (#{bookName},#{bookCounts},#{detail})
</insert>
<delete id="deleteBookById" parameterType="int">
delete from books
where bookID=#{bookID}
</delete>
<update id="updateBook" parameterType="Books">
update books
set
bookName=#{bookName},
bookCounts=#{bookCounts},
detail=#{detail}
where bookID=#{bookID}
</update>
<select id="queryBookById" resultType="Books" parameterType="int">
select * from books where bookID=#{bookID}
</select>
<select id="queryBookList" resultType="Books">
select * from books
</select>
</mapper>
service层接口:
package com.yang.service;
import com.yang.pojo.Books;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface BooksService {
int addBook(Books book);
int deleteBookById(@Param("bookID") Integer id);
int updateBook(Books book);
Books queryBookById(@Param("bookID") Integer id);
List<Books> queryBookList();
}
service层实现类:
package com.yang.service;
import com.yang.mapper.BooksMapper;
import com.yang.pojo.Books;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class BooksServiceImpl implements BooksService{
@Autowired
private BooksMapper booksMapper;
@Override
public int addBook(Books book) {
return booksMapper.addBook(book);
}
@Override
public int deleteBookById(Integer id) {
return booksMapper.deleteBookById(id);
}
@Override
public int updateBook(Books book) {
return booksMapper.updateBook(book);
}
@Override
public Books queryBookById(Integer id) {
return booksMapper.queryBookById(id);
}
@Override
public List<Books> queryBookList() {
return booksMapper.queryBookList();
}
}
7.2、外部配置文件(jdbc.properties)
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&useUnicode=true&charsetEncoding=UTF-8"
jdbc.username=root
jdbc.password=root
7.3、mybatis核心配置文件(mybatis-config.xml)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--设置别名-->
<typeAliases>
<package name="com.yang.pojo"/>
</typeAliases>
</configuration>
7.4、spring核心配置文件(applicationContext.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 扫描spring注解所在的包,将bean注入到spring容器里面 -->
<context:component-scan base-package="com.yang"/>
<!-- 引入外部配置文件 -->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!-- 数据源注入到spring容器中 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- spring整合mybatis -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- 加载mybatis的配置文件 -->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<!--spring中注册mapper-->
<property name="mapperLocations" value="classpath:mappers/*.xml"/>
</bean>
<!-- dao层创建代理对象,扫描dao层接口,注入spring容器中 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--注入sqlSessionFactory-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!--扫描dao层的包-->
<property name="basePackage" value="com.yang.mapper"/>
</bean>
<!-- spring事务支持-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
</beans>
7.5、springMVC核心配置文件(spring-mvc.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:mvc="http://www.springframework.org/schema/mvc"
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/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 扫描包-->
<context:component-scan base-package="com.yang.controller"/>
<!-- 过滤静态资源-->
<mvc:default-servlet-handler/>
<!--springmvc开启注解支持-->
<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>
7.6、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的配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- spring-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--配置DispatchServlet:springMVC的核心-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--DispatchServlet需要绑定springMVC的配置文件-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!--启动级别:1-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--在springMVC中,/只匹配所有请求,不会匹配jsp页面,而/*会匹配所有请求以及jsp页面-->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--配置springmvc的乱码过滤器-->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
7.7、测试
编写controller层:
package com.yang.controller;
import com.yang.pojo.Books;
import com.yang.service.BooksService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
@RequestMapping("/books")
public class BooksController {
@Autowired
private BooksService booksService;
@RequestMapping("/allBook")
public String allBook(Model model){
List<Books> books = booksService.queryBookList();
model.addAttribute("books",books);
return "test";
}
}
8、Ajax
使用Ajax可以实现异步请求(页面无刷新)
8.1、Ajax初体验
使用jQuery实现Ajax异步请求
maven依赖:
<!--spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
spring核心配置文件:
<!--扫描包,并且交由spring管理-->
<context:component-scan base-package="com.yang.controller"/>
<!--使SpringMVC注解生效:该步骤替代了处理器映射器和处理器适配器-->
<mvc:annotation-driven/>
<!--静态资源过滤-->
<mvc:default-servlet-handler/>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
<!--springmvc解决json中文乱码问题-->
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="UTF-8"/>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="failOnEmptyBeans" value="false"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
web.xml:
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
index.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<%--使用jQuery实现ajax异步请求--%>
<script src="${pageContext.request.contextPath}/static/js/jquery-3.7.1.js"></script>
<script>
function a(){
/*使用jQuery实现ajax*/
$.ajax({
/*请求的url*/
url:'${pageContext.request.contextPath}/a1',
/*请求方式*/
method:'post',
/*请求携带的参数(发送的数据)*/
data:{'name':$('#username').val()},
/*请求成功后执行的回调函数*/
success:function (data){
alert(data) // 接收后端响应的信息并弹窗展示
},
//*请求失败后执行的回调函数*/
error:function (){
}
})
}
</script>
</head>
<body>
<%--当输入框失去焦点后执行a函数--%>
用户名:<input type="text" id="username" οnblur="a()">
</body>
</html>
controller:
package com.yang.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@RestController
public class AjaxController {
@RequestMapping("/a1")
public void test(String name, HttpServletResponse response) throws IOException {
System.out.println(name);
// 判断用户名是否正,返回提示信息
if (name.equals("jack")){
response.getWriter().print("true");
} else {
response.getWriter().print("false");
}
}
}
8.2、使用Ajax发送异步请求接收JSON数据
添加依赖:
<!--jackson依赖-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.0</version>
</dependency>
User类:
package com.yang.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String name;
private Integer age;
private String sex;
}
Controller:
@RequestMapping("/a2")
public List<User> test02(){
List<User> userList = new ArrayList<>();
userList.add(new User("jack",20,"男"));
userList.add(new User("smith",30,"女"));
return userList;
}
index02.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="${pageContext.request.contextPath}/static/js/jquery-3.7.1.js"></script>
<script>
$(function (){
$("#btn").click(function (){
var html = ""
$.post({
url:'${pageContext.request.contextPath}/a2',
success:function (data){
for (let i = 0; i < data.length; i++){
html += "<tr>" +
"<td>" + data[i].name + "</td>" +
"<td>" + data[i].age + "</td>" +
"<td>" + data[i].sex + "</td>" +
"</tr>"
}
$("#content").html(html)
}
})
})
})
</script>
</head>
<body>
<input type="button" value="获取数据" id="btn">
<table>
<tr>
<td>姓名</td>
<td>年龄</td>
<td>性别</td>
</tr>
<tbody id="content">
<%--接收后端响应的数据--%>
</tbody>
</table>
</body>
</html>
8.3、用户名验证
login.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="${pageContext.request.contextPath}/static/js/jquery-3.7.1.js"></script>
<script>
function ifUserName(){
$.ajax({
url:'${pageContext.request.contextPath}/a3',
method:'post',
data:{"username":$("#username").val()},
success:function (data){
if (data.toString()==="用户名正确"){
$("#userInfo").css("color","green")
} else {
$("#userInfo").css("color","red")
}
$("#userInfo").html(data)
}
})
}
function ifPassword(){
$.ajax({
url:'${pageContext.request.contextPath}/a3',
method:'post',
data:{"pwd":$("#pwd").val()},
success:function (data){
if (data.toString()==="密码正确"){
$("#pwdInfo").css("color","green")
} else {
$("#pwdInfo").css("color","red")
}
$("#pwdInfo").html(data)
}
})
}
</script>
</head>
<body>
用户名:<input type="text" id="username" οnblur="ifUserName()">
<span id="userInfo"></span>
<br>
密码:<input type="password" id="pwd" οnblur="ifPassword()">
<span id="pwdInfo"></span>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="${pageContext.request.contextPath}/static/js/jquery-3.7.1.js"></script>
<script>
function ifUserName(){
$.ajax({
url:'${pageContext.request.contextPath}/a3',
method:'post',
data:{"username":$("#username").val()},
success:function (data){
if (data.toString()==="用户名正确"){
$("#userInfo").css("color","green")
} else {
$("#userInfo").css("color","red")
}
$("#userInfo").html(data)
}
})
}
function ifPassword(){
$.ajax({
url:'${pageContext.request.contextPath}/a3',
method:'post',
data:{"pwd":$("#pwd").val()},
success:function (data){
if (data.toString()==="密码正确"){
$("#pwdInfo").css("color","green")
} else {
$("#pwdInfo").css("color","red")
}
$("#pwdInfo").html(data)
}
})
}
</script>
</head>
<body>
用户名:<input type="text" id="username" οnblur="ifUserName()">
<span id="userInfo"></span>
<br>
密码:<input type="password" id="pwd" οnblur="ifPassword()">
<span id="pwdInfo"></span>
</body>
</html>
controller:
@RequestMapping("/a3")
public String a3(String username,String pwd){
String msg = "";
if (username != null){
if ("admin".equals(username)){
msg = "用户名正确";
} else {
msg = "用户名不存在";
}
}
if (pwd != null){
if ("123".equals(pwd)){
msg = "密码正确";
} else {
msg = "密码错误";
}
}
return msg;
}
9、拦截器
SpringMVC中的拦截器是AOP思想的应用
maven依赖:
<!--spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
自定义拦截器:
package com.yang.config;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
// 自定义拦截器,实现HandlerInterceptor接口
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("=====处理前=====");
return true; // 返回true表示放行
}
@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("=====清理=====");
}
}
spring核心配置文件:
<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<!--拦截所有请求-->
<mvc:mapping path="/**"/>
<!--使用的拦截器-->
<bean class="com.yang.config.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
controller:
package com.yang.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/c")
public class TestController {
@RequestMapping("c1")
public String test(){
System.out.println("test方法被执行");
return "ok";
}
}
登录判断验证
用户登录的controller:
package com.yang.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpSession;
@Controller
@RequestMapping("/user")
public class LoginController {
// 当注销时删除当前用户登录信息,并返回到web应用主页
@RequestMapping("/goOut")
public String goOut(HttpSession session){
session.removeAttribute("userLoginInfo");
return "redirect:/index.jsp";
}
// 直接访问首页
@RequestMapping("/main")
public String main(){
return "main";
}
// 进入用户登录页面请求
@RequestMapping("/goLogin")
public String goLogin(){
return "login";
}
// 用户登录请求
@RequestMapping("/login")
public String login(HttpSession session, String username, String pwd, Model model){
session.setAttribute("userLoginInfo",username);
model.addAttribute("username",username);
return "main";
}
}
web应用首页:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1><a href="${pageContext.request.contextPath}/user/goLogin">点击登录</a></h1>
<h1><a href="${pageContext.request.contextPath}/user/main">进入首页</a></h1>
</body>
</html>
登录页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>登录</h1>
<form action="${pageContext.request.contextPath}/user/login" method="post">
用户名:<input type="text" name="username"><br/>
密码:<input type="password" name="pwd"><br/>
<input type="submit" value="登录">
</form>
</body>
</html>
首页:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>首页</h1>
<span>${username}</span>
<p>
<a href="${pageContext.request.contextPath}/user/goOut">注销</a>
</p>
</body>
</html>
增加用户登录的拦截器:
package com.yang.config;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 用户登录拦截器
*/
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// 判断用户当前是否在登录页面
if (request.getRequestURI().contains("goLogin")){
return true;
}
// 判断用户是否正在执行登录操作
if (request.getRequestURI().contains("login")){
return true;
}
// 判断用户是否登录
if (request.getSession().getAttribute("userLoginInfo") != null){
return true;
}
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
return false;
}
}
spring核心配置文件:
<!--用户登录拦截器-->
<mvc:interceptor>
<!--拦截所有请求-->
<mvc:mapping path="/user/**"/>
<!--使用的拦截器-->
<bean class="com.yang.config.LoginInterceptor"/>
</mvc:interceptor>
10、文件上传下载
maven依赖:
<!--文件上传下载-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
spring核心配置文件:
<!--扫描包,并且交由spring管理-->
<context:component-scan base-package="com.yang.controller"/>
<!--使SpringMVC注解生效:该步骤替代了处理器映射器和处理器适配器-->
<mvc:annotation-driven/>
<!--静态资源过滤-->
<mvc:default-servlet-handler/>
<!--视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
id="internalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
<!-- 配置文件上传解析器,将上传的文件封装为CommonsMultipartFile -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8" />
<!--文件上传大小限制-->
<property name="maxUploadSize" value="5242440" />
</bean>
web.xml:
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
index.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/upload" enctype="multipart/form-data" method="post">
<input type="file" name="file">
<input type="submit" value="upload">
</form>
</body>
</html>
10.1、方式1上传文件
package com.yang.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
@RestController
public class FileController {
@RequestMapping("/upload")
// @RequestParam("file") 将name=file的表单控件封装为CommonsMultipartFile对象
public String upload(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
// 获取文件名
String uploadFileName = file.getOriginalFilename();
System.out.println("上传的文件名:" + uploadFileName);
// 文件保存的路径
String fileUploadPath = request.getSession().getServletContext().getRealPath("/upload");
// 如果存放上传文件的目录不存在,就创建
File realPath = new File(fileUploadPath);
if (!realPath.exists()){
realPath.mkdir();
}
// 避免上传的文件重复,使用工具类UUID处理,处理结果是一个随机的字符串
String fileName = UUID.randomUUID().toString();
// 获取上传文件的后缀名(路径下最后一个.的下一个元素就是文件后缀名)
String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
// 完整的文件名
String newFileName = fileName + "." + fileExtName;
// 获取文件输入流,获取上传的文件数据
InputStream is = file.getInputStream();
// 创建文件输出流,将上传的文件数据写入到服务器中,完成文件上传
// 在指定目录下创建指定文件(在realPath目录下创建名为newFileName的文件)
OutputStream os = new FileOutputStream(new File(realPath,newFileName));
// 读写输出
int len = 0;
// 缓冲区
byte[] buffer = new byte[1024];
while((len = is.read(buffer)) != -1){
os.write(buffer,0,len);
}
os.close();
is.close();
return "msg:文件上传成功!";
}
}
10.2、方式2上传文件
@RequestMapping("/upload02")
// @RequestParam("file") 将name=file的表单控件封装为CommonsMultipartFile对象
public String upload02(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
// 上传文件路径保存设置
String uploadFileName = request.getSession().getServletContext().getRealPath("/upload");
// 如果存放上传文件的目录不存在,就创建
File realPath = new File(uploadFileName);
if (!realPath.exists()){
realPath.mkdir();
}
// 避免上传的文件重复,使用工具类UUID处理,处理结果是一个随机的字符串
String fileName = UUID.randomUUID().toString();
// 获取上传文件的后缀名(路径下最后一个.的下一个元素就是文件后缀名)
String fileExtName = uploadFileName.substring(uploadFileName.lastIndexOf(".") + 1);
// 完整的文件名
String newFileName = fileName + "." + fileExtName;
// 通过CommonsMultipartFile对象的transferTo方法可直接将上传的文件写入到指定路径下
file.transferTo(new File(uploadFileName,newFileName));
return "msg:文件上传成功!";
}
10.3、文件下载
@RequestMapping("/download")
public void download(String downloadFileName,HttpServletResponse response, HttpServletRequest request) throws Exception{
// 获取需要下载文件的地址
String fileDownloadPath = request.getSession().getServletContext().getRealPath("/upload");
// 设置响应头信息
response.reset(); // 设置页面不缓存
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data"); // 二进制流传输
// 表示响应的数据以附件的形式保存(以文件的形式存储)
response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(downloadFileName,"utf8"));
// 获取需要下载的文件对象
File file = new File(fileDownloadPath, downloadFileName);
// 获取目标文件的输入流
InputStream is = new FileInputStream(file);
// 将目标文件以输出流的形式响应给客户端
OutputStream os = response.getOutputStream();
// 缓冲区
byte[] buff = new byte[1024];
int len = 0;
// 执行读写操作
while ((len = is.read(buff)) != -1){
os.write(buff,0,len);
os.flush(); // 刷新,否者输出不成功
}
os.close();
is.close();
}