SpringMVC(总结完毕) 2021.1.13

一日一句:没有笨人,只有懒人!

简介:“springmvc是一种web层mvc框架,它是spring的一个模块,拥有spring的特性。springmvc分离了控制器、模型对象、分派器以及处理程序对象的角色。”

ssm: mybatis+spring+SpringMVC MVC三层结构

SSM=javaweb做项目;

spring: IOC和AOP

SpringMVC:SpringMVC的执行流程!

SpringMVC: SSM框架整合!

MVC:模型(dao,service) 视图(jsp) 控制器(servlet)

jsp:本质就是一个servlet
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
pom.xml依赖

<?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.liang</groupId>
    <artifactId>springMVC</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
<!--导入依赖-->
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.1.9.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.jsp.jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

    </dependencies>



</project>

再新建一个maven普通项目,建立子项目
在这里插入图片描述
在这里插入图片描述
子类导入依赖

<?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">
    <parent>
        <artifactId>springMVC</artifactId>
        <groupId>com.liang</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springmvc-01-serlvet</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <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>
        
    </dependencies>

</project>

配置tomcat
在这里插入图片描述
在这里插入图片描述

什么是springmvc?

在这里插入图片描述
spring:大杂烩,我们可以将springmvc中所有要用到的bean,注册到spring中!
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
只要实现了HttpServlet本质上来说都是属于servlet
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

springMVC的执行流程

在这里插入图片描述
1.用户发送请求
在这里插入图片描述
2.请求到了dispatcherServlet,执行以下代码在这里插入图片描述
3.委托请求给处理器handlermapping和handlerAdapter适配器
在这里插入图片描述
4.处理器返回model and view
在这里插入图片描述
5. model渲染视图,然后返回给前端控制器

虚线就是我们做的,实线springmvc已经帮我们做了
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
编辑controller

package com.liang.controller;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class HelloController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        ModelAndView mv = new ModelAndView();

        //业务代码
        String result = "HelloSpringMVC";
        mv.addObject("msg",result);


        //视图跳转
mv.setViewName("test");


        return mv;
    }
}

在resources下创建springmvc-servlet.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--处理器映射器-->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    <!--处理器适配器-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
    <!--视图解释器器:模板引擎Thymeleaf Freemarker-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
    <!--前缀-->
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <!--后缀-->
    <property name="suffix" value=".jsp"/>
</bean>
<!--.BeanNameUrlHandlerMapping:bean-->
<bean id="/hello" class="com.liang.controller.HelloController"/>
</beans>

在web下的WEB-INF下创建一个jsp目录,存放jsp文件,在里面创建test.jsp文件

<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2021/1/3
  Time: 18:20
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${msg}
</body>
</html>

写好web.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
         version="5.0">
<!--配置DispatchServlet:这个是SpringMVC的核心:请求分发器,前端控制器-->

    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--DispatcherServlet要绑定spring的配置文件-->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc-servlet.xml</param-value>
    </init-param>
        <!--启动级别-->
        <load-on-startup>1</load-on-startup>
        
    </servlet>
