Maven创建子项目卡住 这个问题是镜像没配置好的原因 参考JavaWeb的解决方法
MVC架构 什么是MVC架构?MVC是Model、View、Controller 的缩写,他们三者的意思分别为:
Model(模型):程序员需要操纵的数据以及信息,也就是数据库 
View(视图):提供用户前端展示界面,是程序的外壳 
Controller(控制器):他负责根据用户从视图层输入的指令,选取数据层中的数据,然后进行对应的操作,最终产生结果 
 
所以顺序分别是View->Controller->Model,由外到里。在SpringMVC中这三者分别就对应Servlet,JSP,JavaBean
Servlet回顾 JavaWeb中我们学习了Servlet的使用,在这里就做一个页面跳转的小Demo来回顾复习一下,顺便学习一下EL和JSTL表达式
由一个Servlet说起 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 package  com.boogipop.servlet;import  javax.servlet.ServletException;import  javax.servlet.http.HttpServlet;import  javax.servlet.http.HttpServletRequest;import  javax.servlet.http.HttpServletResponse;import  java.io.IOException;public  class  TestServlet  extends  HttpServlet  {    @Override      protected  void  doGet (HttpServletRequest req, HttpServletResponse resp)  throws  ServletException, IOException {         String  method  =  req.getParameter("method" );         if (method.equals("add" )){             System.out.println("add" );             req.getSession().setAttribute("msg" ,"执行了add方法" );         }         if (method.equals("delete" )){             System.out.println("delete" );             req.getSession().setAttribute("msg" ,"执行了delete方法" );         }         req.getRequestDispatcher("/jsp/test.jsp" ).forward(req,resp);     }     @Override      protected  void  doPost (HttpServletRequest req, HttpServletResponse resp)  throws  ServletException, IOException {         super .doPost(req, resp);     } } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <!DOCTYPE web-app  PUBLIC   "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"   "http://java.sun.com/dtd/web-app_2_3.dtd"  > <web-app >   <display-name > Archetype Created Web Application</display-name >    <servlet >      <servlet-name > hello</servlet-name >      <servlet-class > com.boogipop.servlet.TestServlet</servlet-class >    </servlet >    <servlet-mapping >      <servlet-name > hello</servlet-name >      <url-pattern > /hello</url-pattern >    </servlet-mapping >  </web-app > 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 <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/maven-v4_0_0.xsd" >   <modelVersion > 4.0.0</modelVersion >    <groupId > org.example</groupId >    <artifactId > SpringMVC</artifactId >    <packaging > pom</packaging >    <version > 1.0-SNAPSHOT</version >    <modules >      <module > springmvc-01</module >      <module > spring-02</module >    </modules >    <name > SpringMVC Maven Webapp</name >    <url > http://maven.apache.org</url >    <dependencies >      <dependency >        <groupId > junit</groupId >        <artifactId > junit</artifactId >        <version > 3.8.1</version >        <scope > test</scope >      </dependency >      <dependency >        <groupId > javax.servlet</groupId >        <artifactId > javax.servlet-api</artifactId >        <version > 4.0.1</version >      </dependency >           <dependency >        <groupId > javax.servlet.jsp</groupId >        <artifactId > javax.servlet.jsp-api</artifactId >        <version > 2.3.3</version >      </dependency >      <dependency >        <groupId > javax.servlet</groupId >        <artifactId > jstl</artifactId >        <version > 1.2  </version >      </dependency >      <dependency >        <groupId > taglibs</groupId >        <artifactId > standard</artifactId >        <version > 1.1.2</version >      </dependency >    </dependencies >    <build >      <finalName > SpringMVC</finalName >      <plugins >        <plugin >          <groupId > org.apache.maven.plugins</groupId >          <artifactId > maven-compiler-plugin</artifactId >          <version > 3.10.1</version >          <configuration >            <source > 1.8</source >            <target > 1.8</target >          </configuration >        </plugin >      </plugins >    </build >  </project > 
 
1 2 3 4 5 6 7 8 9 10 11 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page isELIgnored="false" %> <html > <head >     <title > Title</title >  </head > <body > ${msg} </body > </html > 
 
源码如上已经给出,我们访问路由hello并且传参method会出现下面2种情况: 在这里首先利用到Servlet去对请求做处理和转发,然后在jsp中我们用el表达式获取了msg这个变量,在这里就先讲一下el表达式
EL表达式 EL 全名为Expression Language。EL主要作用:
获取数据 
执行运算 
获取web开发常用对象 
调用java方法 
 
 
使用EL的语法${....} EL表达式语句在执行时,会调用pageContext.findAttribute方法,用标识符为关键字,分别从page、request、session、application四个域中查找相应的对象,找到则返回相应对象,找不到则返回”” (注意,不是null,而是空字符串)。 其中关于四个作用域的说法:
pageContext中最重要的方法:findAttribute方法, 使用pageContext.findAttribute方法能从 四个域(page, request, session, context)中寻找存储的数据, 查找的顺序也是从小到大(page—>request—>session—>context), 只要在某个域中能查到相对应的键值对,就返回, 如果四个域都没有则返回null。 这个方式对于EL表达式是最重要的, 例如JSP页面中有一个EL表达式: ${data} 最终在Servlet中就会被翻译成 pageContext.findAttribute(“data”)。
 
查找顺序是从小到大,在上述我们的Demo中,往session中设置了一个熟悉,然后通过el表达式取出来了,也可以使用如下方法获取各个域中的属性
例子就全部看博客吧
注意事项 EL表达式是JSP 2.0规范中的一门技术 。因此,若想正确解析EL表达式,需使用支持Servlet2.4/JSP2.0技术的WEB服务器。 注意:有些Tomcat服务器如不能使用EL表达式     (1)升级成tomcat6     (2)在JSP中加入<%@ page isELIgnored=”false” %>
JSTL表达式 跟着菜鸟教程看吧,看了一圈发现八九不离十
遇到的问题 首先就是EL表达式默认关闭这件事情,其次是Maven设置java语言版本好像有点他妈的bug 解决方法就是在pom中加入:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20     <properties >          <maven.compiler.source > 1.8</maven.compiler.source >          <maven.compiler.target > 1.8</maven.compiler.target >      </properties >      <build >          <plugins >              <plugin >                  <groupId > org.apache.maven.plugins</groupId >                  <artifactId > maven-compiler-plugin</artifactId >                  <version > 3.6.0</version >                  <configuration >                      <source > 1.8</source >                      <target > 1.8</target >                  </configuration >              </plugin >          </plugins >      </build >  
 
第一个SpringMVC程序 这里我的环境是:tomcat10、jdk19 首先引入一下springmvc的依赖包:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 <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/maven-v4_0_0.xsd" >   <modelVersion > 4.0.0</modelVersion >    <groupId > org.example</groupId >    <artifactId > SpringMVC</artifactId >    <packaging > pom</packaging >    <version > 1.0-SNAPSHOT</version >    <modules >      <module > springmvc-01</module >      <module > spring-02</module >    </modules >    <name > SpringMVC Maven Webapp</name >    <url > http://maven.apache.org</url >    <dependencies >      <dependency >        <groupId > junit</groupId >        <artifactId > junit</artifactId >        <version > 3.8.1</version >      </dependency >      <dependency >        <groupId > jakarta.servlet</groupId >        <artifactId > jakarta.servlet-api</artifactId >        <version > 6.0.0</version >      </dependency >      <dependency >        <groupId > jakarta.servlet.jsp</groupId >        <artifactId > jakarta.servlet.jsp-api</artifactId >        <version > 3.1.0</version >      </dependency >      <dependency >        <groupId > org.glassfish.web</groupId >        <artifactId > jakarta.servlet.jsp.jstl</artifactId >        <version > 2.0.0</version >      </dependency >      <dependency >        <groupId > taglibs</groupId >        <artifactId > standard</artifactId >        <version > 1.1.2</version >      </dependency >      <dependency >        <groupId > org.springframework</groupId >        <artifactId > spring-webmvc</artifactId >        <version > 6.0.4</version >      </dependency >    </dependencies >    <build >      <finalName > SpringMVC</finalName >    </build >    <properties >      <maven.compiler.source > 1.8</maven.compiler.source >      <maven.compiler.target > 1.8</maven.compiler.target >    </properties >  </project > 
 
这里的spring-webmvc已经包含了spring里所有的内容,很方便,接下来就是创建我们的demo了: 首先需要配置web.xml文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <!DOCTYPE web-app  PUBLIC   "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"   "http://java.sun.com/dtd/web-app_2_3.dtd"  > <web-app >   <display-name > Archetype Created Web Application</display-name >    <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 > 
 
然后需要配置springmvc配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?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" />      <bean  class ="org.springframework.web.servlet.view.InternalResourceViewResolver"  id ="internalResourceViewResolver" >          <property  name ="prefix"  value ="/jsp/" />          <property  name ="suffix"  value =".jsp" />      </bean >      <bean  id ="/hello"  class ="com.boogipop.controller.TestController" />  </beans > 
 
其次准备一个Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package  com.boogipop.controller;import  jakarta.servlet.http.HttpServletRequest;import  jakarta.servlet.http.HttpServletResponse;import  org.springframework.web.servlet.ModelAndView;import  org.springframework.web.servlet.mvc.Controller;public  class  TestController  implements  Controller  {    @Override      public  ModelAndView handleRequest (HttpServletRequest request, HttpServletResponse response)  throws  Exception {         ModelAndView mv=new  ModelAndView ();         mv.addObject("msg" ,"HelloSpringMVC" );         mv.setViewName("test" );          return  mv;     } } 
 
最后就是需要跳转的jsp页面
1 2 3 4 5 6 7 8 9 10 <%@ page contentType="text/html;charset=UTF-8"  language="java"  %> <%@ page isELIgnored="false"  %> <html> <head>     <title>Title</title> </head> <body> ${msg} </body> </html> 
 
