SpringMVC重点记录

目录

  • 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.前端应该掌握

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/460105.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

excel导入功能(适用于vue和react都可)

如图所示&#xff08;需求&#xff09;&#xff1a;点击导入excel后&#xff0c;数据自动新增到列表数据内 这里以vue3 andt 为例 template 标签内代码 &#xff1a; <a-uploadname"file":multiple"true":show-upload-list"false":customR…

分布式CAP理论

CAP理论&#xff1a;一致性&#xff08;Consistency&#xff09;、可用性&#xff08;Availability&#xff09;和分区容错性&#xff08;Partition tolerance&#xff09;。是Eric Brewer在2000年提出的&#xff0c;用于描述分布式系统基本性质的定理。这三个性质在分布式系统…

软件杯 深度学习 opencv python 实现中国交通标志识别_1

文章目录 0 前言1 yolov5实现中国交通标志检测2.算法原理2.1 算法简介2.2网络架构2.3 关键代码 3 数据集处理3.1 VOC格式介绍3.2 将中国交通标志检测数据集CCTSDB数据转换成VOC数据格式3.3 手动标注数据集 4 模型训练5 实现效果5.1 视频效果 6 最后 0 前言 &#x1f525; 优质…

微信小程序将高德地图转为腾讯地图的自行车路线规划

微信小程序后台首页开发设置 相关文档 腾讯后台 微信小程序接入JDK JDK腾讯地图文档 腾讯路线规划文档 核心代码 <map id"myMap" ref"myMap" style"width: 100%; height: calc(100vh - 80px)":latitude"latitude" :scale&qu…

springboot274基于web的电影院购票系统

电影院购票系统设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装电影院购票系统软件来发挥其高效…

CGAN——生成0-9数字图像(Tensorflow+mnist)

1、简介 传统的GAN或者其他的GAN都是通过一堆的训练数据&#xff0c;最后训练出了生成网络&#xff0c;随机输入噪声最后产生的数据是这些训练数据类别中之一&#xff0c;无法提前预测生成的是哪个类别。如果需要定向指定生成某些数据&#xff0c;比如想生成飞机&#xff0c;数…

云计算 3月14号 (TCP三次握手和四次挥手)

1.TCP三次握手和四次挥手 1.TCP的传输过程&#xff1a; Seq 序列号 保障传输过程可靠。 ACK &#xff08;确认消息&#xff09; SYN &#xff08;在建立TCP连接的时候使用&#xff09; FIN &#xff08;在关闭TCP连接的时候使用&#xff09; 3.TCP建立连接的过程&…

ES解析word内容为空的问题和直接使用Tika解析文档的方案

导言 在上一篇文章最后&#xff0c;我们虽然跑通了ES文件搜索的全部流程&#xff0c;但是仍然出现了1个大的问题&#xff1a;ES7.3实测无法索引docx和doc文档&#xff0c;content有值但是无法解析到附件成为可读的可搜索的内容&#xff0c;附件内容为空&#xff08;附件中根本…

Microsoft Remote Desktop Mac

Microsoft Remote Desktop是一款功能强大的远程连接工具&#xff0c;允许用户从远程位置连接到另一台计算机&#xff0c;实现跨设备的无缝协作。无论是在不同的设备之间共享文件、应用程序和其他资源&#xff0c;还是远程访问工作站和服务器&#xff0c;Microsoft Remote Deskt…

Unity开发一个FPS游戏之二

在之前的文章中,我介绍了如何开发一个FPS游戏,添加一个第一人称的主角,并设置武器。现在我将继续完善这个游戏,打算添加敌人,实现其智能寻找玩家并进行对抗。完成的效果如下: fps_enemy_demo 下载资源 首先是设计敌人,我们可以在网上找到一些好的免费素材,例如在Unity…

人机交互三原则,网络7层和对应的设备、公钥私钥