<!--
在springmvc中, /  /*
/:只匹配所有的请求,不会去匹配jsp页面
/*:匹配所有的请求,包括jsp页面
-->

    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
    
</web-app>

Maven可能存在资源过滤问题,我们将配置完善

<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>

在这里插入图片描述
springmvc-servlet.xml配置文件,以下文件中除了 <context:component-scan base-package=“com.kuang.controller”/>这个要改,其他是写死的

<?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
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 -->
    <context:component-scan base-package="com.kuang.controller"/>
    <!-- 让Spring MVC不处理静态资源 .css .js .html .mp3-->
    <mvc:default-servlet-handler />
    <mvc:annotation-driven />

    <!--
    支持mvc注解驱动
        在spring中一般采用@RequestMapping注解来完成映射关系
        要想使@RequestMapping注解生效
        必须向上下文中注册DefaultAnnotationHandlerMapping
        和一个AnnotationMethodHandlerAdapter实例
        这两个实例分别在类级别和方法级别处理。
        而annotation-driven配置帮助我们自动完成上述两个实例的注入。
     -->
    <!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          id="internalResourceViewResolver">
        <!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <!-- 后缀 -->
        <property name="suffix" value=".jsp" />
    </bean>

</beans>

controller控制层

package com.kuang.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Controller
//@RestController  返回json字符串
//@RequestMapping("/hello")
public class HelloController {

    //localhost:8080/hello/h1
    @RequestMapping("/h1")
    public String hello(Model model){
        //封装数据
        model.addAttribute("msg","hello,springmvcAnnotation!");

        return "hello";//会被视图解释器处理
    }

}

完整步骤
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
controller

package com.liang.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller  //代表这个类会被spring接管,被注解的类,中的所有方法
//如果返回值是string,并且有具体页面可以跳转,那么就会被试图解释器解析;
public class ControllerTest2 {

    @RequestMapping("/t2")
    public String test1(Model model){

        model.addAttribute("msg","hello,controller2");
        return "test";//return是view     //WEB-INF/jsp/test.jsp
    }
}


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

RestFul风格

请求地址一样,可以通过不同的请求方式来实现不同的效果!
在这里插入图片描述
在这里插入图片描述

package com.liang.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class RestFulController {

    @RequestMapping("/add")
    public String test1(int a, int b, Model model){//model是传数据的
    int res = a+b;
    model.addAttribute("msg","结果为"+res);
        return "/test.jsp";
    }

}

在这里插入图片描述
使用@PathVariable注解,让方法参数的值对应绑定到一个url模板变量上
在这里插入图片描述

package com.liang.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class RestFulController {
//原来的:http://localhost:8080/add?a=1&b=2
//RestFul: http://localhost:8080/add/a/b



    @RequestMapping("/add/{a}/{b}")
    public String test1(@PathVariable int a,@PathVariable int b, Model model){//model是传数据的
    int res = a+b;
    model.addAttribute("msg","结果为"+res);
        return "test";
    }

}

在这里插入图片描述

400请求出问题,500代码有问题

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
狂神牛逼!!!
在这里插入图片描述

创建一个post风格提交的表单

<%--
  Created by IntelliJ IDEA.
  User: Administrator
  Date: 2021/1/4
  Time: 13:41
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="/add/" method="post">
    <input type="text" name="a">
    <input type="text" name="b">
    <input type="submit">
</form>



</body>
</html>

转发和重定向

首先把resources下xml中配置的视图解释器注释掉,以下是测试不配置试图解释器的情况
在这里插入图片描述
在这里插入图片描述
转发,默认的情况下是转发

package com.liang.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@Controller
public class ModelTest1 {

    @RequestMapping("/m1/t1")
    public String test(Model model){

        //转发
model.addAttribute("msg","helloModelTest1");
return "forward:/WEB-INF/jsp/test.jsp";//通过添加关键字forward来说明他是转发
    }
}

重定向,需要重定向的时候加个关键字redirect

package com.liang.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@Controller
public class ModelTest1 {

    @RequestMapping("/m1/t1")
    public String test(Model model){

        //重定向
model.addAttribute("msg","helloModelTest1");
return "redirect:/index.jsp";//通过添加关键字redirect来说明他是重定向
    }
}

在这里插入图片描述
总结:springmvc中的xml中配置的视图解释器的作用是,把访问转发或者重定向的前后缀写好,返回的时候直接写个路径即可,如果没有配置视图解释器就要自己写前后缀这样就比较麻烦,其中转发是默认的一般通过添加关键字forward来说明他是转发,重定向就是回到指定的首页加个关键字redirect

接受请求参数及数据回显

要使用lombok注解data,记得首先要去xml导入相对应的包,还要下载插件

在这里插入图片描述

package com.liang.controller;

import com.liang.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
@RequestMapping("/user")
public class UserController {

    //localhost:8080/user/t1?name=xxxx
@GetMapping("/t1")//@RequestParam("username") 这个无论用不用,前端都要加上,说明这个需要从前端接收数据
    public String test1(@RequestParam("username") String name, Model model){

    //1.接受前端参数
    System.out.println("接收到前端的参数是"+name);
    //2.将返回的结果传递给前端,传给前端就用model
    model.addAttribute("msg",name);
    //3.视图跳转
        return "test";
    }
    //前端接受的是一个对象:id, name ,age
    /*
    1.接受前端用户传递的参数,判断参数的名字,假设名字直接在方法上,可以直接使用
    2.假设传递的是一个对象User,匹配User对象中的字段名:如果名字一致则ok,否则,匹配不到
     */
    @GetMapping("t2")
    public String test2(User user){
        System.out.println(user);
    return "test";

    }
}

创建一个pojo包建个User实体类

package com.liang.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor //有参
@NoArgsConstructor  //无参
public class User {

    private int id;
    private String name;
    private int age;

}

在这里插入图片描述

在这里插入图片描述
传对象用的几种方式
Model、ModelMap、LinkedHashMap
在这里插入图片描述
在这里插入图片描述
@RequestParam(“username”) 这个无论用不用,前端都要加上,说明这个需要从前端接收数据

使用Model接收前端参数

package com.liang.controller;

import com.liang.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
@RequestMapping("/user")
public class UserController {

    //localhost:8080/user/t1?name=xxxx
@GetMapping("/t1")//@RequestParam("username") 这个无论用不用,前端都要加上,说明这个需要从前端接收数据
    public String test1(@RequestParam("username") String name, Model model){

    //1.接受前端参数
    System.out.println("接收到前端的参数是"+name);
    //2.将返回的结果传递给前端,传给前端就用model
    model.addAttribute("msg",name);
    //3.视图跳转
        return "test";
    }
    //前端接受的是一个对象:id, name ,age
    /*
    1.接受前端用户传递的参数,判断参数的名字,假设名字直接在方法上,可以直接使用
    2.假设传递的是一个对象User,匹配User对象中的字段名:如果名字一致则ok,否则,匹配不到
    3.一一匹配太麻烦了,直接传对象
     */
    @GetMapping("t2")
    public String test2(User user){
        System.out.println(user);
    return "test";

    }

}

404乱码问题

如何配置过滤器解决乱码

首先建一个filter包

package com.liang.filter;

import javax.servlet.*;
import java.io.IOException;

public class EncodingFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        servletRequest.setCharacterEncoding("utf-8");
        servletResponse.setCharacterEncoding("utf-8");

        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

写完后,在web.xml添加配置

<filter>
        <filter-name>encoding</filter-name>
        <filter-class>com.liang.filter.EncodingFilter</filter-class>
    </filter>
        <filter-mapping>
            <filter-name>encoding</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
    

在这里插入图片描述

在这里插入图片描述
设置tomcat
在这里插入图片描述
get请求不会乱码,因为已经自动配置了过滤器,但是post会中文乱码喔

不得不说,乱码问题是在我们开发中十分常见的问题,也是让我们程序猿比较头大的问题!

以前乱码问题通过过滤器解决 , 而SpringMVC给我们提供了一个过滤器 , 可以在web.xml中配置 .

修改了xml文件需要重启服务器!

<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>

