[Crazy God Talks about Java] SpringMVC Detailed Notes (Full)

Article directory

1. What is SpringMVC

SpringMVC01: What are SpringMVC
assumptions: Is the architecture of your project designed or evolved?

  • AlibabaPHP
  • With the increasing number of users, Java
  • Wang Jian goes to IOE
  • MySQL·MySQL:MySQL->AliSQL、
  • AliRedis·All in one->Microservices

First create the project SpringMVC and import dependencies

<?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>org.example</groupId>
  <artifactId>SpringMVC</artifactId>
  <version>1.0-SNAPSHOT</version>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
    </dependency>
    <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>
  </dependencies>

</project>

1.1. springmvc-01-servvet module

1. Module

image.png

2. Add support for Web app!

image.png
image.png

3、pom.xml (springmvc-01-serlvet)

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

4、HelloServlet

package com.blue.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

//实现Servlet接口
public class HelloServlet extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        //取得参数
        String method = req.getParameter("method");
        if (method.equals("add")){
    
    
            req.getSession().setAttribute("msg","执行了add方法");
        }
        if (method.equals("delete")){
    
    
            req.getSession().setAttribute("msg","执行了delete方法");
        }
        //业务逻辑
        //视图跳转
        req.getRequestDispatcher("/WEB-INF/jsp/hello.jsp").forward(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    
    
        doGet(req,resp);
    }
}

5、test

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

      ${msg}

    </body>
  </html>

6、web

<?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.blue.servlet.HelloServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>hello</servlet-name>
    <url-pattern>hello</url-pattern>
  </servlet-mapping>

</web-app>

7、from

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

      <form action="/hello" method="post">
        <input type="text" name="method">
        <input type="submit">
      </form>

    </body>
  </html>

8. Result

image.png
/hello
image.png
?method=delete
image.png

1.2. What does the MVC framework do?

  • Method to map url to java class or java class
  • Encapsulate user-submitted data.
  • Process the request – call related business processing – encapsulate response data
  • Render the response data. jsp/html and other presentation layer data

1.3. Documentation

4.3.24Documentation

1.4. Attention

If a 404 problem occurs, please review
image.png
and add all packages
image.png
image.png

2. The first MVC program

1.1、springmvc-02-hellomvc

1. Module

image.png

2、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>
    <!--关联一个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>

3、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"/>
    
    <!--视图解析器: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>
    
    <!--Handler-->
    <bean id="/hello" class="org.example.controller.HelloController"/>

</beans>

4、HelloController.java

package org.example.controller;

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

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

//注意:这里我们先导入Controller接口
public class HelloController implements Controller {
    
    
    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
    
    
        //ModelAndView 模型和视图
        ModelAndView mv = new ModelAndView();

        //封装对象,放在ModelAndView中。Model
        mv.addObject("msg","HelloSpringMVC!");
        //封装要跳转的视图,放在ModelAndView中
        mv.setViewName("hello"); //: /WEB-INF/jsp/hello.jsp
        return mv;
    }
}

5. Configurations configuration

Configure Tomcat


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

If an error 404 is reported, it means that the lib dependency is not included.

6. View Project Structure

image.png

7. Result

success! Type /hello
image.png

1.2. Central controller

The principle of SpringMVC is shown in the figure below:
when a request is initiated, the request is intercepted by the front controller, a proxy request is generated based on the request parameters, the actual controller corresponding to the request is found, the controller processes the request, creates a data model, accesses the database, and The model responds to the central controller, the controller uses the model and view to render the view results, returns the results to the central controller, and then returns the results to the requester.
image.png
HandlerMapping: Processor mapper
HandlerAdapter: Processor adapter
viewResolver: View
image.png
resolver The picture shows a more complete flow chart of SpringMVC. The solid line indicates the technology provided by the SpringMVC framework and does not require developers to implement it. The dotted line indicates that developers need to implement it.
Process: First apply for one DispatherServlet, then access and find the corresponding controller /helloaccording to the configuration in springmvc-servlet.xml , that is , then process it in the corresponding controller class, return the model, and then assign values ​​according to the jump in the model Wait, the prefix and suffix configured in springmvc-servlet.xml will jump to the corresponding page.<bean id="/hello" class="com.blue.controller.HelloController"/>com.blue.controller.HelloController
image.png

1.3. In-depth study of SpringMVC

DispatcherServlet

1、web

<?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,这个是SpringMVC的核心:请求分发器,前端控制器-->
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--DispatcherServlet要绑定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>

2、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"/>

  <!--视图解析器: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>

  <!--Handler-->
  <bean id="/hello" class="com.blue.controller.HelloController"/>

</beans>

3、HelloController.java

package org.example.controller;

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

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

//注意:这里我们先导入Controller接口
public class HelloController implements Controller {
    
    
    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
    
    
        //ModelAndView 模型和视图
        ModelAndView mv = new ModelAndView();

        //封装对象,放在ModelAndView中。Model
        mv.addObject("msg","HelloSpringMVC!");
        //封装要跳转的视图,放在ModelAndView中
        mv.setViewName("hello"); //: /WEB-INF/jsp/hello.jsp
        return mv;
    }
}

1.4. Use annotations to develop SpringMVC

module

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


</web-app>