最后当我们访问/hello路由的时候dispatcherservlet就会帮我们实现跳转,到达/jsp/test.jsp,但是url不会发生改变,这就和上面Servlet的例子一样 这就是一个简单的小案例
简单分析 在这/hello路由我们并没有在web.xml中设置,而是在spring的配置文件中注册了一个bean,当我们访问一个路由时,首先经过的就是dispatcherservlet,然后经过它转交到test.jsp,这一点对应spring配置文件中的:
1 2 3 4 5 6 7 8 9 10 11 	     <bean  class ="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />      <bean  class ="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />      <bean  class ="org.springframework.web.servlet.view.InternalResourceViewResolver"  id ="internalResourceViewResolver" >          <property  name ="prefix"  value ="/jsp/" />          <property  name ="suffix"  value =".jsp" />      </bean >  
 
引入了处理映射器和处理适配器以及视图解析器,然后指定了前缀和后缀,这里指定的也就是view跳转的界面: DispacherServlet就是在Web.xml中注册的唯一servlet,在SpringMVC中,任何路由都经过它的处理进行跳转,相当于一个中央控制器,我们跟进它的源码可以发现,它实际上就是HttpServlet的一个封装:
错误排查 https://www.cnblogs.com/wh521/p/16607474.html https://www.cnblogs.com/ZhaiTangGuo/p/15987830.html  在这过程中也是遇到了很多狗血的错误,其中之一就是我们用的是SpringMVC6.0,因此jdk的版本和tomcat的版本也应该随之变化,在这里我们应该使用tomcat10,jdk也应该为高版本(1.8是不行的),假如tomcat低于10会web.xml会出现org.springframework.web.servlet.DispatcherServlet' is not assignable to 'javax.servlet.Servlet,jakarta.servlet.Servlet报错,这时候需要手动导入tomcat的依赖 除了这些以外在tomcat10中,pom依赖也随之改变了,主要体现在servlet和jsp上,tomcat10以下我们引入的是javax.servlet而在10我们引入jakarta.servlet:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <dependency >      <groupId > jakarta.servlet.jsp</groupId >       <artifactId > jakarta.servlet.jsp-api</artifactId >       <version > 3.1.0</version >     </dependency >    <dependency >       <groupId > org.glassfish.web</groupId >       <artifactId > jakarta.servlet.jsp.jstl</artifactId >       <version > 2.0.0</version >     </dependency >     <dependency >       <groupId > taglibs</groupId >       <artifactId > standard</artifactId >       <version > 1.1.2</version >     </dependency >  
 
这里的tomcat10的依赖太他吗讲究了,老子都要哭了
SpringMVC原理分析 https://blog.csdn.net/yanweihpu/article/details/80366218  虽然这篇文章后半部分貌似有地方错了,但是前半部分还是没问题的 SpringMVC的执行流程如上:
客户端发送请求,到达DispacherServlet,解析请求对应的handler,在这里我们选择的映射器为BeanNameUrlHandlerMapping看名字就知道这是根据bean的id来设置对应的路由,比如我们第一个程序中的/hello 
解析到对应的handler后,开始由HandlerAdapter适配器来处理 
HanlderAdapter会根据Handler来处理对应的请求,并处理相关业务逻辑 
处理器处理完业务后,返回一个ModelAndView对象,Model是返回的数据对象,View是视图 
ViewResolver会根据逻辑View查找实际的View(jsp/test.jsp) 
DispacherServlet把返回的Model传给View 
通过View返回请求者 
 
使用注解开发SpringMVC 使用注解进行开发就有点像Flask和SpringBoot了,很方便,实在是方便,在这之前又发现了一个问题:https://blog.csdn.net/zhangphil/article/details/127134127  解决方法如上,有效,诶妈的,框架这些弯钩东西bug怎么这么多,草拟吗的 我们先新建一个子Maven项目:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <!DOCTYPE web-app  PUBLIC          "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"          "http://java.sun.com/dtd/web-app_2_3.dtd"  > <web-app >   <display-name > Archetype Created Web Application</display-name >       <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 > 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 <?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" >     <context:component-scan  base-package ="com.boogipop.controller" />      <bean  class ="org.springframework.web.servlet.view.InternalResourceViewResolver"  id ="internalResourceViewResolver" >                   <property  name ="prefix"  value ="/jsp/" />                   <property  name ="suffix"  value =".jsp" />      </bean >  </beans > 
 
在这里我们的Springmvc配置文件只开启了一个包扫描conponent-scan功能,为什么没加上之前的几个适配器和映射器呢? 我们之前加这些其实是为了解释原理,在Spring中会自动为我们装配好的,这是默认装配的东西,因此可以去掉,接下来我们用注解写一个Controllor
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package  com.boogipop.controller;import  jakarta.servlet.http.HttpServletRequest;import  jakarta.servlet.http.HttpServletResponse;import  org.springframework.stereotype.Controller;import  org.springframework.ui.Model;import  org.springframework.web.bind.annotation.RequestMapping;@Controller public  class  ControllerTest  {    @RequestMapping("/hello")      public  String redirect (Model model, HttpServletRequest req, HttpServletResponse resp) {         model.addAttribute("msg" ,"Hello AnnotationSpringMVC!" );         return  "hello" ;     } } 
 
由于配置了扫描包,因此Spring会识别注解,这里@Controller就是之前说的@Component注解,只是在不同的层称呼不同
@Controller 控制器(注入服务) 用于标注控制层,相当于struts中的action层 
@Service 服务(注入dao) 用于标注服务层,主要用来进行业务的逻辑处理 
@Repository(实现dao访问) 用于标注数据访问层,也可以说用于标注数据访问组件,即DAO组件 
@Component (把普通pojo实例化到spring容器中,相当于配置文件中的 ) 
 
同样很好理解,@RequestMapping注解就是用来设置路由的,然后这我们就没有继承Controllor接口了,这里直接传入一个Model对象,这个model就和之前的ModelandView对象一样,效果是相同的 最后还有一点,requestmapping下函数返回值为String时,会进行页面跳转,比如这里就会跳转到/jsp/hello.jsp,和之前说的也是一样的
Controller配置总结 到这里我们一共学了两套方法去配置Controller,第一种就是按照原理去配置xml文件,第二种是用注解方法,这里就直接把两套方法的配置文件拿过来比对一下就行
第一种 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <!DOCTYPE web-app  PUBLIC   "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"   "http://java.sun.com/dtd/web-app_2_3.dtd"  > <web-app >   <display-name > Archetype Created Web Application</display-name >    <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 > 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?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" />      <bean  class ="org.springframework.web.servlet.view.InternalResourceViewResolver"  id ="internalResourceViewResolver" >          <property  name ="prefix"  value ="/jsp/" />          <property  name ="suffix"  value =".jsp" />      </bean >      <bean  id ="/hello"  class ="com.boogipop.controller.TestController" />  </beans > 
 
第二种 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <!DOCTYPE web-app  PUBLIC   "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"   "http://java.sun.com/dtd/web-app_2_3.dtd"  > <web-app >   <display-name > Archetype Created Web Application</display-name >    <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 > 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 <?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" >     <context:component-scan  base-package ="com.boogipop.controller" />      <bean  class ="org.springframework.web.servlet.view.InternalResourceViewResolver"  id ="internalResourceViewResolver" >                   <property  name ="prefix"  value ="/jsp/" />                   <property  name ="suffix"  value =".jsp" />      </bean >  </beans > 
 
RequestMapping 在上面也说了,@RequestMapping注解可以用来设置路由,这个注解是放在方法上面的,但同时也可以放在一个类上: 这时加入我们还想访问到hello.jsp,那我们的路由就得是/test/hello,这种设置方法我个人觉得很鸡肋没啥用,就是加一个路由前缀罢了
RestFul风格讲解 RestFul是一种开发的风格,一种规范,而不是什么配置,基于这个风格可以使开发更简洁,更有层次,更易于实现缓存机制传统请求方式: 
传统请求方式是根据传参和对应的控制器来实现增删改查,而在RestFul风格中,会变为:GET :/users # 查询用户信息列表GET :/users/1001 # 查看某个用户信息POST :/users # 新建用户信息PUT :/users/1001 # 更新用户信息(全部字段)PATCH :/users/1001 # 更新用户信息(部分字段)DELETE :/users/1001 # 删除用户信息 RestFul风格根据请求方式和对应的路由来判断,这样需要的Controllor就会大大减少 配置文件不改名,我们就换一个Controller:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package  com.boogipop.controller;import  com.oracle.wls.shaded.org.apache.xpath.operations.Mod;import  jakarta.servlet.http.HttpServletRequest;import  jakarta.servlet.http.HttpServletResponse;import  org.springframework.stereotype.Controller;import  org.springframework.ui.Model;import  org.springframework.web.bind.annotation.PathVariable;import  org.springframework.web.bind.annotation.RequestMapping;import  java.io.IOException;@Controller public  class  RestFulController  {@RequestMapping("/add/{a}/{b}")     public  void  control (@PathVariable  int  a,@PathVariable  int  b,Model model, HttpServletRequest req, HttpServletResponse resp)  throws  IOException {         resp.getWriter().println("pathvar:" +a+b); } } 
 
我们用到了一个新注解@PathVariable,这个东西和我们再django学的很相似 这样我们就可以简单的体验一下RestFul风格,然后这里再讲一下如何设置我们的请求方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 package  com.boogipop.controller;import  com.oracle.wls.shaded.org.apache.xpath.operations.Mod;import  jakarta.servlet.http.HttpServletRequest;import  jakarta.servlet.http.HttpServletResponse;import  org.springframework.stereotype.Controller;import  org.springframework.ui.Model;import  org.springframework.web.bind.annotation.PathVariable;import  org.springframework.web.bind.annotation.RequestMapping;import  org.springframework.web.bind.annotation.RequestMethod;import  java.io.IOException;@Controller public  class  RestFulController  {@RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.POST)     public  void  control (@PathVariable  int  a,@PathVariable  String b,Model model, HttpServletRequest req, HttpServletResponse resp)  throws  IOException {         resp.getWriter().println("pathvar:" +a+b); } } 
 