在这里插入图片描述
controller代码

package com.liang.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.Mapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class EncodingController {

    @PostMapping("/e/t")
    public String test(Model model,String name){
        System.out.println(name);
        model.addAttribute("msg",name); //获取表单提交的值
        return "test"; //跳转到test页面显示输入的值
    }
}

web.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
         version="5.0">

    <!--1.配置DispatchServlet-->
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc-servlet.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. 配置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>

form.jsp在web目录下,别放WEB-INF下面,可能会访问不到

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="/e/t" method="post">
    <input type="text" name="name">
    <input type="submit">
</form>
</body>
</html>

​ web-inf下的jsp目录中的test.jsp文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${msg}
</body>
</html>

resources下的springmvc-servlet.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 -->
    <context:component-scan base-package="com.liang.controller"/>
    <!-- 让Spring MVC不处理静态资源 .css .js .html .mp3-->
    <mvc:default-servlet-handler />
    <mvc:annotation-driven />

    <!--
    支持mvc注解驱动
        在spring中一般采用@RequestMapping注解来完成映射关系
        要想使@RequestMapping注解生效
        必须向上下文中注册DefaultAnnotationHandlerMapping
        和一个AnnotationMethodHandlerAdapter实例
        这两个实例分别在类级别和方法级别处理。
        而annotation-driven配置帮助我们自动完成上述两个实例的注入。
     -->
    <!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          id="internalResourceViewResolver">
        <!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <!-- 后缀 -->
        <property name="suffix" value=".jsp" />

    </bean>


</beans>

什么是JSON?

在这里插入图片描述
在这里插入图片描述
前后端分离时代:

  • 后端部署后端,提供接口(controller下的类就是一个借口),提供数据

​ json(数据交换格式)

  • 前端独立部署,负责渲染后端数据

在这里插入图片描述
jsontest.html测试代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script type="text/javascript">
//编写一个JavaScript对象  es6
var user={
    name:"梁伟浩",
    age:5,
    sex:"男"

};
//将js对象转化为json对象
var json= JSON.stringify(user);
console.log(json);

console.log("===========================");

//将json对象转换为JavaScript对象
var obj = JSON.parse(json);
console.log(obj);
    </script>


</head>
<body>

</body>
</html>

Jackson

在这里插入图片描述

Controller返回JSON数据

Jackson应该是目前比较好的json解析工具了

当然工具不止这一个,比如还有阿里巴巴的 fastjson 等等。

我们这里使用Jackson,使用它需要导入它的jar包;

<!-- 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>

配置SpringMVC需要的配置

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.注册servlet-->
   <servlet>
       <servlet-name>SpringMVC</servlet-name>
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
       <!--通过初始化参数指定SpringMVC配置文件的位置,进行关联-->
       <init-param>
           <param-name>contextConfigLocation</param-name>
           <param-value>classpath:springmvc-servlet.xml</param-value>
       </init-param>
       <!-- 启动顺序,数字越小,启动越早 -->
       <load-on-startup>1</load-on-startup>
   </servlet>

   <!--所有请求都会被springmvc拦截 -->
   <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>

</web-app>

springmvc-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 自动扫描指定的包,下面所有注解类交给IOC容器管理 -->
    <context:component-scan base-package="com.liang.controller"/>
    
    <!--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>




    <!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          id="internalResourceViewResolver">
        <!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <!-- 后缀 -->
        <property name="suffix" value=".jsp" />
    </bean>

</beans>

配置文件后缀这里web-inf下有个jsp文件夹,记得加上

  • 创建一个pojo/entity包,然后编写一个User的实体类,然后我们去编写我们测试的controller;

    package com.liang.pojo;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    //xml记得导入lombok
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User {
        private String name;
        private int age;
        private String sex;
    
    }
    
    
    • 编写一个controller接口
package com.liang.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.liang.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;


@RestController  //以下所有方法只返回字符串
public class UserController {

    @RequestMapping("/json1")
   // @ResponseBody//他就不会走视图解释器,会直接返回一个字符串
    public String json1() throws JsonProcessingException {

       //jackson这个包里面有ObjectMapper
       ObjectMapper mapper = new ObjectMapper();


       //创建一个对象
       User user = new User("梁伟浩1号",3,"男");

       String str = mapper.writeValueAsString(user);

       return str;
    }

    @RequestMapping("/j")
    // @ResponseBody//他就不会走视图解释器,会直接返回一个字符串
    public String json2() throws JsonProcessingException {

        //jackson这个包里面有ObjectMapper
        ObjectMapper mapper = new ObjectMapper();

        List<User> userList = new ArrayList<>();

        //创建一个对象
        User user1 = new User("梁伟浩1号",3,"男");
        User user2 = new User("梁伟浩2号",3,"男");
        User user3 = new User("梁伟浩3号",3,"男");
        User user4 = new User("梁伟浩4号",3,"男");

        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
        userList.add(user4);

        String str = mapper.writeValueAsString(userList);

        return str;
    }

    @RequestMapping("/j3")
    // @ResponseBody//他就不会走视图解释器,会直接返回一个字符串
    public String json3() throws JsonProcessingException {

        //jackson这个包里面有ObjectMapper
        ObjectMapper mapper = new ObjectMapper();
//使用objectmapper来格式化输出




        Date date = new Date();

        SimpleDateFormat adf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    //ObjectMapper,时间解析后的默认格式为:Timestamp,时间戳
        return mapper.writeValueAsString(adf.format(date));
    }
}

