目录
- 1.学习重点
- 2.回顾MVC
- 3.回顾servlet
- 4.初始SpringMVC
- 4.1.为什么要学SpringMVC?
- 4.2.SpringMVC的中重点DispatcherServlet
- 4.3.SpringMVC项目的搭建
- 4.4.MVC框架要做哪些事情?
- 4.5.可能会遇到的问题
- 5.SpringMVC的执行原理
- 6.使用注解开发SpringMVC
- 7.Controller控制总结
- 8.RestFul风格
- 9.转发和重定向
- 9.1.通过ModelAndView对象
- 9.2.通过ServletAPI
- 9.3.通过SpringMVC
- 9.3.1.通过SpringMVC来实现转发和重定向 - 无需视图解析器
- 9.3.2.通过SpringMVC来实现转发和重定向 - 有视图解析器;
- 10.数据处理
- 10.1.处理请求提交的数据
- 10.2.后端数据显示到前端
- 10.3乱码问题解决
- 11.json交互处理
- 11.1.什么是json?
- 11.2.jackson的使用
- 11.3.fastjson的使用
- 12.ssm整合
- 12.1.环境搭建
- 12.1.1.版本:
- 12.1.2.数据库环境:
- 12.1.3.项目架构:
- 12.1.4.实体类及对应的mapper:
- 12.1.整合mybatis层
- 12.2.整合Spring层
- 12.3.整合SpringMVC层
- 12.4.项目运行
- 13.Ajax总结
- 13.1.什么是Ajax?
- 13.2.伪造Ajax
- 13.3JQuery的使用
- 13.3.1.JQuery是什么?
- 13.3.2.使用JQuery的两种方式
- 13.3.3.Ajax的请求参数与JQuery的注意事项
- 13.5.Ajax和JQuery的使用
- 13.6.Ajax执行流程
- 13.7.Ajax验证用户名体验
- 13.8.JSON乱码问题的解决
- 14.拦截器
- 14.1.Springmvc的拦截器:
- 14.2.登录判断验证:
- 15.文件下载和上传
- 15.1.文件上传
- 15.2.文件下载
- 16.总结和展望
- 16.1.ssm回顾:
- 16.2.前端应该掌握
1.学习重点
- SpringMVC重点:SpringMVC执行流程,SSM框架整合。
- 在这个阶段,博客的重要性非常重要。
- mvc就是不停的做,做的越多理解的越深刻。
2.回顾MVC
MVC:模型(dao,service) ,视图(Jsp),和控制器(Servlet)。
细分pojo实体类,vo是视图层的对象。dto是数据传输时的对象。
架构的发展不是一直不变的,有这么一个过程。
java最优秀的地方在于适合构建一些复杂性的项目。
项目越大,java越容易维护。
3.回顾servlet
回顾servlet和tomcat。然后才能进阶到SpringMVC。
相关依赖:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
3.1步骤
新建一个maven工程。
添加依赖。
加入web支持。
创建一个servlet。
//只要继承了servlet接口的程序就叫servlet。
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1.获取前端参数
String method = req.getParameter("method");
if (method.equals("add")){
req.getSession().setAttribute("msg","执行了add方法");
}
if (method.equals("delete")){
req.getSession().setAttribute("msg","执行了delete方法");
}
// 2.调用业务层
// 3.视图转发或重定向
req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
test.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>test</title>
</head>
<body>
${msg}
</body>
</html>
在web.xml中注册servlet。
<?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">
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.kuang.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<!-- <session-config>-->
<!-- <session-timeout>15</session-timeout>-->
<!-- </session-config>-->
<!-- <welcome-file-list>-->
<!-- <welcome-file>index.jsp</welcome-file>-->
<!-- </welcome-file-list>-->
</web-app>
测试运行。
如果为了保证安全,用户不可见就放在WEB-INF下面,如果是公共的页面就放在web下面就可以了。
Artifact 是maven中的一个概念,表示某个module要如何打包。
发现依赖没有导入。
4.初始SpringMVC
4.1.为什么要学SpringMVC?
Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架。
4.2.SpringMVC的中重点DispatcherServlet
DispatcherServlet:请求分发调度作用。
SpringMVC建议全用注解。
4.3.SpringMVC项目的搭建
- 1.新建maven项目,添加web支持。
- 2.导入依赖。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
- 3.配置web.xml,注册DispatcherServlet:
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">
<!--A.注册DispatcherServlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--关联一个springmvc的配置文件:【servlet-name】-servlet.xml-->
<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>
<!--/ 匹配所有的请求;(不包括.jsp)-->
<!--/* 匹配所有的请求;(包括.jsp)-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
- 4.配置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">
<!--B,配置这三个-->
<!-- 1.添加 处理映射器-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<!-- 2.添加 处理器适配器-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!--上面两个的作用是把url去匹配Spring里面有哪个Controller,然后去处理它。-->
<!--3.视图解析器:DispatcherServlet给他的ModelAndView-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
- 5.写一个控制类,实现Controller接口
package com.kuang.controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//C.先导入controller接口
public class HelloController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
//ModelAndView 模型和视图
ModelAndView mv = new ModelAndView();
//封装对象,放在ModelAndView中
mv.addObject("msg","helloSpringMVC");
//封装要跳转的视图,放到放在ModelAndView中
mv.setViewName("hello"); // /WEB-INF/jsp/hello.jsp
// 即可以用于存数据和跳转。会经过视图解析器拼接前后缀,然后找到返回的页面。
return mv;
}
}
/*
原来存放东西是通过session和request里面,现在通过ModelAndView存放东西。
原来跳转页面需要重定向或者转发,现在设置一个视图的名字就可以了。
*/
- 6.在springmvc-servlet.xml中注册该接口
<!-- Handler-->
<!-- c. 匹配导/hello后,交给HelloController去处理-->
<bean id="/hello" class="com.kuang.controller.HelloController"/>
- 7.配置tomcat并启动
4.4.MVC框架要做哪些事情?
1.将url映射到java类或java类的方法 .
2.封装用户提交的数据 .
3.处理请求–调用相关的业务处理–封装响应数据 .
4.将响应的数据进行渲染 . jsp / html 等表示层数据 .
4.5.可能会遇到的问题
5.SpringMVC的执行原理
这里的前端控制器就理解成DispatcherServlet
即3个部分,1是适配请求是干嘛的 2.(请求到底做什么)根据请求找到Controller,返回ModelAndView 3.最后(视图解析)渲染到视图上。
真正要做的就两步:1.controller层调业务层。2.设置视图返回的名字。
6.使用注解开发SpringMVC
1.在springmvc-servlet.xml中自动扫描包,并且让SpringMVC不处理静态资源
<!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 -->
<context:component-scan base-package="com.kuang.controller"/>
<!-- 让Spring MVC不处理静态资源 -->
<mvc:default-servlet-handler />
<!--
支持mvc注解驱动
在spring中一般采用@RequestMapping注解来完成映射关系
要想使@RequestMapping注解生效
必须向上下文中注册DefaultAnnotationHandlerMapping
和一个AnnotationMethodHandlerAdapter实例
这两个实例分别在类级别和方法级别处理。
而annotation-driven配置帮助我们自动完成上述两个实例的注入。
-->
<mvc:annotation-driven />
2.使用注解实现控制类
package com.kuang.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller //代表这个类会被Spring接管
//被这个注解的类的所有方法,如果返回值是String,并且有具体页面可以跳转
// 那么就会被视图解析器解析。
@RequestMapping("/hello")
public class HelloController {
@RequestMapping("/h1")
//返回一个视图解析器。
public String Hello(Model model){
model.addAttribute("msg","Hello,HelloController");
return "hello";
}
}
7.Controller控制总结
缺点是:一个控制器中只有一个方法,如果要多个方法则需要定义多个Controller;定义的方式比较麻烦;
使用注解必须使用包扫描。
只要改了java的代码,就重新发布(Reploy)一下。
只要改了配置文件,就重新tomcat。
8.RestFul风格
@Controller
public class RestFulController {
// @RequestMapping("/add")
// public String test1(int a, String b, Model model) {
// String res = a + b;
// model.addAttribute("msg", res);
// return "test";
// }
@RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.GET)
public String test1(@PathVariable int a,@PathVariable String b, Model model) {
String res = a + b;
model.addAttribute("msg", res);
return "test";
}
@PostMapping("/add/{a}/{b}")
public String test2(@PathVariable int a,@PathVariable String b, Model model) {
String res = a + b;
model.addAttribute("msg", res);
return "test";
}
}
9.转发和重定向
三种跳转方式:1.通过ModelAndView对象。2.通过ServletAPI。3.通过SpringMVC。
9.1.通过ModelAndView对象
设置ModelAndView对象 , 根据view的名称 , 和视图解析器跳到指定的页面 .
页面 : {视图解析器前缀} + viewName +{视图解析器后缀}
9.2.通过ServletAPI
通过原生的servlet来做。
1.通过HttpServletResponse实现输出和重定向
rsp.sendRedirect("/index.jsp");
2.通过HttpServletResponse实现转发
//转发
req.setAttribute("msg","/result/t3");
req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,rsp);
9.3.通过SpringMVC
9.3.1.通过SpringMVC来实现转发和重定向 - 无需视图解析器
测试前,需要将视图解析器注释掉
// 无视图解析器-转发
@RequestMapping("/m1/t1")
public String test1(){
return "/WEB-INF/jsp/test.jsp";
}
// 无视图解析器-重定向
@RequestMapping("/m1/t1")
public String test1(){
return "redirect:/index.jsp";
}
9.3.2.通过SpringMVC来实现转发和重定向 - 有视图解析器;
//有视图解析器时-转发
@RequestMapping("/m1/t1")
public String test1(){
return "test";//默认转发
}
//有视图解析器-重定向
@RequestMapping("/m1/t1")
public String test1(){
return "redirect:/index.jsp";//默认转发
}
重定向仍然是这种形式。
10.数据处理
10.1.处理请求提交的数据
1、提交的域名称和处理方法的参数名一致
提交数据 : http://localhost:8080/hello?name=kuangshen
@RequestMapping("/hello")
public String hello(String name){
System.out.println(name);
return "hello";
}
2、提交的域名称和处理方法的参数名不一致
提交数据 : http://localhost:8080/hello?username=kuangshen
@RequestParam("请求中的参数")
//@RequestParam("username") : username提交的域的名称 .
@RequestMapping("/hello")
public String hello(@RequestParam("username") String name){
System.out.println(name);
return "hello";
}
3、提交的是一个对象
要求提交的表单域和对象的属性名一致 , 参数使用对象即可
提交数据 : http://localhost:8080/mvc04/user?name=kuangshen&id=1&age=15
public class User {
private int id;
private String name;
private int age;
}
请求的参数自动转化为对象中的属性。
@RequestMapping("/user")
public String user(User user){
System.out.println(user);
return "hello";
}
如果使用对象的话,前端传递的参数名和对象名必须一致,否则就是null。
10.2.后端数据显示到前端
第一种 : 通过ModelAndView
public class ControllerTest1 implements Controller {
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
//返回一个模型视图对象
ModelAndView mv = new ModelAndView();
mv.addObject("msg","ControllerTest1");
mv.setViewName("test");
return mv;
}
}
第二种 : 通过ModelMap
@RequestMapping("/hello")
public String hello(@RequestParam("username") String name, ModelMap model){
//封装要显示到视图中的数据
//相当于req.setAttribute("name",name);
model.addAttribute("name",name);
System.out.println(name);
return "hello";
}
第三种 : 通过Model
@RequestMapping("/ct2/hello")
public String hello(@RequestParam("username") String name, Model model){
//封装要显示到视图中的数据
//相当于req.setAttribute("name",name);
model.addAttribute("msg",name);
System.out.println(name);
return "test";
}
对于新手而言简单来说使用区别没有太大差别。
Model 只有寥寥几个方法只适合用于储存数据
ModelMap 继承了 LinkedMap ,除了实现了自身的一些方法,同样的继承 LinkedMap 的方法和特性;
ModelAndView 可以在储存数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转。
10.3乱码问题解决
11.json交互处理
11.1.什么是json?
Json:一种数据交换的格式,并不是一个新的语言。
后端提供一个这样的格式,前端按照这样的格式去解析
前端一般对象和json对象之间的转换。
<body>
<script type="text/javascript">
<!--编写一个javascript对象-->
var user={
name:"阿文",
age:12,
sex:"男"
};
//将js对象转换为json对象
var stringify = JSON.stringify(user);
console.log(stringify)
console.log("=========")
// console.log(user)
//将json对象转为为js对象
var parse = JSON.parse(stringify);
console.log(parse);
</script>
</body>
重点要学习java这么生成json对象。
一般说的API接口是提供一个地址栏,别人访问地址栏就可以访问到。
11.2.jackson的使用
常用解析json的工具:Jackson, fastjson。
Jackson的使用:
(1)导包
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
(2)JsonUtils工具类
package com.kuang.utils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.text.SimpleDateFormat;
/**
*
*/
public class JsonUtils {
public static String getJson(Object object){
return getJson(object,"yyyy-MM-dd HH:mm:ss");
}
public static String getJson(Object object,String dateFormat){
ObjectMapper mapper = new ObjectMapper();
//不使用时间戳的方式
mapper.configure(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS,false);
// 自定义日期的格式
SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
mapper.setDateFormat(sdf);
try {
return mapper.writeValueAsString(object);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
}
(3)使用
//produces属性解决json字符串乱码问题。
@RequestMapping(value = "/j3",produces = "application/json;charset=utf-8")
@ResponseBody //不会走视图解析器,会直接返回一个字符串
public String json3() throws JsonProcessingException {
Date date = new Date();
return JsonUtils.getJson(date,"yyyy-MM-dd");
}
@RequestMapping(value = "/j2",produces = "application/json;charset=utf-8")
@ResponseBody //不会走视图解析器,会直接返回一个字符串
public String json2() throws JsonProcessingException {
// ObjectMapper objectMapper = new ObjectMapper();
List<User> userList=new ArrayList<>();
User user1 = new User("小奈儿", 13, "男");
User user2 = new User("小奈儿", 14, "男");
User user3 = new User("小奈儿", 15, "男");
User user4 = new User("小奈儿", 16, "男");
userList.add(user1);
userList.add(user2);
userList.add(user3);
userList.add(user4);
//创建一个对象
return JsonUtils.getJson(userList);
}
@RestController和@ResponseBody注解:
- @RestController:@Controller更换成@RestControlle后,该类下面的所有方法,只会返回json字符串。
@RequestMapping和@ResponseBody联合使用,该注解标记的方法会返回字符串。
- @RequestMapping(value = “/j2”,produces = “application/json;charset=utf-8”)
- @ResponseBody //不会走视图解析器,会直接返回一个字符串。
11.3.fastjson的使用
(1)Fastjosn的pom依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.8</version>
</dependency>
(2)使用:
package com.kuang.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.kuang.pojo.User;
import java.util.ArrayList;
import java.util.List;
public class FastJsonDemo {
public static void main(String[] args) {
//创建一个对象
User user1 = new User("秦疆1号", 3, "男");
User user2 = new User("秦疆2号", 3, "男");
User user3 = new User("秦疆3号", 3, "男");
User user4 = new User("秦疆4号", 3, "男");
List<User> list = new ArrayList<User>();
list.add(user1);
list.add(user2);
list.add(user3);
list.add(user4);
System.out.println("*******Java对象 转 JSON字符串*******");
String str1 = JSON.toJSONString(list);
System.out.println("JSON.toJSONString(list)==>"+str1);
String str2 = JSON.toJSONString(user1);
System.out.println("JSON.toJSONString(user1)==>"+str2);
System.out.println("\n****** JSON字符串 转 Java对象*******");
User jp_user1=JSON.parseObject(str2,User.class);
System.out.println("JSON.parseObject(str2,User.class)==>"+jp_user1);
System.out.println("\n****** Java对象 转 JSON对象 ******");
JSONObject jsonObject1 = (JSONObject) JSON.toJSON(user2);
System.out.println("(JSONObject) JSON.toJSON(user2)==>"+jsonObject1.getString("name"));
System.out.println("\n****** JSON对象 转 Java对象 ******");
User to_java_user = JSON.toJavaObject(jsonObject1, User.class);
System.out.println("JSON.toJavaObject(jsonObject1, User.class)==>"+to_java_user);
}
}
12.ssm整合
12.1.环境搭建
12.1.1.版本:
12.1.2.数据库环境:
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(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,'Java',1,'从入门到放弃'),
(2,'MySQL',10,'从删库到跑路'),
(3,'Linux',5,'从进门到进牢');
12.1.3.项目架构:
12.1.4.实体类及对应的mapper:
Books.java
public class Books {
private int bookID;
private String bookName;
private int bookCounts;
private String detail;
}
BooksMapper.java
import com.kuang.pojo.Books;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface BooksMapper {
// 增加一本书
int addBook(Books books);
// 删除一本书
int deleteBookById(@Param("id") int id);
// 更新一本书
int updateBook(Books books);
// 查询一本书
Books queryBookById(@Param("id") int id);
// 查询所有书
List<Books> queryAllBook();
// 通过书籍名查询书籍
Books queryBookByName(@Param("bookName") String bookName);
}
BooksMapper.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kuang.dao.BooksMapper">
<insert id="addBook" parameterType="Books">
insert into books
values (null, #{bookName}, #{bookCounts}, #{detail});
</insert>
<delete id="deleteBookById" parameterType="int">
delete
from books
where bookID = #{id}
</delete>
<update id="updateBook" parameterType="Books">
update books
<set>
<if test="bookName!=null">
bookName=#{bookName},
</if>
<if test="bookCounts!=null">
bookCounts=#{bookCounts},
</if>
<if test="detail!=null">
detail=#{detail}
</if>
</set>
where bookID=#{bookID}
</update>
<select id="queryBookById" parameterType="int" resultType="Books">
select * from books where bookID=#{id}
</select>
<select id="queryAllBook" resultType="Books">
select * from books
</select>
<select id="queryBookByName" resultType="Books">
SELECT * FROM `books` where bookName=#{bookName}
</select>
</mapper>
导入依赖:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.kuang</groupId>
<artifactId>ssmbuild</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<!-- 依赖-->
<dependencies>
<!--Junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- 数据库连接池 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<!--Servlet - JSP -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!--Mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>】
<!--Mybatis整合Spring-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.2</version>
</dependency>
<!--Spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<!--Spring连接jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
<!-- aop横切-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
</dependencies>
<!-- 资源导出问题-->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
12.1.整合mybatis层
数据库配置文件:database.properties
jdbc.driver=com.mysql.jdbc.Driver
#如果使用Mysql8.0+,需要增加一个时区的配置
jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=123456
在8.0后的Mysql里面,如果没有设时区,就会报错。
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>
<!-- 配置数据源,交给Spring去做。-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<typeAliases>
<package name="com.kuang.pojo"/>
</typeAliases>
<mappers>
//注册mapper
// <mapper class="com.kuang.dao.BooksMapper"/>
</mappers>
</configuration>
12.2.整合Spring层
1.spring-dao.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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
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/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--1.关联数据库配置文件-->
<context:property-placeholder location="classpath:database.properties"/>
<!-- 2.连接池:原来用的Spring的,这里用c3p0-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="driverClass" value="${jdbc.driver}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!-- c3p0连接池的私有属性 -->
<property name="maxPoolSize" value="30"/>
<property name="minPoolSize" value="10"/>
<!-- 关闭连接后不自动commit -->
<property name="autoCommitOnClose" value="false"/>
<!-- 获取连接超时时间 -->
<property name="checkoutTimeout" value="10000"/>
<!-- 当获取连接失败重试次数 -->
<property name="acquireRetryAttempts" value="2"/>
</bean>
<!--3.sqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!-- 绑定Mybatis的配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<!-- 4.配置dao接口扫描包,动态的实现了 Dao接口可以注入到Spring容器中-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 注入sqlSessionFactory-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!-- 要扫描的dao包-->
<property name="basePackage" value="com.kuang.dao"/>
</bean>
</beans>
2.spring-service.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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
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
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 1.扫描service下的包-->
<context:component-scan base-package="com.kuang.service"/>
<!--2.将我们的所以业务类注入到Spring,可以通过配置或者注解实现-->
<bean id="BookServiceImpl" class="com.kuang.service.BooksServiceImpl">
<property name="booksMapper" ref="booksMapper"/>
</bean>
<!-- 3.配置声明式事务配置-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 注入数据源-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!--4.aop事务支持,要加入事务就把下面的注释解开-->
<!-- 结合AOP实现事务的织入-->
<!-- 配置事务的通知:-->
<!-- <tx:advice id="txAdvice" transaction-manager="transactionManager">-->
<!-- <tx:attributes>-->
<!-- <tx:method name="*" propagation="REQUIRED"/>-->
<!-- </tx:attributes>-->
<!-- </tx:advice>-->
<!-- 配置事务切入-->
<!-- <aop:config>-->
<!-- <aop:pointcut id="txPointCut" expression="execution(* com.kuang.*.*(..))"/>-->
<!-- <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>-->
<!-- </aop:config>-->
</beans>
3.整合到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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="spring-dao.xml"/>
<import resource="spring-service.xml"/>
<import resource="spring-mvc.xml"/>
</beans>
12.3.整合SpringMVC层
加入web支持,配置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">
<!--1.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: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>
<!--2.乱码过滤-->
<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>
<!--3.Session过期时间-->
<session-config>
<session-timeout>15</session-timeout>
</session-config>
</web-app>
配置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: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
https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 配置SpringMVC -->
<!-- 1.注解驱动 -->
<mvc:annotation-driven />
<!-- 2.静态资源过滤-->
<mvc:default-servlet-handler/>
<!-- 3.扫描包:controller-->
<context:component-scan base-package="com.kuang.controller" />
<!-- 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中进行整合:
<import resource="spring-mvc.xml"/>
12.4.项目运行
1.配置tomcat
2.导入包:
3.运行项目。
13.Ajax总结
13.1.什么是Ajax?
url请求一个链接,只会有两种状态,一个是转发一个是重定向。这两个都会使整个页面刷新。
返回来的json数据展示在前端了。可以让我们的网页交互性极强,更像本地的原生应用。
13.2.伪造Ajax
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>iframe体验页面无刷新</title>
<script>
function go() {
//万物皆war
//要操作对应的元素,就要先获取它。
var url= document.getElementById("url").value;
document.getElementById("iframe1").src = url;
}
</script>
</head>
<body>
<div>
<p>请输入地址:</p>
<p>
<input type="text" id="url" value="https://www.iqiyi.com/dianshiju/">
<!-- 点击提交之后,绑定一个事件onclick,点击事件,点击后就会触发该事件。-->
<input type="button" value="提交" onclick="go()">
</p>
</div>
<div>
<!-- 通过一个点击事件,改变窗口的内容。-->
<iframe id="iframe1" style="width: 100%;height: 500px"></iframe>
</div>
</body>
</html>
13.3JQuery的使用
13.3.1.JQuery是什么?
JQuery是一个库,里面包含Js的大量函数。
13.3.2.使用JQuery的两种方式
1.引入cdn
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
2.下载jquery.js文件
13.3.3.Ajax的请求参数与JQuery的注意事项
只会用到这四个。
13.5.Ajax和JQuery的使用
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
<%-- <script src="${pageContext.request.contextPath}/static/js/jquery-3.4.1.js"></script>--%>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
// $=jQuery
function a(){
//调这个函数后,发起一个请求。
$.post({
url:"${pageContext.request.contextPath}/a1",
data:{"name":$('#username').val()},
success:function (data,status){
// alert(date)
console.log("data->"+data)
console.log("status"+status) //200,300,400,500可以通过状态码判断请求是否成功。
}
})
}
</script>
</head>
<body>
<%-- 失去焦点的时候发起一个请求到后台--%>
<%--onblur:失去焦点事件。--%>
用户名:<input type="text" id="username" onblur="a()">
</body>
</html>
如果$.不报错,说明jQuery加载成功了。jQuery的缩写就是$
AjaxController:
@RestController
public class AjaxController {
@RequestMapping("/a1")
public void a1(String name, HttpServletResponse resp) throws IOException {
// 接收前端传来的username等参数
System.out.println("param->" + name);
if ("kuang".equals(name)) {
resp.getWriter().print("true");
} else {
resp.getWriter().print("false");
}
}
引入JQuery.js的方式,如果静态资源不被过滤,会报jQuery找不到。
13.6.Ajax执行流程
Json:为了前后端彻底分离。
这样就实现了前后端交互,并且实现了异步刷新。
Ajax将主动权交给前端。
13.7.Ajax验证用户名体验
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
function a1(){
$.post("${pageContext.request.contextPath}/a3",{"name":$("#name").val()},function (data){
// console.log(data)
if (data.toString()==="ok"){
$("#userInfo").css("color","green");
}else {
$("#userInfo").css("color","red");
}
$("#userInfo").html(data);
})
}
function a2(){
$.post({
url:"${pageContext.request.contextPath}/a3",
data:{"pwd":$("#pwd").val()},
success:function (data) {
// console.log(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="a1()">
<span id="userInfo"></span>
</p>
<p>
密码:<input type="text" id="pwd" onblur="a2()">
<span id="pwdInfo"></span>
</p>
</body>
</html>
AjaxController .java
package com.kuang.controller;
import com.kuang.pojo.User;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@RestController
public class AjaxController {
@RequestMapping("/a3")
public String a3(String name, String pwd) {
String msg = "";
if (name != null) {
if ("admin".equals(name)) {
msg = "ok";
} else {
msg = "用户名有误";
}
}
if (pwd != null) {
if ("123456".equals(pwd)) {
msg = "ok";
} else {
msg = "密码有误";
}
}
return msg;
}
}
13.8.JSON乱码问题的解决
在Spring核心配置文件applicationContext.xml中:
<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>
14.拦截器
14.1.Springmvc的拦截器:
拦截器自带静态资源过滤。
拦截器写完,aop和拦截器要配置。
14.2.登录判断验证:
登录页:login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/user/login" method="post">
用户名: <input type="text" name="username"/>
密码:<input type="text" name="password"/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
LoginController
package com.kuang.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 {
@RequestMapping("/main")
public String main(){
return "main";
}
@RequestMapping("/goLogin")
public String login(){
return "login";
}
@RequestMapping("/login")
public String login(Model model,HttpSession session, String username, String password) {
// 把用户的信息存在session中。
System.out.println(username+"---"+password);
model.addAttribute("username",username);
session.setAttribute("userLoginInfo", username);
return "main";
}
@RequestMapping("/goOut")
public String goOut(HttpSession session){
session.removeAttribute("userLoginInfo");
return "main";
}
}
首页:main.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<p>首页</p>
<span>${username}</span>
<p>
<a href="${pageContext.request.contextPath}/user/goOut" >注销</a>
</p>
</body>
</html>
初始页:index.jsp
<%@ 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>
拦截器:LoginInterceptor
package com.kuang.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 {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
// 判断什么情况下登录
// session中有东西
if (session.getAttribute("userLoginInfo")!=null){
return true;
}
// 登录页面也会放行(只能通过登录页面提交数据的方式登录)
if (request.getRequestURI().contains("login")){
return true;
}
// 判断什么情况下没有登录
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
return false;
}
}
在spring中注册拦截器:
<!-- 拦截器设置-->
<mvc:interceptors>
<!-- 拦截哪里,谁去拦截。-->
<mvc:interceptor>
<!-- 包括这个请求下面的所以请求。-->
<mvc:mapping path="/user/**"/>
<bean class="com.kuang.config.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
15.文件下载和上传
15.1.文件上传
导入依赖:
<!--文件上传-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
<!--servlet-api导入高版本的-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
文件上传的配置:
<!--文件上传配置 id=multipartResolver,不能是其他的id。-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 -->
<property name="defaultEncoding" value="utf-8"/>
<!-- 上传文件大小上限,单位为字节(10485760=10M) -->
<property name="maxUploadSize" value="10485760"/>
<property name="maxInMemorySize" value="40960"/>
</bean>
FileController
package com.kuang.controller;
import org.springframework.stereotype.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 javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
@RestController
public class FileController {
//@RequestParam("file") 将 name=file控件 得到的文件 封装成CommonsMultipartFile 对象
//批量上传CommonsMultipartFile则为数组即可
/**
*
* @param file CommonsMultipartFile:是用来接收文件的。
* @param request
* @return
* @throws IOException
*/
@RequestMapping("/upload")
public String fileUpload(@RequestParam("file") CommonsMultipartFile file , HttpServletRequest request) throws IOException {
//1.获取文件名 : file.getOriginalFilename();
String uploadFileName = file.getOriginalFilename();
//2.如果文件名为空,直接回到首页!
if ("".equals(uploadFileName)){
return "redirect:/index.jsp";
}
System.out.println("上传文件名 : "+uploadFileName);
//3.上传路径保存设置
String path = request.getServletContext().getRealPath("/upload");
//如果路径不存在,创建一个
File realPath = new File(path);
if (!realPath.exists()){
realPath.mkdir();
}
System.out.println("上传文件保存地址:"+realPath);
InputStream is = file.getInputStream(); //文件输入流
OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); //文件输出流
//4.读取写出
int len=0;
byte[] buffer = new byte[1024];
while ((len=is.read(buffer))!=-1){
os.write(buffer,0,len);
os.flush();
}
os.close();
is.close();
return "redirect:/index.jsp";
}
/*
* 采用file.Transto 来保存上传的文件
*/
@RequestMapping("/upload2")
public String fileUpload2(@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";
}
@RequestMapping("/download")
public String downloads(HttpServletResponse response , HttpServletRequest request) throws Exception{
System.out.println("download--->");
//要下载的图片地址
// String path = request.getServletContext().getRealPath("/upload");
String path = request.getServletContext().getRealPath("/statics");
String fileName = "1.png";
//1、设置response 响应头
response.reset(); //设置页面不缓存,清空buffer
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);
//2、 读取文件--输入流
InputStream input=new FileInputStream(file);
//3、 写出文件--输出流
OutputStream out = response.getOutputStream();
byte[] buff =new byte[1024];
int index=0;
//4、执行 写出操作
while((index= input.read(buff))!= -1){
out.write(buff, 0, index);
out.flush();
}
out.close();
input.close();
return "ok";
}
}
即4个步骤:1.导包 2.web.xml 3.表单 4.controller
15.2.文件下载
16.总结和展望
16.1.ssm回顾:
重点是闭着眼睛都能写出来的。
在前后端分离之前,或者vue之前,要熟练掌握js。
16.2.前端应该掌握