这里我修改了一下a,b的类型注意一下,b改为了String,测试一下能否转换类型,并且指定POST请求访问: 用GET访问已经不行了,我们换成POST: 完美解决问题,这里通过method = RequestMethod.POST来指定路由的请求类型 还有一个需要注意点就是这里既然指定了method,那么前面路由也必须加一个value=(name=是不可以的,测试过了,会报错) 这里也要指定路由的名字value或者是path
请求方式Mapping 我们前面通过RequestMethod.POST来指定请求类型,这样未免太复杂了,其实spring给我们准备好了对应的路由,比如POST方式的叫做@PostMapping:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package  com.boogipop.controller;import  com.oracle.wls.shaded.org.apache.xpath.operations.Mod;import  jakarta.servlet.http.HttpServletRequest;import  jakarta.servlet.http.HttpServletResponse;import  org.springframework.stereotype.Controller;import  org.springframework.ui.Model;import  org.springframework.web.bind.annotation.*;import  java.io.IOException;@Controller public  class  RestFulController  {@PostMapping( "/add/{a}/{b}")     public  void  control1 (@PathVariable  int  a,@PathVariable  String b,Model model, HttpServletRequest req, HttpServletResponse resp)  throws  IOException {         resp.getWriter().println("POST pathvar:" +a+b); } @GetMapping( "/add/{a}/{b}")     public  void  control2 (@PathVariable  int  a,@PathVariable  String b,Model model, HttpServletRequest req, HttpServletResponse resp)  throws  IOException {         resp.getWriter().println("Get pathvar:" +a+b);     } } 
 
这里只需要用对应的请求方式加一个Mapping即可: 经过测试成功:
这里就是对RestFul风格的一些简短介绍
重定向和转发 在JavaWeb中我们学习了两种重定向的方法,一种是转发,用的是request.getRequestDispatcher().另一种是重定向,用的是response.sendRedirect(); 二者区别主要体现在URL是否改变,转发是将请求转发到目标界面,把目标界面的回显在当前页面显示,而重定向则是多一次请求,直接跳转到目标界面,前者URL不改变,后者URL改变 在SpringMVC中同样也存在着重定向和转发,他们的关键词分别是redirect:和forward:,我们首先把视图解析器注释掉:
1 2 3 4 5 6 7 8 9 10 11 12 13 <?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" >     <context:component-scan  base-package ="com.boogipop.controller" />                        </bean >  </beans > 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package  com.boogipop.controller;import  jakarta.servlet.http.HttpServletRequest;import  jakarta.servlet.http.HttpServletResponse;import  org.springframework.stereotype.Controller;import  org.springframework.ui.Model;import  org.springframework.web.bind.annotation.RequestMapping;@Controller public  class  RedirectController  {    @RequestMapping("/redirect")      public  String redirect (Model model, HttpServletRequest request, HttpServletResponse response) {         return  "/jsp/redirect.jsp" ;     } } 
 
这种情况下,我们的请求不会经过视图解析器,因此需要手动添加前缀和后缀: 可以看到成功跳转,接着我们把视图解析器取消注释,然后修改Controller为如下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package  com.boogipop.controller;import  jakarta.servlet.http.HttpServletRequest;import  jakarta.servlet.http.HttpServletResponse;import  org.springframework.stereotype.Controller;import  org.springframework.ui.Model;import  org.springframework.web.bind.annotation.RequestMapping;@Controller public  class  RedirectController  {    @RequestMapping("/redirect")      public  String redirect (Model model, HttpServletRequest request, HttpServletResponse response) {         return  "forward:/jsp/redirect.jsp" ;     } } 
 
forward关键字是转发的意思,加了forward关键词后会无视视图解析器,直接转发: 我们再次修改关键词为redirect:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 package  com.boogipop.controller;import  jakarta.servlet.http.HttpServletRequest;import  jakarta.servlet.http.HttpServletResponse;import  org.springframework.stereotype.Controller;import  org.springframework.ui.Model;import  org.springframework.web.bind.annotation.RequestMapping;@Controller public  class  RedirectController  {    @RequestMapping("/redirect")      public  String redirect (Model model, HttpServletRequest request, HttpServletResponse response) {         return  "redirect:/jsp/redirect.jsp" ;     } } 
 
这种情况就是重定向了,URL会变化: 很简单的重定向和转发案例,理解起来轻松~
接收请求和数据回显 接收数据 在JavaWeb中我们是依靠request.getParameter()去获取前台传入的数据,而在SpringMVC中有两种方式,注解和直接获取,我们可以做一个小案例来解释:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package  com.boogipop.controller;import  org.springframework.stereotype.Controller;import  org.springframework.ui.Model;import  org.springframework.web.bind.annotation.RequestMapping;@Controller public  class  RedirectController  {    @RequestMapping("/redirect")      public  String redirect (Model model,String name,int  age) {         System.out.println(name);         System.out.println(age);         return  "redirect" ;     } } 
 