@RequestMap![ping(value = "/js](https://img-blog.csdnimg.cn/20210107213519349.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDE2NTI4MA==,size_16,color_FFFFFF,t_70)
on1",produces = "application/json;charset=utf-8")  原生态的乱码解决方式

在这里插入图片描述
乱码统一解决

上一种方法比较麻烦,如果项目中有许多请求则每一个都要添加,可以通过Spring配置统一指定,这样就不用每次都去处理了!

我们可以在springmvc的配置文件上添加一段消息StringHttpMessageConverter转换配置!

<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>

在这里插入图片描述

打印时间日期


    @RequestMapping("/j3")
    // @ResponseBody//他就不会走视图解释器,会直接返回一个字符串
    public String json3() throws JsonProcessingException {

        //jackson这个包里面有ObjectMapper
        ObjectMapper mapper = new ObjectMapper();

        Date date = new Date();

        SimpleDateFormat adf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    //ObjectMapper,时间解析后的默认格式为:Timestamp,时间戳
        return mapper.writeValueAsString(adf.format(date));
    }

在这里插入图片描述
如果我们经常使用的话,这样是比较麻烦的,我们可以将这些代码封装到一个工具类中

package com.liang.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_DATES_AS_TIMESTAMPS,false);

        //自定义日期的格式
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        mapper.setDateFormat(sdf);

        try {
            return mapper.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

}

我们使用工具类,代码就更简洁了!

@RequestMapping("/json5")
public String json5() throws JsonProcessingException {
   Date date = new Date();
   String json = JsonUtils.getJson(date);
   return json;
}

FastJson

在这里插入图片描述
fastjson.jar是阿里开发的一款专门用于Java开发的包,可以方便的实现json对象与JavaBean对象的转换,实现JavaBean对象与json字符串的转换,实现json对象与json字符串的转换。实现json的转换方法很多,最后的实现结果都是一样的。

fastjson 的 pom依赖!

<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>fastjson</artifactId>
   <version>1.2.60</version>
</dependency>

在这里插入图片描述

SpringMVC:整合SSM

创建数据库,记住一部分一部分执行

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,'从进门到进牢');

在这里插入图片描述
在这里插入图片描述
and then导入依赖

<?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.liang</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>

    <!--依赖:junit,数据库驱动,连接池,servlet,jsp,mybatis,mybatis-spring,spring-->
    <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>
        <!--c3p0: 数据库连接池 -->
        <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>
        <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.1.9.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.1.9.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.10</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>

在这里插入图片描述
在这里插入图片描述
在url后添加:?serverTimezone=GMT%2B8设置时区,即可连接成功
在这里插入图片描述
在这里插入图片描述
dao=mapper

2、建立基本结构和配置框架!

  • com.liang.pojo 实体类

  • com.liang.dao

  • com.liang.service

  • com.liang.controller

  • mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?> ```
  • applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>

<import resource="classpath:spring-service.xml"/>



> Mybatis层编写

1、数据库配置文件 **database.properties**

```sql
jdbc.driver=com.mysql.jdbc.Driver
#如果使用的mysql8.0+,增加一个市区的配置
#在idea连接数据库url后添加:?serverTimezone=GMT%2B8设置时区,即可连接成功
jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=false&useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=root

idea连接数据库
在这里插入图片描述
在这里插入图片描述
2.写好实体类后,在dao写一个mapper接口

package com.liang.dao;

import com.kuang.pojo.Books;
import java.util.List;

public interface BookMapper {

   //增加一个Book
   int addBook(Books book);

   //根据id删除一个Book
   int deleteBookById(int id);

   //更新Book
   int updateBook(Books books);

   //根据id查询,返回一个Book
   Books queryBookById(int id);

   //查询全部Book,返回list集合
   List<Books> queryAllBook();

}

创建一个mapper.xml,一个mapper对应一个接口

3、编写接口对应的 Mapper.xml 文件。需要导入MyBatis的包;