2、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.blue.controller"/>
  <!-- 让Spring MVC不处理静态资源 -->
  <mvc:default-servlet-handler />
  <!--
  支持mvc注解驱动
  在spring中一般采用@RequestMapping注解来完成映射关系
  要想使@RequestMapping注解生效
  必须向上下文中注册DefaultAnnotationHandlerMapping
  和一个AnnotationMethodHandlerAdapter实例
  这两个实例分别在类级别和方法级别处理。
  而annotation-driven配置帮助我们自动完成上述两个实例的注入。
  -->
  <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>

3、HelloController

package org.example.controller;

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

@Controller
    @RequestMapping("/hello")
    public class HelloController {
    
    
        //真实访问地址 : 项目名/hello/h1
        @RequestMapping("/h1")
        public String sayHello(Model model){
    
    
            //封装数据
            //向模型中添加属性msg与值,可以在JSP页面中取出并渲染
            model.addAttribute("msg","hello,SpringMVCAnnotation!");
            return "hello";   //web-inf/jsp/hello.jsp  会被视图解析器处理:
        }
    }

In the view parser, we store all views in the /WEB-INF/ directory, which ensures the security of the views, because the files in this directory cannot be directly accessed by the client.

<%--
   Created by IntelliJ IDEA.
   User: dlmu
   Date: 2022/4/11
   Time: 16:25
   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>

4. View Tomcat configuration

image.png

5. Add all packages to lib

image.png

6. Result

image.png

3. Controller and RestFul

The first method - implement the Controller interface

springmvc-04-controller module

image.png

1、web
<?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>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>

</web-app>
2、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">

  <!--    &lt;!&ndash; 自动扫描包,让指定包下的注解生效,由IOC容器统一管理 &ndash;&gt;-->
  <!--    <context:component-scan base-package="com.blue.controller"/>-->
  <!--    &lt;!&ndash; 让Spring MVC不处理静态资源 &ndash;&gt;-->
  <!--    <mvc:default-servlet-handler />-->
  <!--    <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>

  <bean name="/t1" class="org.example.controller.ControllerTest1"/>

</beans>
3、ControllerTest1
package org.example.controller;

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

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

//只要实现了ControlLer 接口的类。说明这就是一个控制器了
public class ControllerTest1 implements Controller {
    
    

    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
    
    
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","ControllerTest1");
        mv.setViewName("test");
        return mv;
    }
}
4、test.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
  <html>
    <head>
      <title>SpringMVC</title>
    </head>
    <body>
      ${msg}
    </body>
  </html>
5. Result:

image.png

The second way - use the annotation @Controller

1、ControllerTest2

package org.example.controller;

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

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


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

    @RequestMapping("/t2")
    public String test1(Model model){
    
    
        model.addAttribute("msg","ControllerTest2");
        return "test";
    }
}

2、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="org.example.controller"/>
  <!-- 让Spring MVC不处理静态资源 -->
  <!--    <mvc:default-servlet-handler />-->
  <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>

3. Result

correct

RestFul style

Restful is a style of resource positioning and resource operation. Not a standard or a protocol, just a style. Software designed based on this style can be simpler, more hierarchical, and easier to implement mechanisms such as caching.
Function
Resources: All things on the Internet can be abstracted into resources. Resource
operations: Use POST, DELETE, PUT, and GET to operate resources using different methods.
Corresponding to add, delete, modify and query respectively.
Manipulate resources in the traditional way: achieve different effects through different parameters! Single method, post and get

http://127.0.0.1/item/queryItem.action?id=1 查询,GET
http://127.0.0.1/item/saveItem.action 新增,POST
http://127.0.0.1/item/updateItem.action 更新,POST
http://127.0.0.1/item/deleteItem.action?id=1 删除,GET或POST

Use RESTful to operate resources: different effects can be achieved through different request methods! As follows: The request address is the same, but the functions can be different!

http://127.0.0.1/item/1 查询,GET
http://127.0.0.1/item 新增,POST
http://127.0.0.1/item 更新,PUT
http://127.0.0.1/item/1 删除,DELETE

RestFulController

package com.blue.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
    //现在:  http://localhost:8080/add/a/b

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

    @RequestMapping("/add")
    public String test2(int a, int b, Model model){
    
    
        int res = a + b;
        model.addAttribute("msg","结果为"+res);
        return "test";
    }
}

result

image.png

post method

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

    </body>
  </html>
package com.blue.controller;

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

@Controller
public class RestFulController {
    
    

    //原来的: http://localhost:8080/add?a=1&b=2
    //现在:  http://localhost:8080/add/a/b

    //http://localhost:8080/add/a/b
    @RequestMapping("/add/{a}/{b}")
    public String test1(@PathVariable int a,@PathVariable int b, Model model){
    
    
        int res = a + b;
        model.addAttribute("msg","结果1为"+res);
        return "test";
    }

    //http://localhost:8080/add/1/3
    @PostMapping("/add/{a}/{b}")
    public String test3(@PathVariable int a,@PathVariable String b, Model model){
    
    
        String res = a + b;
        model.addAttribute("msg","结果2为"+res);
        return "test";
    }

}

result:
image.png
image.png

4. Data processing and jump

4.1. Result jump method

ModelAndView

ModelTest1

package com.blue.controller;

import org.springframework.stereotype.Controller;
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 test1(HttpServletRequest request, HttpServletResponse response){
    
    
        HttpSession session = request.getSession();
        System.out.println(session.getId());
        return "test";
    }
}