我们传参:[http://localhost:8080/redirect?name=kino&age=15](http://localhost:8080/redirect?name=kino&age=15) 在后台即可获取对应的数据,SpringMVC会帮我们识别参数
另外假如我们URL中传入的参数名称和方法中的形参名称不相同,我们可以通过注解的方法去让他识别:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 package  com.boogipop.controller;import  org.springframework.stereotype.Controller;import  org.springframework.ui.Model;import  org.springframework.web.bind.annotation.RequestMapping;import  org.springframework.web.bind.annotation.RequestParam;@Controller public  class  RedirectController  {    @RequestMapping("/redirect")      public  String redirect (Model model, @RequestParam("username")  String name) {         System.out.println(name);         return  "redirect" ;     } } 
 
这时候我们需要传入一个username后台才能获取参数的值:[http://localhost:8080/redirect?username=testuser](http://localhost:8080/redirect?username=testuser)
那我们可不可以接受一个对象呢?答案是可以的,我们先定义一个pojo类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package  com.boogipop.pojo;public  class  User  {    private  String name;     @Override      public  String toString ()  {         return  "User{"  +                 "name='"  + name + '\''  +                 ", score="  + score +                 ", age="  + age +                 '}' ;     }     private  int  score;     private  int  age; } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package  com.boogipop.controller;import  com.boogipop.pojo.User;import  org.springframework.stereotype.Controller;import  org.springframework.ui.Model;import  org.springframework.web.bind.annotation.RequestMapping;import  org.springframework.web.bind.annotation.RequestParam;@Controller public  class  RedirectController  {    @RequestMapping("/redirect")      public  String redirect (Model model, User user) {         System.out.println(user);         return  "redirect" ;     } } 
 
这个时候我们传参[http://localhost:8080/redirect?name=Boogipop&score=100&age=18](http://localhost:8080/redirect?name=Boogipop&score=100&age=18)会发现: 值完全都没注入进去,这其实和Spring的Bean装配是一个道理,因此我们需要给它加上set和get方法: 加上之后就正常了
数据回显到前端 在Javaweb我们用的是resp.getWriter().Println()去进行回显的,在SpringMVC中有三种,分别是ModelandVIew Model ModelMap 其中ModelandView在一开始我们就知道了其用法:
1 2 3 4 5 6 7 8 9 10 11 12 public  class  TestController  implements  Controller  {    @Override      public  ModelAndView handleRequest (HttpServletRequest request, HttpServletResponse response)  throws  Exception {         ModelAndView mv=new  ModelAndView ();         mv.addObject("msg" ,"HelloSpringMVC" );         mv.setViewName("test" );          return  mv;     } } 
 
而Model的用法我们在上面也用到了,ModelMap和Model的用法师一样的,只不过是继承关系,继承关系为Model->ModelMap->LinkHashMap,Model继承了ModelMap继承了LinkHashMap,用法就不多赘述,和上面一模一样
乱码问题解决 response.getWriter()造成的乱码 在SpringMVC架构中,假如往页面回显中文的时候,可能就会出现乱码的问题,这时候就需要解决乱码问题,可能有的人一开始会认为用requset去设置servlet请求和回显的编码就行,实际上是行不通的,这是因为中央控制器DispacherServlet是SpringMVC设置的,不是一般的servlet,因此我们需要更早拦截,也就是自定义filter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 package  com.boogipop.controller;import  com.boogipop.pojo.User;import  jakarta.servlet.http.HttpServletRequest;import  jakarta.servlet.http.HttpServletResponse;import  org.springframework.stereotype.Controller;import  org.springframework.ui.Model;import  org.springframework.web.bind.annotation.RequestMapping;import  org.springframework.web.bind.annotation.RequestParam;import  java.io.IOException;@Controller public  class  RedirectController  {    @RequestMapping("/redirect")      public  String redirect (Model model, User user) {         System.out.println(user);         return  "redirect" ;     }     @RequestMapping("/chinese")      public  void  encode (String name, HttpServletRequest request , HttpServletResponse response)  throws  IOException {         System.out.println(name);         response.getWriter().println(name);     } } 
 
Controller基本配置如下,我们正常传入一个中文,结果如下: 会出现乱码的问题,解决这个乱码的问题很简单,我们多加入一段代码:
1 2 3 4 request.setCharacterEncoding("UTF-8" ); response.setCharacterEncoding("UTF-8" ); response.setContentType("text/html;charset=UTF-8" ); response.getWriter().println(name); 
 
这样即可解决 但是接受控制台参数就是会乱码,这个改不了啊啊啊啊,等以后看看能不能解决吧呜呜呜
Jsp跳转界面的乱码 我们测试的代码如下:
1 2 3 4 5 @RequestMapping("/chinese2")    public  String coding (Model model,String name) {        model.addAttribute("msg" ,name);        return  "redirect" ;    } 
 
1 2 3 4 5 6 7 8 9 10 11 12 <%@ page contentType="text/html;charset=UTF-8"  language="java"  %> <%@ page isELIgnored="false"  %> <html> <head>     <title>Title</title> </head> <body> <h1>REDIRECT PAGE</h1> ${msg} </body> </html> 
 
有三种配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package  com.boogipop.filters;import  jakarta.servlet.*;import  java.io.IOException;public  class  EncodingFilter  implements  Filter  {    @Override      public  void  init (FilterConfig filterConfig)  throws  ServletException {         Filter.super .init(filterConfig);     }     @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 ()  {         Filter.super .destroy();     } } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 package  com.boogipop.filters;import  jakarta.servlet.*;import  jakarta.servlet.http.HttpServletRequest;import  jakarta.servlet.http.HttpServletRequestWrapper;import  jakarta.servlet.http.HttpServletResponse;import  java.io.IOException;import  java.io.UnsupportedEncodingException;import  java.util.Map;public  class  SpecialFilter  implements  Filter  {    @Override      public  void  init (FilterConfig filterConfig)  throws  ServletException {         Filter.super .init(filterConfig);     }     @Override      public  void  doFilter (ServletRequest request, ServletResponse response, FilterChain filterChain)  throws  IOException, ServletException {                  HttpServletResponse myResponse=(HttpServletResponse) response;         myResponse.setContentType("text/html;charset=UTF-8" );                  HttpServletRequest  httpServletRequest  =  (HttpServletRequest) request;                  HttpServletRequest  myrequest  =  new  MyRequest (httpServletRequest);         filterChain.doFilter(myrequest, response);     }     @Override      public  void  destroy ()  {         Filter.super .destroy();     }          class  MyRequest  extends  HttpServletRequestWrapper  {         private  HttpServletRequest request;                  private  boolean  hasEncode;                  public  MyRequest (HttpServletRequest request)  {             super (request);             this .request = request;         }                  @Override          public  Map getParameterMap ()  {                          String  method  =  request.getMethod();             if  (method.equalsIgnoreCase("post" )) {                                  try  {                                          request.setCharacterEncoding("utf-8" );                     return  request.getParameterMap();                 } catch  (UnsupportedEncodingException e) {                     e.printStackTrace();                 }             } else  if  (method.equalsIgnoreCase("get" )) {                                  Map<String, String[]> parameterMap = request.getParameterMap();                 if  (!hasEncode) {                      for  (String parameterName : parameterMap.keySet()) {                         String[] values = parameterMap.get(parameterName);                         if  (values != null ) {                             for  (int  i  =  0 ; i < values.length; i++) {                                 try  {                                                                          values[i] = new  String (values[i]                                             .getBytes("ISO-8859-1" ), "utf-8" );                                 } catch  (UnsupportedEncodingException e) {                                     e.printStackTrace();                                 }                             }                         }                     }                     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;         }     } } 
 
1 2 3 4 5 6 7 8 9 10 11 12 <filter >   <filter-name > characterEncodingFilter</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 >    <init-param >      <param-name > forceEncoding</param-name >      <param-value > true</param-value >    </init-param >  </filter > 
 
@ResponseBody和return造成的乱码 1 2 3 4 5 @RequestMapping("/chinese3")    @ResponseBody     public  String coding2 (Model model,String name)  throws  UnsupportedEncodingException {        return  "我是好人" ;    } 
 
 我们只需要加上produces = "text/html;charset=UTF-8":
JackJson、FastJson2(推荐FastJson2) 由于他妈的上面的乱码实在是给我带来了许多震撼,真的 首先JSON我反正是已经很熟悉了,我就不介绍了,我脑里还游荡者上一波的中文乱码问题,我草,真的纯畜 先讲一下JackJson吧,首先是依赖包
1 2 3 4 5 6 <dependency >     <groupId > com.fasterxml.jackson.core</groupId >      <artifactId > jackson-databind</artifactId >      <version > 2.14.2</version >  </dependency > 
 
其次之前我们提到过了加上@ResponseBody注解之后,return单纯就是返回一个字符串而已,然后JSON中也同样会出现JSON乱码的问题,有2种解决方法,第一种是在RequestMapping处加东西:@RequestMapping(value = "/json2",produces = "text/html;charset=UTF-8") 第二种则是修改springMvc的配置文件,一劳永逸:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <mvc:annotation-driven >     <mvc:message-converters  register-defaults ="true" >          <bean  class ="org.springframework.http.converter.StringHttpMessageConverter" >              <property  name ="supportedMediaTypes" >                  <list >                      <value > text/html;charset=UTF-8</value >                      <value > application/json;charset=UTF-8</value >                      <value > text/plain;charset=UTF-8</value >                      <value > application/xml;charset=UTF-8</value >                  </list >              </property >          </bean >      </mvc:message-converters >  </mvc:annotation-driven > 
 
这两种都可以解决问题,这里我就选择后者了
RestController 一个小tips,这个注解放在类上就相当于给每个方法都加了Responsebody注解
JackJson用法 用法很简单:
1 2 3 4 5 6 7 8 @ResponseBody     @RequestMapping("/json1")      public  String json1 (Model model,String name)  throws  JsonProcessingException {         ObjectMapper mapper=new  ObjectMapper ();         User user=new  User ("高贝克" ,100 ,18 );         String  s  =  mapper.writeValueAsString(user);         return  s;     } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @ResponseBody     @RequestMapping(value = "/json2")      public  String json2 (Model model,String name)  throws  JsonProcessingException {         ObjectMapper mapper=new  ObjectMapper ();         User user1=new  User ("高贝克" ,100 ,18 );         User user2=new  User ("高贝克1" ,100 ,18 );         User user3=new  User ("高贝克3" ,100 ,18 );         User user4=new  User ("高贝克4" ,100 ,18 );         List<User> list=new  ArrayList <>();         list.add(user1);         list.add(user2);         list.add(user3);         list.add(user4);         String  s  =  mapper.writeValueAsString(list);         return  s;     } 
 
以上两种方法对应的输出结果为: 符合JSON的格式规范,除此之外它还能用来对日期做转换:
1 2 3 4 5 6 @RequestMapping("/json3")     @ResponseBody      public  String data ()  throws  JsonProcessingException {         Date date=new  Date ();         return  new  ObjectMapper ().writeValueAsString(date);     } 
 
正常来说返回值应该是一个时间戳: 这里假如我们想要将其转换为标准格式该怎么做呢,传统做法是用new SimpleDateFormat().format(new Date())来实现的,但是JackJson给了一种方法:
1 2 3 4 5 6 @RequestMapping("/json3")    public  String data ()  throws  JsonProcessingException {        ObjectMapper mapper=new  ObjectMapper ();        mapper.setDateFormat(new  SimpleDateFormat ("yyyy-MM-dd HH:mm:ss" ));        return  mapper.writeValueAsString(new  Date ());    } 
 
 其实我觉得都差不多,根据这个东西我们可以写一个工具类来帮我做转换,如果是普通对象那就直接JSON格式输出,是日期就转换格式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package  com.boogipop.utils;import  com.fasterxml.jackson.core.JsonProcessingException;import  com.fasterxml.jackson.databind.ObjectMapper;import  java.text.SimpleDateFormat;public  class  JsonUtil  {    public  static  String gerjson (Object o)  throws  JsonProcessingException {         return  gerjson(o,"yy-MM-dd HH:mm:ss" );     }     public  static  String gerjson (Object o,String format)  throws  JsonProcessingException {         ObjectMapper mapper=new  ObjectMapper ();         mapper.setDateFormat(new  SimpleDateFormat (format));         return  mapper.writeValueAsString(o);     } } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @RequestMapping("/json3")     public  String data ()  throws  JsonProcessingException {         return  JsonUtil.gerjson(new  Date ());     }     @RequestMapping("/json4")      public  String json4 ()  throws  JsonProcessingException {         User user1=new  User ("高贝克" ,100 ,18 );         User user2=new  User ("高贝克1" ,100 ,18 );         User user3=new  User ("高贝克3" ,100 ,18 );         User user4=new  User ("高贝克4" ,100 ,18 );         List<User> list=new  ArrayList <>();         list.add(user1);         list.add(user2);         list.add(user3);         list.add(user4);         return  JsonUtil.gerjson(list);     } 
 
 输出结果与之对应,工具里面把getjson方法利用达到了最大
FastJson使用(控制台乱码破案) 首先到这里破案了,是Jdk的版本太高,之前用的是19,换成17的之后立马没问题了呜呜呜呜 FastJson使用也很简单:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @RequestMapping("/json5")    public  void  fastjson () {        User user1=new  User ("高贝克" ,100 ,18 );        User user2=new  User ("高贝克1" ,100 ,18 );        User user3=new  User ("高贝克3" ,100 ,18 );        User user4=new  User ("高贝克4" ,100 ,18 );        List<User> list=new  ArrayList <>();        list.add(user1);        list.add(user2);        list.add(user3);        list.add(user4);        System.out.println("Java对象转JSON字符串" );        String str1= JSON.toJSONString(list);        String str2=JSON.toJSONString(user1);        System.out.println(str1);        System.out.println("JSON字符串转Java对象" );        User  user  =  JSON.parseObject(str2, User.class);        System.out.println(user);        System.out.println("java对象转json对象" );        Object  o  =  JSON.toJSON(user);        System.out.println(o);    } 
 
 其实我感觉FastJson更好用,真的,我以后就用FastJson了 
SSM整合:环境搭建 依赖包:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86   <dependencies >      <dependency >        <groupId > junit</groupId >        <artifactId > junit</artifactId >        <version > 3.8.1</version >      </dependency >      <dependency >        <groupId > jakarta.servlet</groupId >        <artifactId > jakarta.servlet-api</artifactId >        <version > 6.0.0</version >      </dependency >      <dependency >        <groupId > jakarta.servlet.jsp</groupId >        <artifactId > jakarta.servlet.jsp-api</artifactId >        <version > 3.1.0</version >      </dependency >      <dependency >        <groupId > org.glassfish.web</groupId >        <artifactId > jakarta.servlet.jsp.jstl</artifactId >        <version > 2.0.0</version >      </dependency >      <dependency >        <groupId > taglibs</groupId >        <artifactId > standard</artifactId >        <version > 1.1.2</version >      </dependency >      <dependency >        <groupId > org.springframework</groupId >        <artifactId > spring-webmvc</artifactId >        <version > 6.0.4</version >      </dependency >      <dependency >        <groupId > com.fasterxml.jackson.core</groupId >        <artifactId > jackson-databind</artifactId >        <version > 2.14.1</version >      </dependency >           <dependency >        <groupId > com.alibaba.fastjson2</groupId >        <artifactId > fastjson2</artifactId >        <version > 2.0.23</version >      </dependency >      <dependency >        <groupId > mysql</groupId >        <artifactId > mysql-connector-java</artifactId >        <version > 8.0.30</version >      </dependency >      <dependency >        <groupId > org.mybatis</groupId >        <artifactId > mybatis</artifactId >        <version > 3.5.6</version >      </dependency >           <dependency >        <groupId > org.springframework</groupId >        <artifactId > spring-jdbc</artifactId >        <version > 6.0.4</version >      </dependency >      <dependency >        <groupId > org.mybatis</groupId >        <artifactId > mybatis-spring</artifactId >        <version > 3.0.1</version >      </dependency >      <dependency >        <groupId > org.aspectj</groupId >        <artifactId > aspectjweaver</artifactId >        <version > 1.9.19</version >      </dependency >           <dependency >        <groupId > com.mchange</groupId >        <artifactId > c3p0</artifactId >        <version > 0.9.5.5</version >      </dependency >    </dependencies >  
 
初始化数据库:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 CREATE  DATABASE ssmbuild;USE ssmbuild; CREATE  TABLE  `books`(`bookID` INT  NOT  NULL  AUTO_INCREMENT COMMENT '书id' , `bookName` VARCHAR (100 ) NOT  NULL  COMMENT '书名' , `bookCounts` INT  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 ,'从进门到进牢' ); 
 
Mybatis层 mybatis层就是pojo类和mapper以及service:
1 2 3 4 5 6 7 8 9 10 11 12 <?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 >     <settings >          <setting  name ="logImpl"  value ="STDOUT_LOGGING" />      </settings >      <typeAliases >          <package  name ="com.boogipop.pojo" />      </typeAliases >  </configuration > 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 package  com.boogipop.pojo;import  org.apache.ibatis.type.Alias;@Alias("Books") public  class  Books  {    private  int  bookID;     private  String bookName;     private  int  bookCounts;     private  String detail;     @Override      public  String toString ()  {         return  "Books{"  +                 "bookID="  + bookID +                 ", bookName='"  + bookName + '\''  +                 ", bookCounts="  + bookCounts +                 ", detail='"  + detail + '\''  +                 '}' ;     }     public  int  getBookID ()  {         return  bookID;     }     public  void  setBookID (int  bookID)  {         this .bookID = bookID;     }     public  String getBookName ()  {         return  bookName;     }     public  void  setBookName (String bookName)  {         this .bookName = bookName;     }     public  int  getBookCounts ()  {         return  bookCounts;     }     public  void  setBookCounts (int  bookCounts)  {         this .bookCounts = bookCounts;     }     public  String getDetail ()  {         return  detail;     }     public  void  setDetail (String detail)  {         this .detail = detail;     }     public  Books (int  bookID, String bookName, int  bookCounts, String detail)  {         this .bookID = bookID;         this .bookName = bookName;         this .bookCounts = bookCounts;         this .detail = detail;     } } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 package  com.boogipop.mapper;import  com.boogipop.pojo.Books;import  java.util.List;import  java.util.Map;public  interface  BooksMapper  {    Boolean AddBook (Books book) ;     Boolean DelBook (int  id) ;     Boolean UpdateBook (Map<Object,Object> map) ;     List<Books> SelectAllBooks () ;     Books SelectBookById (int  id) ; } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <?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.boogipop.mapper.BooksMapper" >     <select  id ="SelectAllBooks"  resultType ="Books" >          select * from books     </select >      <select  id ="SelectBookById"  resultType ="Books"  parameterType ="int" >          select * from books where id=#{id}     </select >      <insert  id ="AddBook"  parameterType ="Books" >          insert into books(bookName,bookCounts,detail) values (#{bookName},#{bookCounts},#{detail})     </insert >      <update  id ="UpdateBook"  parameterType ="map" >          update books set bookName=#{bookname},bookCounts=#{bookcounts},detail=#{detail} where bookID=#{id}     </update >      <delete  id ="DelBook"  parameterType ="int" >          delete from books where bookID=#{id}     </delete >  </mapper > 
 
Spring层 Spring需要做的就是整合mybatis,以及注册bean
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 <?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" >     <context:property-placeholder  location ="db.properties" />      <context:component-scan  base-package ="com.boogipop.mapper" />      <context:component-scan  base-package ="com.boogipop.service" />      <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}" />          <property  name ="maxPoolSize"  value ="30" />          <property  name ="minPoolSize"  value ="10" />          <property  name ="autoCommitOnClose"  value ="false" />          <property  name ="checkoutTimeout"  value ="10000" />          <property  name ="acquireRetryAttempts"  value ="2" />      </bean >           <bean  id ="sqlsessionfactory"  class ="org.mybatis.spring.SqlSessionFactoryBean" >                   <property  name ="dataSource"  ref ="datasource" />          <property  name ="configLocation"  value ="classpath:mybatis-config.xml" />          <property  name ="mapperLocations"  value ="classpath:com/boogipop/mapper/*Mapper.xml" />      </bean >           <bean  class ="org.mybatis.spring.mapper.MapperScannerConfigurer" >                   <property  name ="sqlSessionFactoryBeanName"  value ="sqlsessionfactory" />          <property  name ="basePackage"  value ="com.boogipop.mapper" />      </bean >      <bean  class ="org.springframework.jdbc.datasource.DataSourceTransactionManager"  id ="transactionManager" >                   <property  name ="dataSource"  ref ="datasource" />      </bean >  </beans > 
 
1 2 3 4 jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&seUnicode=true&characterEncoding=UTF-8 jdbc.username=root jdbc.password=jiayou357753 
 
现在可以写个测试类试一下SQL执行是否正常:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 import  com.boogipop.mapper.BooksMapper;import  com.boogipop.pojo.Books;import  org.junit.Test;import  org.springframework.context.support.ClassPathXmlApplicationContext;import  java.util.HashMap;import  java.util.List;import  java.util.Map;public  class  TestSql  {    @Test      public  void  selectall () {         ClassPathXmlApplicationContext  context  =  new  ClassPathXmlApplicationContext ("ApplicationContext.xml" );         BooksMapper  bookMapper  =  context.getBean("booksMapper" , BooksMapper.class);         List<Books> books = bookMapper.SelectAllBooks();         for  (Books book : books) {             System.out.println(book);         }     }     @Test      public  void  add () {         ClassPathXmlApplicationContext  context  =  new  ClassPathXmlApplicationContext ("ApplicationContext.xml" );         BooksMapper  bookMapper  =  context.getBean("booksMapper" , BooksMapper.class);         Books book=new  Books (7 ,"HackerBook" ,100 ,"黑客从0到1" );         if  (bookMapper.AddBook(book)) {             System.out.println("add successfully" );         }     }     @Test      public  void  del () {         ClassPathXmlApplicationContext  context  =  new  ClassPathXmlApplicationContext ("ApplicationContext.xml" );         BooksMapper  bookMapper  =  context.getBean("booksMapper" , BooksMapper.class);         if  (bookMapper.DelBook(4 )) {             System.out.println("del successfully" );         }     }     @Test      public  void  update () {         ClassPathXmlApplicationContext  context  =  new  ClassPathXmlApplicationContext ("ApplicationContext.xml" );         BooksMapper  bookMapper  =  context.getBean("booksMapper" , BooksMapper.class);         Map<Object,Object> map=new  HashMap <>();         map.put("bookname" ,"Web" );         map.put("bookcounts" ,"8" );         map.put("detail" ,"web from boogipop" );         map.put("id" ,5 );         if  (bookMapper.UpdateBook(map)) {             System.out.println("update successfully" );         }     } } 
 
SpringMVC层 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 <!DOCTYPE web-app  PUBLIC   "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"   "http://java.sun.com/dtd/web-app_2_3.dtd"  > <web-app >   <display-name > Archetype Created Web Application</display-name >       <filter >      <filter-name > encoding</filter-name >      <filter-class > org.springframework.web.filter.CharacterEncodingFilter</filter-class >    </filter >    <filter-mapping >      <filter-name > encoding</filter-name >      <url-pattern > /*</url-pattern >    </filter-mapping >    <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 >    </servlet >    <servlet-mapping >      <servlet-name > springmvc</servlet-name >      <url-pattern > /</url-pattern >    </servlet-mapping >    <session-config >      <session-timeout > 15</session-timeout >    </session-config >  </web-app > 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 <?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" >     <context:property-placeholder  location ="db.properties" />      <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}" />          <property  name ="maxPoolSize"  value ="30" />          <property  name ="minPoolSize"  value ="10" />          <property  name ="autoCommitOnClose"  value ="false" />          <property  name ="checkoutTimeout"  value ="10000" />          <property  name ="acquireRetryAttempts"  value ="2" />      </bean >           <bean  id ="sqlsessionfactory"  class ="org.mybatis.spring.SqlSessionFactoryBean" >                   <property  name ="dataSource"  ref ="datasource" />          <property  name ="configLocation"  value ="classpath:mybatis-config.xml" />          <property  name ="mapperLocations"  value ="classpath:com/boogipop/mapper/*Mapper.xml" />      </bean >           <bean  class ="org.mybatis.spring.mapper.MapperScannerConfigurer" >                   <property  name ="sqlSessionFactoryBeanName"  value ="sqlsessionfactory" />          <property  name ="basePackage"  value ="com.boogipop.mapper" />      </bean >      <bean  class ="org.springframework.jdbc.datasource.DataSourceTransactionManager"  id ="transactionManager" >                   <property  name ="dataSource"  ref ="datasource" />      </bean >  </beans > 
 
1 2 3 4 5 6 7 <?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" >     <context:component-scan  base-package ="com.boogipop.mapper" />  </beans > 
 
1 2 3 4 5 6 7 <?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" >     <context:component-scan  base-package ="com.boogipop.service" />  </beans > 
 
将之后我们需要注入的实现类impl注册,并且整合进springmvc-servlet文件中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package  com.boogipop.service;import  com.boogipop.pojo.Books;import  java.util.List;import  java.util.Map;public  interface  BookService  {                 Boolean AddBook (Books book) ;                  Boolean DelBook (int  id) ;                  Boolean UpdateBook (Map<Object,Object> map) ;                  List<Books> SelectAllBooks () ;                  Books SelectBookById (int  id) ; } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 package  com.boogipop.service;import  com.boogipop.mapper.BooksMapper;import  com.boogipop.pojo.Books;import  org.springframework.beans.factory.annotation.Autowired;import  org.springframework.stereotype.Component;import  java.util.List;import  java.util.Map;@Component public  class  BookServiceImpl  implements  BookService {    @Autowired      private  BooksMapper booksMapper;     @Override      public  Boolean AddBook (Books book)  {         return  booksMapper.AddBook(book);     }     @Override      public  Boolean DelBook (int  id)  {         return  booksMapper.DelBook(id);     }     @Override      public  Boolean UpdateBook (Map<Object, Object> map)  {         return  booksMapper.UpdateBook(map);     }     @Override      public  List<Books> SelectAllBooks ()  {         return  booksMapper.SelectAllBooks();     }     @Override      public  Books SelectBookById (int  id)  {         return  booksMapper.SelectBookById(id);     } } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <?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/context           https://www.springframework.org/schema/context/spring-context.xsd            http://www.springframework.org/schema/mvc             http://www.springframework.org/schema/mvc/spring-mvc.xsd" >    <import  resource ="ApplicationContext.xml" />      <import  resource ="mapperbean.xml" />      <import  resource ="servicebean.xml" />  <context:component-scan  base-package ="com.boogipop.controller" />     <mvc:default-servlet-handler />      <mvc:annotation-driven />      <bean  class ="org.springframework.web.servlet.view.InternalResourceViewResolver"  id ="internalResourceViewResolver" >                   <property  name ="prefix"  value ="/jsp/" />                   <property  name ="suffix"  value =".jsp" />      </bean >  </beans > 
 
到此树状图为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 SSM   ├─src     └─main         ├─java         │  └─com         │      └─boogipop         │          ├─controller         │          ├─mapper         │          ├─pojo         │          ├─service         │          └─utils         ├─resources         ├─test         └─webapp             ├─jsp             └─WEB-INF 
 
SSM整合:查询书籍功能 坑点注意 首先是开启了静态资源过滤时,回导致默认的注解驱动失效,导致无法扫描到controller造成404,因此正确的配置应该改为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <?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/context           https://www.springframework.org/schema/context/spring-context.xsd            http://www.springframework.org/schema/mvc             http://www.springframework.org/schema/mvc/spring-mvc.xsd" >    <import  resource ="ApplicationContext.xml" />      <import  resource ="mapperbean.xml" />      <import  resource ="servicebean.xml" />  <context:component-scan  base-package ="com.boogipop.controller" />     <mvc:default-servlet-handler />      <mvc:annotation-driven />      <bean  class ="org.springframework.web.servlet.view.InternalResourceViewResolver"  id ="internalResourceViewResolver" >                   <property  name ="prefix"  value ="/jsp/" />                   <property  name ="suffix"  value =".jsp" />      </bean >  </beans > 
 
然后还有一个坑点就是假如爆了500,Unsatisfiled错误,那就是说明我们的bean文件没有关联到一起,我们首先自定义了一个Controller:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 package  com.boogipop.controller;import  com.boogipop.pojo.Books;import  com.boogipop.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("/allbooks")      public  String booklist (Model model) {         System.out.println(bookService);         List<Books> books = bookService.SelectAllBooks();         for  (Books book : books) {             System.out.println(book);         }         model.addAttribute("msg" ,"test" );         return  "allbooks" ;     } } 
 
在这里设置了私有属性bookservice,因此我们要将servicebean.xml和ApplicationContext.xml以及springmvc-servlet.xml文件整合在一起
踩完坑之后就开始完善:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package  com.boogipop.controller;import  com.boogipop.pojo.Books;import  com.boogipop.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("/allbooks")      public  String booklist (Model model) {         System.out.println(bookService);         List<Books> books = bookService.SelectAllBooks();         model.addAttribute("books" ,books);         return  "allbooks" ;     } } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 <html> <%@ page contentType="text/html;charset=UTF-8"  language="java"  %> <%@ page isELIgnored="false"  %> <head>     <title>首页</title>     <style>         a{             text-decoration: none;             color: black;             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/allbooks" >进入书籍界面</a> </h3> </body> </html> 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 <%@ taglib prefix="c"  uri="http://java.sun.com/jsp/jstl/core"  %> <%--   Created by IntelliJ IDEA.   User: 22927    Date: 2023 /2 /2    Time: 22 :19    To change this  template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8"  language="java"  %> <%@ page isELIgnored="false"  %> <html> <head>     <link href="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css"  rel="stylesheet" >     <title>书籍展示</title> </head> <body> <div class="container" >     <div class="row clearfix" >         <div class="col-md-12" >             <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>                 <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> 
 
最后页面的效果如下! 还是比较好看的QWQ
SSM整合: 增加书籍功能 增加书籍功能和实现查询功能是一样的,大致就分为controller创建,JSP编写,返回视图:Controller :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @RequestMapping("/toaddbook")    public  String toaddbook (Model model) {        return  "addbook" ;    }    @PostMapping("/addbook")     public  String addbook (Model model,Books books)  throws  Exception {        Boolean  add  =  bookService.AddBook(books);        if (add){            System.out.println("add successfully" );        }        else {            throw  new  Exception ("添加错误" );        }        return  "redirect:/book/allbooks" ;    } 
 
Jsp: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 <%@ page contentType="text/html;charset=UTF-8" language="java" %>   <%@ page isELIgnored="false" %>     <html >        <head >          <link  href ="https://cdn.staticfile.org/twitter-bootstrap/3.4.1/css/bootstrap.min.css"  rel ="stylesheet" >          <title > 添加书籍</title >        </head >        <body >          <div >            <div  class ="container" >              <div  class ="panel panel-default" >                <div  class ="panel-heading" >                  <h3  class ="panel-title" > 新建部门</h3 >                </div >                <div  class ="panel-body" >                  <form  action ="${pageContext.request.contextPath}/book/addbook"  method ="post" >                    <div  class ="form-group" >                      <label  > 书籍名称</label >                      <input  type ="text"  class ="form-control"  placeholder ="书籍名称"  name ="bookName"  required ="required" >                    </div >                    <div  class ="form-group" >                      <label  > 书籍数量</label >                      <input  type ="text"  class ="form-control"  placeholder ="书籍数量"  name ="bookCounts"  required ="required" >                    </div >                    <div  class ="form-group" >                      <label  > 书籍详情</label >                      <input  type ="text"  class ="form-control"  placeholder ="书籍详情"  name ="detail"  required ="required" >                    </div >                    <button  type ="submit"  class ="btn btn-primary" > 提交</button >                  </form >                </div >              </div >            </div >          </div >        </body >      </html >  
 
然后在allbooks界面添加一下进入添加界面的入口:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%--   Created by IntelliJ IDEA.   User: 22927   Date: 2023/2/2   Time: 22:19   To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page isELIgnored="false" %> <html > <head >     <link  href ="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css"  rel ="stylesheet" >      <title > 书籍展示</title >  </head > <body > <div  class ="container" >     <div  class ="row clearfix" >          <div  class ="col-md-12" >              <div  class ="page-header" >                  <h1 >                      <small > 书籍列表 ———— 显示所有数据</small >                  </h1 >              </div >          </div >      </div >  <%--添加书籍界面--%>     <div  class ="row" >          <div  class ="col-md-4 column" >              <a  class ="btn btn-primary"  href ="${pageContext.request.contextPath}/book/toaddbook" > 新增书籍</a >          </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 >                  <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  class ="btn btn-primary btn-xs"  href ="${pageContext.request.contextPath}/book/toupdate?id=${book.bookID}" > 编辑</a >                                                               <a  class ="btn btn-danger btn-xs"  href ="${pageContext.request.contextPath}/book/deletebook/${book.bookID}" > 删除</a >                          </td >                      </tr >                  </c:forEach >                  </tbody >              </table >          </div >      </div >  </div > </body > </html > 
 
这样子这个功能就完善了:
坑点注意 在这里由于我们没有传入ID,所以Controller捕获到的books对象中bookID为null,这样会报错,因为int无法为null,因此会报错,我们要将bookID属性改为integer:
SSM整合:修改和删除书籍功能 Controller :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @GetMapping("/toupdate")    public  String toupdatebook (Model model,int  id) {        Books  book  =  bookService.SelectBookById(id);        model.addAttribute("book" ,book);        return  "updatebook" ;    }    @PostMapping("/updatebook")     public  String updatebook (Books books) {        System.out.println(books);        bookService.UpdateBook(books);        return  "redirect:/book/allbooks" ;    }    @RequestMapping("/deletebook/{id}")     public  String deletebook (@PathVariable  int  id) {        bookService.DelBook(id);        return  "redirect:/book/allbooks" ;    } 
 
JSP: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 <%--   Created by IntelliJ IDEA.   User: 22927   Date: 2023/2/3   Time: 19:52   To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page isELIgnored="false" %> <html > <head >   <link  href ="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css"  rel ="stylesheet" >      <title > 更新书籍信息</title >  </head > <body > <div >   <div  class ="container" >      <div  class ="panel panel-default" >        <div  class ="panel-heading" >          <h3  class ="panel-title" > 新建部门</h3 >        </div >        <div  class ="panel-body" >          <form  action ="${pageContext.request.contextPath}/book/updatebook"  method ="post" >            <div  class ="form-group" >              <input  type ="hidden"   name ="bookID"  value ="${book.bookID}" >            </div >            <div  class ="form-group" >              <label  > 书籍名称</label >              <input  type ="text"  class ="form-control"  placeholder ="书籍名称"  name ="bookName"  required ="required"  value ="${book.bookName}" >            </div >            <div  class ="form-group" >              <label  > 书籍数量</label >              <input  type ="text"  class ="form-control"  placeholder ="书籍数量"  name ="bookCounts"  required ="required"  value ="${book.bookCounts}" >            </div >            <div  class ="form-group" >              <label  > 书籍详情</label >              <input  type ="text"  class ="form-control"  placeholder ="书籍详情"  name ="detail"  required ="required"  value ="${book.detail}" >            </div >            <button  type ="submit"  class ="btn btn-primary" > 提交</button >          </form >        </div >      </div >    </div >  </div > </body > </html > 
 
然后再allbooks界面加上进入删除和修改的入口:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%--   Created by IntelliJ IDEA.   User: 22927   Date: 2023/2/2   Time: 22:19   To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page isELIgnored="false" %> <html > <head >     <link  href ="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css"  rel ="stylesheet" >      <title > 书籍展示</title >  </head > <body > <div  class ="container" >     <div  class ="row clearfix" >          <div  class ="col-md-12" >              <div  class ="page-header" >                  <h1 >                      <small > 书籍列表 ———— 显示所有数据</small >                  </h1 >              </div >          </div >      </div >  <%--添加书籍界面--%>     <div  class ="row" >          <div  class ="col-md-4 column" >              <a  class ="btn btn-primary"  href ="${pageContext.request.contextPath}/book/toaddbook" > 新增书籍</a >          </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 >                  <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  class ="btn btn-primary btn-xs"  href ="${pageContext.request.contextPath}/book/toupdate?id=${book.bookID}" > 编辑</a >                                                               <a  class ="btn btn-danger btn-xs"  href ="${pageContext.request.contextPath}/book/deletebook/${book.bookID}" > 删除</a >                          </td >                      </tr >                  </c:forEach >                  </tbody >              </table >          </div >      </div >  </div > </body > </html > 
 
之后功能就完善了:
SSM整合:查询功能 Controller: 
1 2 3 4 5 6 7 @RequestMapping("/querybook")     public  String querybook (String queryBookName,Model model) {         System.out.println(queryBookName);         List<Books> books = bookService.SelectBookByLike(queryBookName);         model.addAttribute("books" ,books);         return  "allbooks" ;     } 
 
Jsp: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%--   Created by IntelliJ IDEA.   User: 22927   Date: 2023/2/2   Time: 22:19   To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page isELIgnored="false" %> <html > <head >     <link  href ="https://cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css"  rel ="stylesheet" >      <title > 书籍展示</title >  </head > <body > <div  class ="container" >     <div  class ="row clearfix" >          <div  class ="col-md-12" >              <div  class ="page-header" >                  <h1 >                      <small > 书籍列表 ———— 显示所有数据</small >                  </h1 >              </div >          </div >      </div >  <%--添加书籍界面--%>     <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/allbooks" > 书籍展示界面</a >          </div >      </div >  <%--搜索框界面--%>     <div  class ="col-md-4 column" > </div >      <div  class ="col-md-4 column" > </div >      <div  class ="col-md-4 column" >          <form  action ="${pageContext.request.contextPath}/book/querybook"  method ="post"  class ="form-inline"  style ="float: right" >              <input  type ="text"  name ="queryBookName"  class ="form-control"  placeholder ="请输入你要查询的书籍名称" >              <input  type ="submit"  value ="查询"  class ="btn btn-primary" >          </form >      </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 >                  <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  class ="btn btn-primary btn-xs"  href ="${pageContext.request.contextPath}/book/toupdate?id=${book.bookID}" > 编辑</a >                                                               <a  class ="btn btn-danger btn-xs"  href ="${pageContext.request.contextPath}/book/deletebook/${book.bookID}" > 删除</a >                          </td >                      </tr >                  </c:forEach >                  </tbody >              </table >          </div >      </div >  </div > </body > </html > 
 
其实html界面用的还是之前allbooks的,只不过我们改了查询语句,这次我们用的是模糊查询,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 package  com.boogipop.mapper;import  com.boogipop.pojo.Books;import  java.util.List;import  java.util.Map;public  interface  BooksMapper  {    Boolean AddBook (Books book) ;     Boolean DelBook (int  id) ;     Boolean UpdateBook (Books books) ;     List<Books> SelectAllBooks () ;     Books SelectBookById (int  id) ;     List<Books> SelectBookByLike (String queryname) ; } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 package  com.boogipop.service;import  com.boogipop.pojo.Books;import  java.util.List;import  java.util.Map;public  interface  BookService  {                 Boolean AddBook (Books book) ;                  Boolean DelBook (int  id) ;                  Boolean UpdateBook (Books books) ;                  List<Books> SelectAllBooks () ;                  Books SelectBookById (int  id) ;         List<Books> SelectBookByLike (String queryname) ; } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 package  com.boogipop.service;import  com.boogipop.mapper.BooksMapper;import  com.boogipop.pojo.Books;import  org.springframework.beans.factory.annotation.Autowired;import  org.springframework.stereotype.Component;import  java.util.List;import  java.util.Map;@Component public  class  BookServiceImpl  implements  BookService {    @Autowired      private  BooksMapper booksMapper;     @Override      public  Boolean AddBook (Books book)  {         return  booksMapper.AddBook(book);     }     @Override      public  Boolean DelBook (int  id)  {         return  booksMapper.DelBook(id);     }     @Override      public  Boolean UpdateBook (Books books)  {         return  booksMapper.UpdateBook(books);     }     @Override      public  List<Books> SelectAllBooks ()  {         return  booksMapper.SelectAllBooks();     }     @Override      public  Books SelectBookById (int  id)  {         return  booksMapper.SelectBookById(id);     }     @Override      public  List<Books> SelectBookByLike (String queryname)  {         return  booksMapper.SelectBookByLike(queryname);     } } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <?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.boogipop.mapper.BooksMapper" >     <select  id ="SelectAllBooks"  resultType ="Books" >          select * from books     </select >      <select  id ="SelectBookById"  resultType ="Books"  parameterType ="int" >          select * from books where bookID=#{id}     </select >      <insert  id ="AddBook"  parameterType ="Books" >          insert into books(bookName,bookCounts,detail) values (#{bookName},#{bookCounts},#{detail})     </insert >      <update  id ="UpdateBook"  parameterType ="Books" >          update books set bookName=#{bookName},bookCounts=#{bookCounts},detail=#{detail} where bookID=#{bookID}     </update >      <delete  id ="DelBook"  parameterType ="int" >          delete from books where bookID=#{id};         ALTER TABLE books AUTO_INCREMENT = 1;     </delete >      <select  id ="SelectBookByLike"  parameterType ="String"  resultType ="Books" >          select * from books where bookName like concat("%",#{querybookname},"%")     </select >  </mapper > 
 
问题总结 在整合的过程中肯定遇到了一些问题:
删除数据后id不连续问题:1 2 3 4 <delete  id ="DelBook"  parameterType ="int" >         delete from books where bookID=#{id};         ALTER TABLE books AUTO_INCREMENT = 1;     </delete >  
 
1 2 3 4 jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/ssmbuild?useSSL=true&seUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true jdbc.username=root jdbc.password=jiayou357753 
 
 
Ajax 其实这个不想多讲的,因为没啥好说的,就是jquery的一些用法
SSM整合:登录拦截 这里我觉得狂神讲的可能不太好,因此打算自己写写试试,首先我们先来介绍一下SpringMVC中的拦截器是什么: 其实在Struct2中也有拦截器这一个概念(struct2是个啥远古东西),SpringMVC中也有,你可以理解为和Filter一样,也是对我们的请求进行拦截,我们接下来就用一个小Demo来测试一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package  com.boogipop.Interceptor;import  jakarta.servlet.http.HttpServletRequest;import  jakarta.servlet.http.HttpServletResponse;import  org.springframework.web.servlet.HandlerInterceptor;import  org.springframework.web.servlet.ModelAndView;public  class  LoginInterceptor  implements  HandlerInterceptor  {    @Override      public  boolean  preHandle (HttpServletRequest request, HttpServletResponse response, Object handler)  throws  Exception {         System.out.println("preHandle in" );         return  true ;     }     @Override      public  void  postHandle (HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)  throws  Exception {         System.out.println("postHandler in" );     }     @Override      public  void  afterCompletion (HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)  throws  Exception {         System.out.println("afterHandler in" );     } } 
 
我们将我们自定义类继承HandlerInterceptor接口即可,和Filter一样,之后重写他的方法,在这里放行 是通过preHandle中return true来实现的,如果return false,那么就不会进入posthandle和afterhandle之中,随后我们需要在springmvc-servlet.xml中去配置拦截器设置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 <?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/context           https://www.springframework.org/schema/context/spring-context.xsd            http://www.springframework.org/schema/mvc             http://www.springframework.org/schema/mvc/spring-mvc.xsd" >    <import  resource ="ApplicationContext.xml" />      <import  resource ="mapperbean.xml" />      <import  resource ="servicebean.xml" />  <context:component-scan  base-package ="com.boogipop.controller" />     <mvc:default-servlet-handler />      <mvc:annotation-driven />      <bean  class ="org.springframework.web.servlet.view.InternalResourceViewResolver"  id ="internalResourceViewResolver" >                   <property  name ="prefix"  value ="/jsp/" />                   <property  name ="suffix"  value =".jsp" />      </bean >      <mvc:interceptors >          <mvc:interceptor >                           <mvc:mapping  path ="/**" />              <bean  class ="com.boogipop.Interceptor.LoginInterceptor" />          </mvc:interceptor >      </mvc:interceptors >  </beans > 
 
这样一个简单的拦截器就完成了,之后我们写一个测试的requestmapping即可:
访问接口,发现拦截成功,这一过程与AOP横切似乎有点类似,但不完全是,那么接下来我们需要写一个登录功能,我们遵从由内到外的原则,也就是先写底层controller,再去编写前端view视图,在这一过程我们需要写controller和Interceptor,以及Model(数据库): 首先我们先创建一张用户表吧: 那么随之而来的就是pojo类和Mapper类了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 package  com.boogipop.pojo;import  org.apache.ibatis.type.Alias;@Alias("User") public  class  User  {    private  Integer id;     private  String username;     private  String password;     public  User (String username, String password)  {         this .username = username;         this .password = password;     }     @Override      public  String toString ()  {         return  "User{"  +                 "id="  + id +                 ", username='"  + username + '\''  +                 ", password='"  + password + '\''  +                 '}' ;     }     public  Integer getId ()  {         return  id;     }     public  void  setId (Integer id)  {         this .id = id;     }     public  String getUsername ()  {         return  username;     }     public  void  setUsername (String username)  {         this .username = username;     }     public  String getPassword ()  {         return  password;     }     public  void  setPassword (String password)  {         this .password = password;     }     public  User ()  {     }     public  User ( String username, String password,Integer id)  {         this .id = id;         this .username = username;         this .password = password;     } } 
 
1 2 3 4 5 6 7 8 9 package  com.boogipop.mapper;import  com.boogipop.pojo.User;public  interface  UserMapper  {    Boolean Register (User user) ;     User SelectUserByName (String name) ; } 
 
1 2 3 4 5 6 7 8 9 10 11 <?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.boogipop.mapper.UserMapper" >     <insert  id ="Register"  parameterType ="User" >          insert into user(username,password) values (#{username},#{password})     </insert >      <select  id ="SelectUserByName"  parameterType ="String"  resultType ="User" >          select * from user where username=#{username}     </select >  </mapper > 
 
Controller: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 package  com.boogipop.controller;import  com.boogipop.pojo.Books;import  com.boogipop.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.*;import  org.springframework.web.servlet.HandlerInterceptor;import  java.util.List;@Controller @RequestMapping("/book") public  class  BookController  {    @Autowired      @Qualifier("bookServiceImpl")      private  BookService bookService;     @RequestMapping("/allbooks")      public  String booklist (Model model) {         List<Books> books = bookService.SelectAllBooks();         model.addAttribute("books" ,books);         return  "allbooks" ;     }     @RequestMapping("/toaddbook")      public  String toaddbook (Model model) {         return  "addbook" ;     }     @PostMapping("/addbook")      public  String addbook (Model model,Books books)  throws  Exception {         Boolean  add  =  bookService.AddBook(books);         if (add){             System.out.println("add successfully" );         }         else {             throw  new  Exception ("添加错误" );         }         return  "redirect:/book/allbooks" ;     }     @GetMapping("/toupdate")      public  String toupdatebook (Model model,int  id) {         Books  book  =  bookService.SelectBookById(id);         model.addAttribute("book" ,book);         return  "updatebook" ;     }     @PostMapping("/updatebook")      public  String updatebook (Books books) {         System.out.println(books);         bookService.UpdateBook(books);         return  "redirect:/book/allbooks" ;     }     @RequestMapping("/deletebook/{id}")      public  String deletebook (@PathVariable  int  id) {         bookService.DelBook(id);         return  "redirect:/book/allbooks" ;     }     @RequestMapping("/querybook")      public  String querybook (String queryBookName,Model model) {         System.out.println(queryBookName);         List<Books> books = bookService.SelectBookByLike(queryBookName);         model.addAttribute("books" ,books);         return  "allbooks" ;     }     @RequestMapping("/index")      public  String index ()  {         return  "index" ;     } } 
 
Inceptor: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package  com.boogipop.Interceptor;import  jakarta.servlet.http.HttpServletRequest;import  jakarta.servlet.http.HttpServletResponse;import  jakarta.servlet.http.HttpSession;import  org.springframework.web.servlet.HandlerInterceptor;import  org.springframework.web.servlet.ModelAndView;public  class  LoginInterceptor  implements  HandlerInterceptor  {    @Override      public  boolean  preHandle (HttpServletRequest request, HttpServletResponse response, Object handler)  throws  Exception {         HttpSession  session  =  request.getSession();         String username= (String) session.getAttribute("username" );         if (username!=null ){             return  true ;         }         else  {             response.sendRedirect("/user/login" );             return  false ;         }     }     @Override      public  void  postHandle (HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)  throws  Exception {     }     @Override      public  void  afterCompletion (HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)  throws  Exception {     } } 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 	<?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/context           https://www.springframework.org/schema/context/spring-context.xsd            http://www.springframework.org/schema/mvc             http://www.springframework.org/schema/mvc/spring-mvc.xsd" >    <import  resource ="ApplicationContext.xml" />      <import  resource ="mapperbean.xml" />      <import  resource ="servicebean.xml" />  <context:component-scan  base-package ="com.boogipop.controller" />     <mvc:default-servlet-handler />      <mvc:annotation-driven />      <bean  class ="org.springframework.web.servlet.view.InternalResourceViewResolver"  id ="internalResourceViewResolver" >                   <property  name ="prefix"  value ="/jsp/" />                   <property  name ="suffix"  value =".jsp" />      </bean >      <mvc:interceptors >          <mvc:interceptor >                           <mvc:mapping  path ="/book/**" />              <bean  class ="com.boogipop.Interceptor.LoginInterceptor" />          </mvc:interceptor >      </mvc:interceptors >  </beans > 
 
JSP: 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 <!DOCTYPE html > <%@ page contentType="text/html; charset=utf-8"%> <%@ page isELIgnored="false" %> <html  lang ="zh-CN" > <head >     <meta  charset ="UTF-8" >      <meta  http-equiv ="X-UA-Compatible"  content ="IE=edge" >      <meta  name ="viewport"  content ="width=device-width, initial-scale=1.0" >      <title > 图书管理系统登录界面</title >      <link  rel ="stylesheet"  href ="/static/css/style.css" >  </head > <body > <div  class ="box" >     <h2 > Login</h2 >      <form  action ="${pageContext.request.contextPath}/user/login"  method ="post" >          <div  class ="input-box" >              <label > 账号</label >              <input  type ="text"  name ="username" />          </div >          <div  class ="input-box" >              <label > 密码</label >              <input  type ="password"  name ="password" />              <span  style ="color: white;font-size: small" > ${msg}</span >          </div >          <div  class ="btn-box" >              <a  href ="#" > 忘记密码?</a >              <div >                  <button  type ="submit"  value ="login" > 登录</button >                                 <%--                无下划线--%>                 <button > <a  href ="${pageContext.request.contextPath}/user/register"  style ="color: white;text-decoration: none"  > 注册</a > </button >              </div >          </div >      </form >  </div > <script  type ="text/javascript" > </script > </body > </html > 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 <!DOCTYPE html > <%@ page contentType="text/html; charset=utf-8"%> <%@ page isELIgnored="false" %> <html  lang ="zh-CN" > <head >   <meta  charset ="UTF-8" >    <meta  http-equiv ="X-UA-Compatible"  content ="IE=edge" >    <meta  name ="viewport"  content ="width=device-width, initial-scale=1.0" >    <title > 用户注册界面</title >    <link  rel ="stylesheet"  href ="/static/css/registerstyle.css" >  </head > <body > <div  class ="box" >   <h2 > Login</h2 >    <form  action ="${pageContext.request.contextPath}/user/register"  method ="post" >      <div  class ="input-box" >        <label > 账号</label >        <input  type ="text"  name ="username" />      </div >      <div  class ="input-box" >        <label > 密码</label >        <input  type ="password"  name ="password" />        <span  style ="color: white;font-size: small" > ${msg}</span >      </div >      <div  class ="btn-box" >        <a  href ="#" > 什么?在想我的事情?</a >        <div >          <button  type ="submit"  value ="login" > 提交注册</button >          <%--                无下划线--%>         <button > <a  href ="${pageContext.request.contextPath}/user/login"  style ="color: white;text-decoration: none"  > 登录</a > </button >        </div >      </div >    </form >  </div > <script  type ="text/javascript" > </script > </body > </html > 
 
坑点小结 首先是遇到错误Error attempting to get column 'username' from result set的解决方法,这个是因为pojo类没有无参构造方法,假如不要无参构造方法的话,你有参构造方法中形参的排序和类型一定要和数据库字段保持一致,否则报错:
SpringMVC文件上传 SpringMVC文件下载 小结 那到这里SpringMVC也算是正式结束了,开发这东西果然会上瘾的,寒假学了Spring、mybatis、springmvc,感觉也是获得了挺多东西的,再接再厉