<?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.kuang.dao.BookMapper">

   <!--增加一个Book-->
   <insert id="addBook" parameterType="Books">
      insert into ssmbuild.books(bookName,bookCounts,detail)
      values (#{bookName}, #{bookCounts}, #{detail})
   </insert>

   <!--根据id删除一个Book-->
   <delete id="deleteBookById" parameterType="int">
      delete from ssmbuild.books where bookID=#{bookID}
   </delete>

   <!--更新Book-->
   <update id="updateBook" parameterType="Books">
      update ssmbuild.books
      set bookName = #{bookName},bookCounts = #{bookCounts},detail = #{detail}
      where bookID = #{bookID}
   </update>

   <!--根据id查询,返回一个Book-->
   <select id="queryBookById" resultType="Books">
      select * from ssmbuild.books
      where bookID = #{bookID}
   </select>

   <!--查询全部Book-->
   <select id="queryAllBook" resultType="Books">
      SELECT * from ssmbuild.books
   </select>

</mapper>

4、编写Service层的接口和实现类

接口:

package com.kuang.service;

import com.kuang.pojo.Books;

import java.util.List;

//BookService:底下需要去实现,调用dao层
public interface BookService {
   //增加一个Book
   int addBook(Books book);
   //根据id删除一个Book
   int deleteBookById(int id);
   //更新Book
   int updateBook(Books books);
   //根据id查询,返回一个Book
   Books queryBookById(int id);
   //查询全部Book,返回list集合
   List<Books> queryAllBook();
}

实现类:

package com.kuang.service;

import com.kuang.dao.BookMapper;
import com.kuang.pojo.Books;
import java.util.List;

public class BookServiceImpl implements BookService {

   //调用dao层的操作,设置一个set接口,方便Spring管理
   private BookMapper bookMapper;

   public void setBookMapper(BookMapper bookMapper) {
       this.bookMapper = bookMapper;
  }
   
   public int addBook(Books book) {
       return bookMapper.addBook(book);
  }
   
   public int deleteBookById(int id) {
       return bookMapper.deleteBookById(id);
  }
   
   public int updateBook(Books books) {
       return bookMapper.updateBook(books);
  }
   
   public Books queryBookById(int id) {
       return bookMapper.queryBookById(id);
  }
   
   public List<Books> queryAllBook() {
       return bookMapper.queryAllBook();
  }
}

OK,到此,底层需求操作编写完毕!

Spring层

1、配置Spring整合MyBatis,我们这里数据源使用c3p0连接池;

2、我们去编写Spring整合Mybatis的相关的配置文件;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"
       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">
<!--1.关联数据库配置文件-->
<context:property-placeholder location="classpath:database.properties"/>

<!--2.数据库连接池
dbcp:半自动化操作,不能自动连接
cp30:自动化操作(自动化加载配置文件,并且可以自动设置到对象中)
druid:
-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <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.liang.dao"/>
    </bean>


</beans>

3、Spring整合service层

<?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">

<!--1.扫描service下的包-->
    <context:component-scan base-package="com.liang.service"/>

    <!--2.将我们所有的业务注入到spring,可以通过配置,或者注解实现-->
    <bean id="BookServiceImpl" class="com.liang.service.BookServiceImpl">
        <property name="bookMapper" ref="bookMapper"/>
</bean>

    <!--3.声明式事务配置-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!--注入数据源-->
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--4.aop事务支持-->

</beans>

Spring层搞定!再次理解一下,Spring就是一个大杂烩,一个容器!对吧!
添加成为web项目

web.xml的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
         version="5.0">
    <!--dispatchServlet-->
<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>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
   <init-param>
       <param-name>encoding</param-name>
       <param-value>utf-8</param-value>
   </init-param>
    </filter>

    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <!--session-->
    <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: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
       http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

<!--1.注解驱动-->
<mvc:annotation-driven/>
    <!--2.静态资源过滤-->
    <mvc:default-servlet-handler/>
    <!--3.扫描包:controller-->
<context:component-scan base-package="com.liang.controller"/>
    <!--4.视图解释器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <property name="suffix" value=".jsp"/>
</bean>
</beans>

至此整合SSM完毕

开始编写controller层,controller调用service层

package com.liang.controller;

import com.liang.pojo.Books;
import com.liang.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

@Controller
@RequestMapping("/book")
public class BookController {
    //controller调用service层

    @Autowired
    @Qualifier("BookServiceImpl")//指定加载的类
    private BookService bookService;

    //查询全部的书籍,并且返回到一个书籍展示页面
    @RequestMapping("/allBook")
    public  String list(Model model){
        List<Books> books = bookService.queryAllBook();
        model.addAttribute("books",books);//返回前端
        return "allBook";
    }

}

记得配置好tomcat,在artifacts哪里建好lib目录,添加好包
在这里插入图片描述

解决报错思路

1.问题:bean不存在

步骤:

  1. 查看bean注入是否成功
    在这里插入图片描述
    2.junit单元测试,看我们的代码是否能够查询出来结果!

3.以上两个都正常,问题一定不在我们的底层,是spring出了无问题

4.springmvc,整合的时候没有调用到我们service层的bean:

  • applicationContext.xml 没有注入bean
  • web.xml中,我们也绑定过配置文件!,发现问题,我们配置的是springmvc-mvc.xml这里面确实没有service bean,所以报空指针
出现这个错误是因为URL中出现了useSSL=true,只需要改成false即可。
jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=true

在这里插入图片描述
这里我们配置的是springmvc-mvc.xml这里面确实没有service bean,所以报空指针
在这里插入图片描述
在这里插入图片描述
美化一下前端书记展示登录进去那个页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>首页</title>
    <style>
      a{
      text-decoration: aqua;
        color: black;
        font-size: 15px;
      }

      h3{
        width: 180px;
        height: 50px;
        margin: 100px auto;
        text-align: center;
        line-height: 35px;
        background: bisque;
        border-radius: 15px;//圆角
      }

    </style>

  </head>
  <body>
<h3>
  <a href="${pageContext.request.contextPath}/book/allBook">进入书籍页面</a>
</h3>
  </body>
</html>

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

书籍显示allBook.jsp数据前端页面
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>书籍展示</title>
    <%--bootstrap美化界面--%>
    <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
    <div class="row clearfix">
        <div class="col-md-12 column">
            <div class="page-header">
                <h1>
                    <small>书籍列表 ------ 显示所有书籍</small>
                </h1>
            </div>

        </div>
    </div>
<div class="row clearfix">
    <div class="col-md-12 column">
        <table class="table table-hover table-striped">
            <thead>
            <tr>
                <th>书籍编号</th>
                <th>书籍名称</th>
                <th>书籍数量</th>
                <th>书籍详情</th>
            </tr>
            </thead>
            <%--书籍从数据库中查询出来,从这个list中遍历出来,foreach--%>
            <tbody>
                <c:forEach var="book" items="${books}">
                    <tr>
                        <td>${book.bookID}</td>
                        <td>${book.bookName}</td>
                        <td>${book.bookCounts}</td>
                        <td>${book.detail}</td>
                    </tr>
                </c:forEach>

            </tbody>

        </table>
    </div>
</div>
    </div>
</body>
</html>

添加书籍

在这里插入图片描述

一定要留意/不能少,对应跳转的页面的名字不能写错
<a href="${pageContext.request.contextPath}/book/toAddBook">新增书籍</a> book前面那个斜杆别忘记要加上去

在这里插入图片描述

一定要留意标点符号的相i对应,别漏,别多
a class="btn btn-primary" 这是一个小按钮

controller层代码

package com.liang.controller;

import com.liang.pojo.Books;
import com.liang.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

@Controller
@RequestMapping("/book")
public class BookController {
    //controller调用service层

    @Autowired
    @Qualifier("BookServiceImpl")//指定加载的类
    private BookService bookService;

    //查询全部的书籍,并且返回到一个书籍展示页面
    @RequestMapping("/allBook")
    public  String list(Model model){
        List<Books> books = bookService.queryAllBook();
        model.addAttribute("books",books);//返回前端
        return "allBook";
    }
    //跳转到增加书籍页面
    @RequestMapping("toAddBook")
    public String toAddPageer(){
        return "addBook";
    }
    //添加书籍的请求
    @RequestMapping("/addBook")
    public String addBook(Books books){
        System.out.println("addBook=>"+books);
        bookService.addBook(books);
        return "redirect:/book/allBook";//重定向 回到首页@RequestMapping("/allBook")
    }

}

index.jsp前端首页代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>首页</title>
    <style>
      a{
      text-decoration: #00ffff;
        color: black;
        font-size: 15px;
      }

      h3{
        width: 180px;
        height: 50px;
        margin: 100px auto;
        text-align: center;
        line-height: 35px;
        background: bisque;
        border-radius: 15px;//圆角
      }

    </style>

  </head>
  <body>
<h3>
  <a href="${pageContext.request.contextPath}/book/allBook">进入书籍页面</a>
</h3>
  </body>
</html>

allBook.jsp全部书籍首页页面代码

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>书籍展示</title>
    <%--bootstrap美化界面--%>
    <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
    <div class="row clearfix">
        <div class="col-md-12 column">
            <div class="page-header">
                <h1>
                    <small>书籍列表 ------ 显示所有书籍</small>
                </h1>
            </div>
<div class="row">
    <div class="col-md-4 columu">
        <%--toAllBook--%>
<a class="btn btn-primary" href="${pageContext.request.contextPath}/book/toAddBook">新增书籍</a>
    </div>
</div>


        </div>
    </div>
<div class="row clearfix">
    <div class="col-md-12 column">
        <table class="table table-hover table-striped">
            <thead>
            <tr>
                <th>书籍编号</th>
                <th>书籍名称</th>
                <th>书籍数量</th>
                <th>书籍详情</th>
            </tr>
            </thead>
            <%--书籍从数据库中查询出来,从这个list中遍历出来,foreach--%>
            <tbody>
                <c:forEach var="book" items="${books}">
                    <tr>
                        <td>${book.bookID}</td>
                        <td>${book.bookName}</td>
                        <td>${book.bookCounts}</td>
                        <td>${book.detail}</td>
                    </tr>
                </c:forEach>

            </tbody>

        </table>
    </div>
</div>
</div>
</body>
</html>

addBook.jsp增加书籍页面代码

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>书籍展示</title>
    <%--bootstrap美化界面--%>
    <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">

    <div class="row clearfix">
        <div class="col-md-12 column">
            <div class="page-header">
                <h1>
                    <small>新增书籍</small>
                </h1>
            </div>
        </div>
    </div>


    <form action="${pageContext.request.contextPath}/book/addBook" method="post">
        <div class="form-group">
            <label>书籍名称:</label>
            <input type="text" name="bookName" class="form-control" required>
        </div>
        <div class="form-group">
            <label >书籍数量:</label>
            <input type="text" name="bookCounts" class="form-control"required>
        </div>
        <div class="form-group">
            <label>书籍描述:</label>
            <input type="text" name="detail" class="form-control"required>
        </div>
            <div class="form-group">
                <input type="submit" class="form-control" value="添加">
            </div>
    </form>

</div>
</body>
</html>

required加了这个之后,表单提交不能为空
在这里插入图片描述
在这里插入图片描述
添加成功啦!!!
在这里插入图片描述

修改书籍

controller层代码

   //跳转到修改页面
    @RequestMapping("/toUpdate")
    public String toUpdatePaper(int id,Model model){
        Books books = bookService.queryBookById(id);
        model.addAttribute("QBook",books);
        return "updateBook";
    }

    //修改书籍:id
    @RequestMapping("/updateBook")
    public String updateBook(Books books){
        System.out.println("updateBook=="+books);
        int i = bookService.updateBook(books);
        if (i>0){
            System.out.println("添加成功"+books);
        }
        return "redirect:/book/allBook";
    }

前端update.jsp页面

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>修改书籍</title>
    <%--bootstrap美化界面--%>
    <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">

    <div class="row clearfix">
        <div class="col-md-12 column">
            <div class="page-header">
                <h1>
                    <small>修改书籍</small>
                </h1>
            </div>
        </div>
    </div>


    <form action="${pageContext.request.contextPath}/book/updateBook" method="post">

        <%--出现的问题:我们提交修改的了sql请求,但是修改失败,初次考虑,是事务问题,配置完毕事务,依旧失败--%>
        <%--看一下sql语句:是否执行成功:sql执行失败,修改未完成--%>

            <%--前端隐藏域--%>
          <input type="hidden" name="bookID" value="${QBook.bookID}">

            <div class="form-group">
            <label>书籍名称:</label>
            <input type="text" name="bookName" class="form-control" value="${QBook.bookName}" required>
        </div>
        <div class="form-group">
            <label >书籍数量:</label>
            <input type="text" name="bookCounts" class="form-control" value="${QBook.bookCounts}" required>
        </div>
        <div class="form-group">
            <label>书籍描述:</label>
            <input type="text" name="detail" class="form-control" value="${QBook.detail}" required>
        </div>
            <div class="form-group">
                <input type="submit" class="form-control" value="修改">
            </div>
    </form>

</div>
</body>
</html>

在allBook.jsp主页面添加两个按钮,修改 | 删除添加标签

因为删除书籍,需要找到他的id,根据id删除

  <%--前端隐藏域--%><input type="hidden" name="bookID" value="${QBook.bookID}">
   <th>操作</th>

<td>
                            <a href="${pageContext.request.contextPath}/book/toUpdate?id=${book.bookID}">修改</a><%--在这里传一个bookid过去controller接收,然后controller用int接收--%>
                            &nbsp; | &nbsp;
                            <a href="${pageContext.request.contextPath}/book/deleteBook/${book.bookID}">删除</a><%--这个是restful风格--%>
                        </td>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>书籍展示</title>
    <%--bootstrap美化界面--%>
    <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
    <div class="row clearfix">
        <div class="col-md-12 column">
            <div class="page-header">
                <h1>
                    <small>书籍列表 ------ 显示所有书籍</small>
                </h1>
            </div>
<div class="row">
    <div class="col-md-4 columu">
        <%--toAllBook--%>
<a class="btn btn-primary" href="${pageContext.request.contextPath}/book/toAddBook">新增书籍</a>
    </div>
</div>


        </div>
    </div>
<div class="row clearfix">
    <div class="col-md-12 column">
        <table class="table table-hover table-striped">
            <thead>
            <tr>
                <th>书籍编号</th>
                <th>书籍名称</th>
                <th>书籍数量</th>
                <th>书籍详情</th>
                <th>操作</th>
            </tr>
            </thead>
            <%--书籍从数据库中查询出来,从这个list中遍历出来,foreach--%>
            <tbody>
                <c:forEach var="book" items="${books}">
                    <tr>
                        <td>${book.bookID}</td>
                        <td>${book.bookName}</td>
                        <td>${book.bookCounts}</td>
                        <td>${book.detail}</td>

                        <td>
                            <a href="${pageContext.request.contextPath}/book/toUpdate?id=${book.bookID}">修改</a><%--在这里传一个bookid过去controller接收,然后controller用int接收--%>
                            &nbsp; | &nbsp;
                            <a href="${pageContext.request.contextPath}/book/deleteBook/${book.bookID}">删除</a><%--这个是restful--%>
                        </td>

                    </tr>
                </c:forEach>

            </tbody>

       </table>
    </div>
</div>


</div>


</body>
</html>

刚修改完书籍,但是数据库和页面没有刷新数据,因为没有提交事务(增删改需要提交事务),service处理事务,通过aop事务织入
<?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/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd

        http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd

       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd">

<!--1.扫描service下的包-->
    <context:component-scan base-package="com.liang.service"/>

    <!--2.将我们所有的业务注入到spring,可以通过配置,或者注解实现-->
    <bean id="BookServiceImpl" class="com.liang.service.BookServiceImpl">
        <property name="bookMapper" ref="bookMapper"/>
</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">
        <!--给那些方法配置事务-->
        <!--配置事务的传播特性:new propagation-->
        <tx:attributes>
<!--            <tx:method name="add" propagation="REQUIRED"/>-->
<!--            <tx:method name="delete" propagation="REQUIRED"/>-->
<!--            <tx:method name="update" propagation="REQUIRED"/>-->
<!--            <tx:method name="query" read-only="true"/>-->
            <tx:method name="*" propagation="REQUIRED"/>
        </tx:attributes>
        <!--配置事务植入-->
    </tx:advice>

    <aop:config>
    <aop:pointcut id="txPointCut" expression="execution(* com.liang.dao.*.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
    </aop:config>

</beans>

在这里插入图片描述
写一步测一步,别一下子写完,容易出问题不好找
在这里插入图片描述
前端业务,每次添加完包,记得添加lib包
在这里插入图片描述
在这里插入图片描述
打印日志要放在第一个不然会报错
在这里插入图片描述

记得路径哪里别把/漏了啊

删除书籍

controller层代码

   //删除书籍
    @RequestMapping("/deleteBook/{bookId}")//restful风格,路径取值记得要加{}啊
    public String deleteBook(@PathVariable("bookId") int id){
    bookService.deleteBookById(id);
        return "redirect:/book/allBook";
    }

allBook.jsp的点击按钮删除

                            <a href="${pageContext.request.contextPath}/book/deleteBook/${book.bookID}">删除</a><%--这个是restful风格--%>
                        </td>

在这里插入图片描述
ojbk 增删改查功能完成
在这里插入图片描述

新增搜索查询功能

在这里插入图片描述

编写业务的流程

从下往上写,dao开始写
写完后,小黄鸭调试法,从前端开始读
在这里插入图片描述

记得啊映射的名字不要写错,要对应

报错了话就对着慢慢慢找错出来,是不是有不一样的
在这里插入图片描述
在这里插入图片描述
记得啊标签要放在自己定义相对应那个里面

拦截器

什么是拦截器?

过滤器和拦截器的区别?

  • 拦截器是AOP思想的具体应用

  • 拦截器是springmvc自己的,只有使用了springmvc框架工程才能使用

  • 拦截器只会去拦截控制器(controller)方法,如果访问的是jsp/html/css/images/js是不会进行拦截的

  • 在这里插入图片描述

自定义拦截器

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

一般你写一个新的项目的时候,一定要先把框架能正常跑起来访问,再写其他代码

首先建一个新的moodel,导入ajax中的web.xml和application.xml配置文件,

配置好看tomcat是否能跑起来哦,然后写一个接口访问,看是否能成功

配好拦截器

在这里插入图片描述

在这里插入图片描述

return true;执行下一个拦截器,放行
在web-inf下的所有页面或者资源,只能通过controller,或者servlet进行访问,访问的时候需要一个入口就是在index.jsp这里了

main.jsp主页面
main.jsp主页面

<%@ 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>

login.jsp登录页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<%--在web-inf下的所有页面或者资源,只能通过controller,或者servlet进行访问--%>
<h1>登录页面</h1>
<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>

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>

controller api接口

LoginController

package com.liang.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(HttpSession session,String username, String password,Model Model){
        System.out.println("login==>"+username);

      //把用户的信息存在session中
        session.setAttribute("userLoginInfo", username);
    Model.addAttribute("username",username);
        return "main";
    }


    @RequestMapping("/goOut")
    public String goOut(HttpSession session,String username, String password,Model Model){
//注销,移除掉session的信息
        session.removeAttribute("userLoginInfo");
        return "main";
    }
}