image.png
Revise

package com.blue.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 test1(Model model){
    
    
        //转发
        model.addAttribute("msg","ModelTest1");
        return "forward:/WEB-INF/jsp/test.jsp";
    }

    @RequestMapping("/rsm/t3")
    public String test3(){
    
    
        //重定向
        return "redirect:/test.jsp";
    }

}

image.png

4.2. Data processing

package com.blue.controller;

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

@Controller
@RequestMapping("/user")
public class UserController {
    
    
    
    // url: /user/t1?name=xxx  参数一致
    @GetMapping("/t1")
    public String test1(String name, Model model){
    
    
        // 1. 接收前端参数
        System.out.println("接收到前端的参数为"+name);

        // 2. 将返回的结果传递纷前端, Model
        model.addAttribute("msg",name);

        // 3. 视图跳转
        return "test";
    }

}

image.png

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

    @GetMapping("/t1")
    // url: /user/t1?username=xxx  参数不一致
    public String test1(@RequestParam("username") String name, Model model){
    
    
        // 1. 接收前端参数
        System.out.println("接收到前端的参数为"+name);

        // 2. 将返回的结果传递纷前端, Model
        model.addAttribute("msg",name);

        // 3. 视图跳转
        return "test";
    }

}

image.png

/*
1. 接收前端用户传递的参数,判断参数的名字,假设名字直接在方法上,可以直接使用
2. 假设传递的是一个对象User,匹User对象中的字段名:如果名字一致则OK,否则,匹配不到
*/
@GetMapping("/t2")
    public String test2(User user){
    
    
    System.out.println(user);
	return "test";
}

image.png
image.png

4.3. Garbled code problem

image.png

question:

form.jsp

<html>
  <head>
    <title>Title</title>
  </head>
  <body>

    <form action="/e/t1" method="get">
      <input type="text" name="name">
      <input type="submit">
    </form>

  </body>
</html>

EncodingController

package com.blue.controller;

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

@Controller
public class EncodingController {
    
    

    @GetMapping("/e/t1")
    public String test1(String name, Model model){
    
    
        System.out.println(name);
        model.addAttribute("msg",name);
        return "test";
    }

}

Filter solves garbled characters

Add filter
EncodingFilter

package com.blue.filter;


import javax.servlet.*;
import java.io.IOException;
import java.util.logging.LogRecord;

public class EncodingFilter implements Filter {
    
    

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    
    

    }

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

        filterChain.doFilter(request,response);
    }

    @Override
    public void destroy() {
    
    

    }
}

web.jsp

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

Enter http://localhost:8080/form.jsp, enter, and click to submit
image.png
image.png
the filter of the boss

package com.kuang.filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Map;

/**
 * 解决get和post请求 全部乱码的过滤器
 */
public class GenericEncodingFilter implements Filter {
    
    

    @Override
    public void destroy() {
    
    
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    
    
        // 处理response的字符编码
        HttpServletResponse myResponse = (HttpServletResponse) response;
        myResponse.setContentType("text/html;charset=UTF-8");

        // 转型为与协议相关对象
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        // 对request包装增强
        HttpServletRequest myrequest = new MyRequest(httpServletRequest);
        chain.doFilter(myrequest, response);
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    
    
    }

}

// 自定义request对象,HttpServletRequest的包装类
class MyRequest extends HttpServletRequestWrapper {
    
    

    private final HttpServletRequest request;
    // 是否编码的标记
    private boolean hasEncode;

    // 定义一个可以传入HttpServletRequest对象的构造函数,以便对其进行装饰
    public MyRequest(HttpServletRequest request) {
    
    
        super(request);// super必须写
        this.request = request;
    }

    // 对需要增强方法 进行覆盖
    @Override
    public Map getParameterMap() {
    
    
        // 先获得请求方式
        String method = request.getMethod();
        if (method.equalsIgnoreCase("post")) {
    
    
            // post请求
            try {
    
    
                // 处理post乱码
                request.setCharacterEncoding("utf-8");
                return request.getParameterMap();
            } catch (UnsupportedEncodingException e) {
    
    
                e.printStackTrace();
            }
        } else if (method.equalsIgnoreCase("get")) {
    
    
            // get请求
            Map<String, String[]> parameterMap = request.getParameterMap();
            if (!hasEncode) {
    
     // 确保get手动编码逻辑只运行一次
                for (String parameterName : parameterMap.keySet()) {
    
    
                    String[] values = parameterMap.get(parameterName);
                    if (values != null) {
    
    
                        for (int i = 0; i < values.length; i++) {
    
    
                            // 处理get乱码
                            values[i] = new String(values[i]
                                    .getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8);
                        }
                    }
                }
                hasEncode = true;
            }
            return parameterMap;
        }
        return super.getParameterMap();
    }

    // 取一个值
    @Override
    public String getParameter(String name) {
    
    
        Map<String, String[]> parameterMap = getParameterMap();
        String[] values = parameterMap.get(name);
        if (values == null) {
    
    
            return null;
        }
        return values[0]; // 取回参数的第一个值
    }

    // 取所有值
    @Override
    public String[] getParameterValues(String name) {
    
    
        Map<String, String[]> parameterMap = getParameterMap();
        String[] values = parameterMap.get(name);
        return values;
    }
}
}

5. Json interactive processing