人机交互三原则 heo Mandel提出了人机交互的三个黄金原则&#xff0c;它们强调了相似的设计目标&#xff0c;分别是&#xff1a; 简单总结为&#xff1a;控负持面–>空腹吃面 1&#xff0c;用户控制 2&#xff0c;减轻负担 3&#xff0c;保持界面一致 置用户于控制之下&a…

DHCP在企业网的部署及安全防范

学习目标&#xff1a; 1. DHCP能够解决什么问题&#xff1f; 2. DHCP服务器如何部署&#xff1f; 3. 私接设备会带来什么问题以及如何防范&#xff1f; 给DHCP服务器配置地址&#xff1a; 地址池&#xff1a; DHCP有2种分配模式&#xff1a;全局分配和接口分配 DHCP enable

Upload-labs靶场

文件漏洞上传进行复现 环境搭建--->搭建好环境如下&#xff1a; 打开第一关&#xff0c;尝试文件上传漏洞 根据界面提示&#xff0c;选择一个文件&#xff08;.php文件&#xff09;进行上传&#xff0c;发现无法上传 根据提示是指使用js对不合法文件进行了检查&#xff0c;…

传输层的UDP协议

1. UDP协议报文格式 1.1 16位端口号 UDP协议报文中&#xff0c;端口号占2个字节&#xff0c;包括 源端口号 和 目的端口号。 1.2 16位UDP长度 UDP报文长度为2个字节 &#xff0c;即UDP数据报长度为0~65535&#xff0c;也就是64kb。 1.3 16位UDP检验和 数据在网络传输的…

Python图像处理指南:PIL与OpenCV的比较【第135篇—PIL】

Python图像处理指南&#xff1a;PIL与OpenCV的比较 图像处理在计算机视觉和图像识别等领域中扮演着至关重要的角色。Python作为一种功能强大且易于学习的编程语言&#xff0c;提供了多种库供图像处理使用。在本文中&#xff0c;我们将比较两个最流行的Python图像处理库&#x…

基于正点原子潘多拉STM32L496开发板的简易示波器

一、前言 由于需要对ADC采样性能的评估&#xff0c;重点在于对原波形的拟合性能。 考虑到数据的直观性&#xff0c;本来计划采集后使用串口导出&#xff0c;并用图形做数据拟合&#xff0c;但是这样做的效率低下&#xff0c;不符合实时观察的需要&#xff0c;于是将开发板的屏幕…

云计算2主从数据库

设置主从数据库的目的是将数据库1和数据库2分别建在两个虚拟机上&#xff0c;并实现数据互通访问 首先准备两个虚拟机&#xff0c;这里示例ip分别为&#xff1a; 192.168.200.10&#xff1b;192.168.200.20 修改主机名&#xff0c;一个是mysql1&#xff0c;一个是mysql2&#x…

【每日一问】手机如何开启USB调试?

一、背景 当电脑跟手机之间需要进行交互的时候&#xff0c;可以考虑使用usb进行连接。那么手机如何开启USB调试呢&#xff1f; 二、操作步骤&#xff1a; 思路&#xff1a; 步骤1&#xff1a;手机开启开发者模式 步骤2&#xff1a;在开发者模式中&#xff0c;开启“USB调试”…

【AAAI 2024】解锁深度表格学习(Deep Tabular Learning)的关键:算术特征交互

近日&#xff0c;阿里云人工智能平台PAI与浙江大学吴健、应豪超老师团队合作论文《Arithmetic Feature Interaction is Necessary for Deep Tabular Learning》正式在国际人工智能顶会AAAI-2024上发表。本项工作聚焦于深度表格学习中的一个核心问题&#xff1a;在处理结构化表格…

html5的css使用display: flex进行div居中的坑!

最近做项目的时候&#xff0c;有个需求&#xff0c;一个高度宽度不确定的Div在另一个Div内上下左右居中。 然后以前上下居中用的都是很繁琐的&#xff0c;就打算去百度搜索一个更优秀的方法。 百度AI自己给我一个例子&#xff1a; /* div在容器里居中显示&#xff0c;设置外容…