拦截器代码配置

LoginInterceptor

package com.liang.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();


        //放行:判断什么情况下登录
        if (request.getRequestURI().contains("goLogin")){
            return true;
        }

        //说明我在提交登录
        if (request.getRequestURI().contains("login")){
            return true;
        }


        //第一次登录,也是没有session的;
   if (session.getAttribute("userLoginInfo")!=null){
       return true;
   }


    //判断什么情况下没有登录

        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
        return false;
    }
}

写完后,去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"
       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
       https://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 自动扫描指定的包,下面所有注解类交给IOC容器管理 -->
    <context:component-scan base-package="com.liang.controller"/>

   <!--记得配置静态资源过滤-->
 <mvc:default-servlet-handler/>

    <mvc:annotation-driven/>

    <!--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>

    <!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          id="internalResourceViewResolver">
        <!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <!-- 后缀 -->
        <property name="suffix" value=".jsp" />
    </bean>

    <!--拦截器配置-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--包括这个请求下面的所有请求 /-->
            <mvc:mapping path="/**"/>
            <bean class="com.liang.config.MyInterceptor" />
        </mvc:interceptor>

        <mvc:interceptor>
            <!--包括这个请求下面的所有请求 /-->
            <mvc:mapping path="/**"/>
            <bean class="com.liang.config.LoginInterceptor" />
        </mvc:interceptor>
    </mvc:interceptors>