5.1. Jackson Databind import dependencies

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
  <groupId>com.fasterxml.jackson.core</groupId>
  <artifactId>jackson-databind</artifactId>
  <version>2.13.1</version>
</dependency>

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="org.example.controller"/>
    
    <!-- 视图解析器 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          id="internalResourceViewResolver">
        <!-- 前缀 -->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <!-- 后缀 -->
        <property name="suffix" value=".jsp" />
    </bean>
    
    <!--    <bean name="/t1" class="com.blue.controller.ControllerTest1"/>-->

</beans>

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>

User

package org.example.pojo;


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

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    
    
    private String name;
    private int age;
    private String sex;
}

UserController

package org.example.controller;

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

@Controller
public class UserController {
    
    

    @RequestMapping("/j1")
    @ResponseBody   //它就不会走视图解析器,会直接返回一个字符串
    public String json1() throws JsonProcessingException {
    
    
        //创建一个jackson的对象映射器,用来解析数据
        ObjectMapper mapper = new ObjectMapper();
        //创建一个对象
        User user = new User("blue1号", 3, "女");
        //将我们的对象解析成为json格式
        String str = mapper.writeValueAsString(user);
        //由于@ResponseBody注解,这里会将str转成json格式返回;十分方便
        return str;
    }

}

result:
image.png

5.2. Solve the json garbled problem

method one

//produces:指定响应体返回类型和编码
@RequestMapping(value = "/json1",produces = "application/json;charset=utf-8")

image.png

Method Two

Add the following code to springmvc-servlet.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>

image.png

5.3. Return json string for unified solution

1. Return multiple objects

package com.blue.controller;

import com.blue.pojo.User;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
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.util.ArrayList;
import java.util.List;

//@Controller
@RestController //只返回字符串
    public class UserController {
    
    

        //produces:指定响应体返回类型和编码
        //    @RequestMapping(value = "/j1",produces = "application/json;charset=utf-8")
        @RequestMapping("/j1")
        //    @ResponseBody   //它就不会走视图解析器,会直接返回一个字符串
        public String json1() throws JsonProcessingException {
    
    
            //创建一个jackson的对象映射器,用来解析数据
            ObjectMapper mapper = new ObjectMapper();
            //创建一个对象
            User user = new User("blue1号", 3, "女");
            //将我们的对象解析成为json格式
            String str = mapper.writeValueAsString(user);
            //由于@ResponseBody注解,这里会将str转成json格式返回;十分方便
            return str;
        }

        @RequestMapping("/j2")
        public String json2() throws JsonProcessingException {
    
    
            //创建一个jackson的对象映射器,用来解析数据
            ObjectMapper mapper = new ObjectMapper();

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

            User user1 = new User("blue1", 3, "女");
            User user2 = new User("blue1", 3, "女");
            User user3 = new User("blue1", 3, "女");
            User user4 = new User("blue1", 3, "女");

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

            String str = mapper.writeValueAsString(userList);

            return str;
        }

    }

image.png

2. Default timestamp

@RequestMapping("/j3")
public String json3() throws JsonProcessingException {
    
    

	ObjectMapper mapper = new ObjectMapper();
	Date date = new Date();
	return mapper.writeValueAsString(date);
}

image.png

3. Pure java solution - timestamp

@RequestMapping("/j3")
public String json3() throws JsonProcessingException {
    
    

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

image.png

4. Not using timestamps

@RequestMapping("/j4")
public String json4() throws JsonProcessingException {
    
    

    ObjectMapper mapper = new ObjectMapper();
    //不使用 时间戳 的方式
    mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    mapper.setDateFormat(sdf);
    
    Date date = new Date();
    
    // ObjectMapper,时间解析后的默认格式为:Timestamp,时间戳
    return mapper.writeValueAsString(date);
}

image.png

5. Tools

JsonUtils

package com.blue.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("/j5")
public String json5() throws JsonProcessingException {
    
    
    Date date = new Date();
    String json = JsonUtils.getJson(date);
    return json;
}

image.png

5.4、FastJson

fastjson.jar is a package developed by Alibaba specifically for Java development. It can easily convert json objects and JavaBean objects, convert JavaBean objects and json strings, and convert json objects and json strings. There are many ways to convert json, and the final result is the same.

package com.blue.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.blue.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);
    }
}	
@RequestMapping("/j6")
public String json6() throws JsonProcessingException {
    
    

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

    User user1 = new User("blue1", 3, "女");
    User user2 = new User("blue1", 3, "女");
    User user3 = new User("blue1", 3, "女");
    User user4 = new User("blue1", 3, "女");
    
    userList.add(user1);
    userList.add(user2);
    userList.add(user3);
    userList.add(user4);
    
    String str = JSON.toJSONString(userList);
    return str;
	}
}

image.png

6. SpringMVC: Integrate SSM

6.1. Environmental requirements:

  • IDEA
  • MySQL 5.7.19 (I use 8.0+)
  • Tomcat 9
  • Maven 3.6

Requirements:
You need to be proficient in MySQL database, Spring, JavaWeb and MyBatis knowledge, and simple front-end knowledge;

6.2. Create database

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

6.3. Import dependencies

Create a new project, import dependencies junit, mysql, c3p0, servlet, JSP, Mybatis, Spring, and connect to the database

1. pom file dependency

<dependencies>
        <!--Junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!--数据库驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>
        <!-- 数据库连接池 -->
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.5.5</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.6</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.2.0.RELEASE</version>
        </dependency>
        <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.18.10</version>
        </dependency>
    </dependencies>

2. Database

image.png

3. Maven static resource export problem

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

6.4. Basic architecture and configuration files

Create package structure

  • com.kuang.pojo
  • com.kuang.dao
  • com.kuang.service
  • com.kuang.controller

Configuration file

  • mybatis-config.xml
  • applicationContext.xml
  • database.properties

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <typeAliases>
        <package name="com.kuang.pojo"/>
    </typeAliases>
    
</configuration>

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

</beans>

database.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=root

6.5, Mybatis layer

Entity class pojo layer

The fields are the same as in the database

package com.kuang.pojo;

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

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Books {
    
    

    private int bookID;
    private String bookName;
    private int bookCounts;
    private String detail;

}

image.png

Interface dao layer

BookMapper

package com.kuang.dao;

import com.kuang.pojo.Books;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface BookMapper {
    
    

    // 增加一本书
    int addBook(Books books);

    // 删除一本书,booId和id不一样,所以用个注解转换
    int deleteBookById(@Param("bookId") int id);

    //更新一本书
    int updateBook(Books books);

    // 查询一本书
    Books queryBookById(@Param("bookId") int id);

    // 查询全部的书
    List<Books> queryAllBook();

}

BookMapper.xml

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

After the mybatis-config.xml
interface and mapper are written, they need to be bound to 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 去做  -->
    <typeAliases>
        <package name="com.kuang.pojo"/>
    </typeAliases>
    
    <mappers>
        <mapper class="com.kuang.dao.BookMapper"/>
    </mappers>

</configuration>

Business service layer

BookService

package com.kuang.service;


import com.kuang.pojo.Books;

import java.util.List;

public interface BookService {
    
    

    // 增加一本书
    int addBook(Books books);

    // 删除一本书,不是dao层,所以不用加注解@Para("bookId")
    int deleteBookById(int id);

    //更新一本书
    int updateBook(Books books);

    // 查询一本书
    Books queryBookById(int id);

    // 查询全部的书
    List<Books> queryAllBook();

}

BookServiceImpl

package com.kuang.service;


import com.kuang.dao.BookMapper;
import com.kuang.pojo.Books;

import java.util.List;

public class BookServiceImpl implements BookService{
    
    

    // service调 dao层:组合Dao
    private BookMapper bookMapper;

    public void setBookMapper(BookMapper bookMapper) {
    
    
        this.bookMapper = bookMapper;
    }

    @Override
    public int addBook(Books books) {
    
    
        return bookMapper.addBook(books);
    }

    @Override
    public int deleteBookById(int id) {
    
    
        return bookMapper.deleteBookById(id);
    }

    @Override
    public int updateBook(Books books) {
    
    
        return bookMapper.updateBook(books);
    }

    @Override
    public Books queryBookById(int id) {
    
    
        return bookMapper.queryBookById(id);
    }

    @Override
    public List<Books> queryAllBook() {
    
    
        return bookMapper.queryAllBook();
    }
}

6.6. Spring layer

spring-dao.xml
configures this morning and afternoon to the previous applicationContext.xmlcontext

<?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">
    
    <!-- 配置整合mybatis -->
    <!-- 1.关联数据库文件 -->
    <context:property-placeholder location="classpath:database.properties"/>
    
    <!-- 2.数据库连接池 -->
    <!--数据库连接池
        dbcp 半自动化操作 不能自动连接
        c3p0 自动化操作(自动的加载配置文件 并且设置到对象里面)
    -->
    <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"/>
        <!-- 配置MyBaties全局配置文件:mybatis-config.xml -->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>
    
    <!-- 4.配置扫描Dao接口包,动态实现Dao接口注入到spring容器中 -->
    <!--解释 :https://www.cnblogs.com/jpfss/p/7799806.html-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 注入sqlSessionFactory -->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!-- 给出需要扫描Dao接口包 -->
        <property name="basePackage" value="com.kuang.dao"/>
    </bean>

</beans>

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: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">
    
    <!-- 1. 扫描service相关的bean -->
    <context:component-scan base-package="com.kuang.service" />
    
    <!--2. BookServiceImpl注入到IOC容器中-->
    <bean id="BookServiceImpl" class="com.kuang.service.BookServiceImpl">
        <property name="bookMapper" ref="bookMapper"/>
    </bean>
    
    <!-- 3. 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 注入数据库连接池 -->
        <property name="dataSource" ref="dataSource" />
    </bean>

</beans>

If the configured context is not automatically integrated, you can manually import it.

<?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="classpath:spring-dao.xml"/>
    <import resource="classpath:spring-service.xml"/>
    <import resource="classpath:spring-mvc.xml"/>
</beans>

6.7, SpringMVC layer

Add web framework support!
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">

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

  <!--乱码过滤 encodingFilter-->
  <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: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.开启SpringMVC注解驱动 -->
  <mvc:annotation-driven />
  <!-- 2.静态资源默认servlet配置-->
  <mvc:default-servlet-handler/>

  <!-- 3.配置jsp 显示ViewResolver视图解析器 -->
  <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
    <property name="prefix" value="/WEB-INF/jsp/" />
    <property name="suffix" value=".jsp" />
  </bean>

  <!-- 4.扫描web相关的bean -->
  <context:component-scan base-package="com.kuang.controller" />