</beans>

在这里插入图片描述

文件上传和下载

准备工作

文件上传是项目开发中最常见的功能之一 ,springMVC 可以很好的支持文件上传,但是SpringMVC上下文中默认没有装配MultipartResolver,因此默认情况下其不能处理文件上传工作。如果想使用Spring的文件上传功能,则需要在上下文中配置MultipartResolver。

前端表单要求:为了能上传文件,必须将表单的method设置为POST,并将enctype设置为multipart/form-data。只有在这样的情况下,浏览器才会把用户选择的文件以二进制数据发送给服务器;

对表单中的 enctype 属性做个详细的说明:

  • application/x-www=form-urlencoded:默认方式,只处理表单域中的 value 属性值,采用这种编码方式的表单会将表单域中的值处理成 URL 编码方式。

  • multipart/form-data:这种编码方式会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数中,不会对字符编码。

  • text/plain:除了把空格转换为 “+” 号外,其他字符都不做编码处理,这种方式适用直接通过表单发送邮件。

    <form action="" enctype="multipart/form-data" method="post">
       <input type="file" name="file"/>
       <input type="submit">
    </form>
    

文件上传

在这里插入图片描述

文件上传

1、导入文件上传的jar包,commons-fileupload , Maven会自动帮我们导入他的依赖包 commons-io包;