</beans>

BookController

package com.kuang.controller;

import com.kuang.pojo.Books;
import com.kuang.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 {
    
    

    @Autowired
    @Qualifier("BookServiceImpl")
    private BookService bookService;

    @RequestMapping("/allBook")
    public String list(Model model) {
    
    
        List<Books> list = bookService.queryAllBook();
        model.addAttribute("list", list);
        return "allBook";
    }
}

allBook.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
  <html>
    <head>
      <title>书籍展示</title>
    </head>
    <body>
      <h1>书籍展示</h1>
    </body>
  </html>

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
  <title>首页</title>
</head>
<body>

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

</body>
</html>

Troubleshooting ideas

Problem: Unable to start, artifact ssmbuild:war exploded: An error occurred while deploying the artifact. See the server logs for details.

Create lib under wen-inf and add maven static resources
image.png

Problem: bean does not exist (500)

Steps:
1. Check whether the bean injection is successful!
2. Junit unit test to see if our code can query the results!

import com.kuang.pojo.Books;
import com.kuang.service.BookService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
    
    
    @Test
    public void test(){
    
    
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        BookService bookServiceImpl = (BookService) context.getBean("BookServiceImpl");

        for (Books books:bookServiceImpl.queryAllBook()){
    
    
            System.out.println(books);
        }

    }
}

3. The problem must not be with our bottom layer, but something wrong with spring!
4. SpringMVC, our service. layer beans were not called during integration.

  • applicationContext.xml does not inject beans
  • In web.xml, we have also bound the configuration file! Found the problem. We configured Spring-mvc.Xml and there is indeed no service bean in it, so a null pointer is reported.
  • So, in web.xml <param-value>classpath:applicationContext.xml</param-value>instead of<param-value>classpath:spring-mvc.xml</param-value>

6.8. Search books

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
  <html>
    <head>
      <title>首页</title>
      <style>
        a{
      
      
          text-decoration: none;
          color: blue;
          font-size: 18px;
        }
        h3{
      
      
          width: 180px;
          height: 38px;
          margin: 100px auto;
          text-align: center;
          line-height: 38px;
          background: deepskyblue;
          border-radius: 5px;
        }
      </style>

    </head>
    <body>

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

    </body>
  </html>

To find BootStrap CDN, search

<!-- 新 Bootstrap 核心 CSS 文件 -->

<link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">

<!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->

<script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>

<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->

<script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>

allbook.jsp

  • First import <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> and put the first line
<%@ 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 核心 CSS 文件 -->

        <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">

        <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->

        <script src="https://cdn.staticfile.org/jquery/2.1.1/jquery.min.js"></script>

        <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->

        <script src="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
      </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>
                    <th>操作</th>
                  </tr>
                </thead>

                <%-- 书籍从数据库中查询出来,从这个List中遍历出来:foreach --%>
                  <tbody>
                    <%--                <c:forEach var="book" items="${requestScope.get('list')}">--%>
                      <c:forEach var="book" items="${requestScope.get('list')}">
                        <tr>
                          <td>${book.getBookID()}</td>
                          <td>${book.getBookName()}</td>
                          <td>${book.getBookCounts()}</td>
                          <td>${book.getDetail()}</td>
                        </tr>
                      </c:forEach>
                    </tbody>
                    </table>
                    </div>
                    </div>


                    </div>



                    </body>
                    </html>

image.png

6.9. Add books

allBook.jsp

<div class="row">
  <div class="col-md-4 column">
    <a class="btn btn-primary" href="${pageContext.request.contextPath}/book/toAddBook">新增书籍</a>
  </div>
</div>

BookController.java

// 跳转到增加书籍页面
@RequestMapping("/toAddBook")
    public String toAddPaper(){
    
    
    return "addBook";
}

// 添加书籍
@RequestMapping("/addBook")
public String addBook(Books books){
    
    
    System.out.println("addBook=>"+books);
    bookService.addBook(books);
    return "redirect:/book/allBook";
}

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>

result
image.png
image.png

6.10. Modify books

allBook.jsp

<tbody>
  <c:forEach var="book" items="${requestScope.get('list')}">
    <tr>
      <td>${book.getBookID()}</td>
      <td>${book.getBookName()}</td>
      <td>${book.getBookCounts()}</td>
      <td>${book.getDetail()}</td>
      <td>
        <a href="${pageContext.request.contextPath}/book/toUpdateBook?id=${book.getBookID()}">修改</a> |

      </td>
    </tr>
  </c:forEach>
</tbody>

BookController.java

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

updateBook.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>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- 引入 Bootstrap -->
    <link href="https://cdn.bootcss.com/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/" method="post">
        <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>
        <%--        <input type="submit" value="提交"/>--%>
    </form>

</div>

result
image.png

BookController

@RequestMapping("/updateBook")
public String updateBook( Books books) {
    
    
    System.out.println("updateBook=>"+books);
    bookService.updateBook(books);
    return "redirect:/book/allBook";
}

BookServiceImpl

@Override
    public int updateBook(Books books) {
    
    
        System.out.println("BookServiceImpl:updateBook=>"+books);
return bookMapper.updateBook(books);
}

Import jar package

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.4</version>
</dependency>

Add transaction
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: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
  http://www.springframework.org/schema/aop/spring-aop.xsd
  http://www.springframework.org/schema/tx
  http://www.springframework.org/schema/tx/spring-tx.xsd">

  <!-- 扫描service相关的bean -->
  <context:component-scan base-package="com.kuang.service" />

  <!--BookServiceImpl注入到IOC容器中-->
  <bean id="BookServiceImpl" class="com.kuang.service.BookServiceImpl">
    <property name="bookMapper" ref="bookMapper"/>
  </bean>

  <!-- 配置事务管理器 -->
  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <!-- 注入数据库连接池 -->
    <property name="dataSource" ref="dataSource" />
  </bean>

  <!--  结合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.dao.*.*(..))"/>
    <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
  </aop:config>

</beans>

lib package import
updateBook.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>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <!-- 引入 Bootstrap -->
        <link href="https://cdn.bootcss.com/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>

          <%--  出现的问题:我们提交了修改的SQ请求,但是修改失败,初次考虑,是事务问题,配置完华事务,依旧失败!--%>
            <%-- 看一下SQL语句,能否执行成功:SQL执行失败,修政未完成-%>  &ndash;%&gt;--%>
              <form action="${pageContext.request.contextPath}/book/updateBook" method="post">
                <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>
                <%--        <input type="submit" value="提交"/>--%>
              </form>

            </div>

Manually add log
mybatis-config.xml
image.png

6.11. Delete books

//删除书籍
@RequestMapping("/deleteBook")
    public String deleteBook(int id){
    
    
    bookService.deleteBookById(id);
    return "redirect:/book/allBook";
}

allBook.jsp

<td>
  <a href="${pageContext.request.contextPath}/book/toUpdateBook?id=${book.getBookID()}">修改</a> |
  <a href="${pageContext.request.contextPath}/book/del/${book.getBookID()}">删除</a>
</td>

6.12. Search books

BookMapper

Books queryBookByName(String bookName);

BookMapper.xml

<select id="queryBookByName" resultType="Books">
  select * from ssmbuild.books where bookName = #{bookName}
</select>

BookService

Books queryBookByName(String bookName);

BookServiceImpl

@Override
public Books queryBookByName(String bookName) {
    
    
    return bookMapper.queryBookByName(bookName);
}

BookController

//查询书籍
@RequestMapping("/queryBook")
public String queryBook(String queryBookName,Model model){
    
    
    Books books = bookService.queryBookByName(queryBookName);
    System.err.println("books=>"+books);
    List<Books> list = new ArrayList<Books>();
    list.add(books);
    model.addAttribute("list",list);
    return "allBook";
}

addBook.jsp

<div class="row">
  <div class="col-md-4 column">
    <a class="btn btn-primary" href="${pageContext.request.contextPath}/book/toAddBook">新增书籍</a>
  </div>
  <div class="col-md-4 column">
    <%-- 查询书籍--%>
      <form action="${pageContext.request.contextPath}/book/queryBook" method="post" style="float: right">
        <input type="text" name="queryBookName" class="form-control" placeholder="请输入要查询书籍的名称">
        <input type="submit" value="查询" class="btn btn-primary">
      </form>
  </div>
</div>

Result:
image.png
500 error reported, dao.BookMapper.xml cannot be found
, plus maven resource filtering

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

6.13. Show all books

allBook.jsp

<div class="row">
  <div class="col-md-4 column">
    <a class="btn btn-primary" href="${pageContext.request.contextPath}/book/toAddBook">新增书籍</a>
    <a class="btn btn-primary" href="${pageContext.request.contextPath}/book/allBook">显示全部书籍</a>
  </div>
  <div class="col-md-8 column">
    <%-- 查询书籍--%>
      <form class="form-inline" action="${pageContext.request.contextPath}/book/queryBook" method="post" style="float: right">
        <span style="color:red; font-weight: bold">${error}</span>
        <input type="text" name="queryBookName" class="form-control" placeholder="请输入要查询书籍的名称">
        <input type="submit" value="查询" class="btn btn-primary">
      </form>
  </div>
</div>

BookController

//查询书籍
@RequestMapping("/queryBook")
public String queryBook(String queryBookName,Model model){
    
    
    Books books = bookService.queryBookByName(queryBookName);
    System.err.println("books=>"+books);
    List<Books> list = new ArrayList<Books>();
    list.add(books);

    if (books == null){
    
    
        list = bookService.queryAllBook();
        model.addAttribute("error","未查到");
    }

    model.addAttribute("list",list);
    return "allBook";
}

result
image.png

7. Ajax Research

moduleweb.xml
image.png
_

<?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:applicationContext.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>

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.blue.controller"/>
  <!-- 静态资源过滤 -->
  <mvc:default-servlet-handler />
  <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>

  <!--    <bean name="/t1" class="com.blue.controller.ControllerTest1"/>-->

</beans>

AjaxController

package com.blue.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class AjaxController {
    
    
    @RequestMapping("/t1")
    public String test(){
    
    
        return "hello";
    }
}