<!--文件上传-->
<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>

2、配置bean:multipartResolver

注意!!!这个bena的id必须为:multipartResolver , 否则上传文件会报400的错误!在这里栽过坑,教训!

<!--文件上传配置-->
<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.liang.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则为数组即可
    @RequestMapping("/upload")
    public String fileUpload(@RequestParam("file") CommonsMultipartFile file , HttpServletRequest request) throws IOException {

        //获取文件名 : file.getOriginalFilename();
        String uploadFileName = file.getOriginalFilename();

        //如果文件名为空,直接回到首页!
        if ("".equals(uploadFileName)){
            return "redirect:/index.jsp";
        }
        System.out.println("上传文件名 : "+uploadFileName);

        //上传路径保存设置  UUID
        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)); //文件输出流

        //读取写出
        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(value="/download")
    public String downloads(HttpServletResponse response , HttpServletRequest request) throws Exception{
        //要下载的图片地址
        String  path = request.getServletContext().getRealPath("/upload");
        String  fileName = "1.jpg";

        //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";
    }

}

文件下载

在这里插入图片描述
在这里插入图片描述
FileController下载代码

@RequestMapping(value="/download")
    public String downloads(HttpServletResponse response , HttpServletRequest request) throws Exception{
        //要下载的图片地址
        String  path = request.getServletContext().getRealPath("/upload");
        String  fileName = "1.jpg";

        //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";
    }

在这里插入图片描述
前端

<a href="/download">点击下载</a>

测试,文件下载OK,大家可以和我们之前学习的JavaWeb原生的方式对比一下,就可以知道这个便捷多了!
在这里插入图片描述
***完毕!撒花!!!!***

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Java中的战斗机

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值