Result:
image.png
There is no refresh effect on the page
image.png
test.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <title>iframe测试体验页面无刷新</title>

    <script>
      function go(){
      
      
        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.bilibili.com/">
        <input type="button" value="提交" onclick="go()">
      </p>
    </div>

    <div>
      <iframe id="iframe1" style="width: 100%;height: 500px"></iframe>
    </div>

  </body>
</html>

image.png
Because I didn't use it, the blogger didn't finish reading it. I'm sorry (.・_・.)ノI'm sorry~

8. Interceptor

8.1. True and false of interceptors

Module
image.png
copy
image.png
main.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
  <html>
    <head>
      <title>Title</title>
    </head>
    <body>
      <h1>首页</h1>
    </body>
  </html>

login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
  <html>
    <head>
      <title>Title</title>
    </head>
    <body>
      <h1>登录页面</h1>
      <form action="${pageContext.request.contextPath}/user/login" method="post">
        用户名:<input type="text" name="username"/>

        密码:<input type="text" name="password"/>
        <input type="submit" value="提交">
      </form>
    </body>
  </html>

TestController

package com.blue.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
    
    

    @GetMapping("/t1")
    public String test(){
    
    
        System.out.println("TestController==> test()执行了");
        return "OK";
    }
}

HandlerInterceptor

package com.blue.config;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

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

public class MyInterceptor implements HandlerInterceptor {
    
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        System.out.println("================处理前===============");
        return true;
        //        return HandlerInterceptor.super.preHandle(request, response, handler);
    }


    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    
    
        System.out.println("================处理后===============");
        //        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    
    
        System.out.println("================清理===============");
        //        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }
}

applicationContext.xml

<!--拦截器配置-->
<mvc:interceptors>
  <mvc:interceptor>
    <mvc:mapping path="/**"/>
    <bean class="com.blue.config.MyInterceptor"/>
  </mvc:interceptor>
</mvc:interceptors>

Result:image.png
interceptor is false

public class MyInterceptor implements HandlerInterceptor {
    
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        System.out.println("================处理前===============");
        return false;
        //        return HandlerInterceptor.super.preHandle(request, response, handler);
    }
}

result
image.png
image.png

Home page----Login page,

LoginController

package com.blue.controller;


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

import javax.servlet.http.HttpSession;

@Controller
@RequestMapping("/user")
public class LoginController {
    
    
    //跳转到登陆页面
    @RequestMapping("/jumplogin")
    public String jumpLogin() throws Exception {
    
    
        return "login";
    }

    //跳转到成功页面
    @RequestMapping("/jumpSuccess")
    public String jumpSuccess() throws Exception {
    
    
        return "success";
    }

    //登陆提交
    @RequestMapping("/login")
    public String login(HttpSession session, String username, String pwd) throws Exception {
    
    
        // 向session记录用户身份信息
        System.out.println("接收前端==="+username);
        session.setAttribute("user", username);
        return "success";
    }

    //退出登陆
    @RequestMapping("logout")
    public String logout(HttpSession session) throws Exception {
    
    
        // session 过期
        session.invalidate();
        return "login";
    }
}

index.jsp

<%--
  Created by IntelliJ IDEA.
  User: dlmu
  Date: 2022/4/23
  Time: 9:59
  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>
        <h1><a href="${pageContext.request.contextPath}/goLogin"></a></h1>
        <h1><a href="${pageContext.request.contextPath}/main"></a></h1>
      </body>
    </html>

Interceptor

LoginInterceptor

package com.blue.config;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class LoginInterceptor implements HandlerInterceptor {
    
    
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
    
    
        // 如果是登陆页面则放行
        //        System.out.println("uri: " + request.getRequestURI());
        if (request.getRequestURI().contains("goLogin")) {
    
    
            return true;
        }

        HttpSession session = request.getSession();

        // 如果用户已登陆也放行
        if(session.getAttribute("user") != null) {
    
    
            return true;
        }

        // 用户没有登陆跳转到登陆页面
        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
        return false;
    }

    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
    
    

    }

    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
    
    

    }
}

applicationContext.xml

<!--拦截器配置-->
<mvc:interceptors>
  <mvc:interceptor>
    <mvc:mapping path="/**"/>
    <bean class="com.blue.config.MyInterceptor"/>
  </mvc:interceptor>
  <mvc:interceptor>
    <mvc:mapping path="/**"/>
    <bean class="com.blue.config.LoginInterceptor"/>
  </mvc:interceptor>
</mvc:interceptors>

Login page login

LoginInterceptor

package com.blue.config;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class LoginInterceptor implements HandlerInterceptor {
    
    
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
    
    
        // 如果是登陆页面则放行
        if (request.getRequestURI().contains("goLogin")) {
    
    
            return true;
        }
        if (request.getRequestURI().contains("login")) {
    
    
            return true;
        }

        HttpSession session = request.getSession();

        // 如果用户已登陆也放行 第一次登录,也是没有session的:
        if(session.getAttribute("userLoginInfo") != null) {
    
    
            return true;
        }

        // 用户没有登陆跳转到登陆页面
        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
        return false;
    }

LoginController

package com.blue.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 pwd, Model model){
    
    
        // 向session记录用户身份信息
        System.out.println("接收前端login==="+username);
        session.setAttribute("userLoginInfo", username);
        model.addAttribute("username",username);
        return "main";
    }

    //退出登陆
    @RequestMapping("/goOut")
    public String logout(HttpSession session){
    
    
        // session 过期
        //        session.invalidate();
        session.removeAttribute("userLoginInfo");
        return "main";

    }
}                                                                                                                             43

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>

image.png
image.png

Guess you like

Origin blog.csdn.net/qq_53517370/article/details/128875779