springmvc学习笔记
- 一、MVC回顾
- 二、SpringMVC原理及开发步骤
- 三. 使用注解开发SpringMVC
- 四、Controller、RequestMapping、RestFul、结果跳转等功能详解
- 五、JSON
- 六 、SSM整合
- 1. mybatis层
- 1.1 数据库准备
- 1.2 创建一个maven项目
- 1.3 导入依赖包pom.xml:junit,数据库驱动,连接池,servlet,JSP,mybatis,mybatis-spring,spring
- 1.4 静态资源导出问题pom.xml
- 1.5 创建基本的包架构:com.sxsl.pojo、controller、dao、service
- 1.6 创建mybatis的核心配置文件mybatis-config.xml
- 1.7 创建spring的核心配置文件applicationContext.xml,点击configure application context
- 1.8 编写实体类Books.java
- 1.9 编写实体类的接口类BookMapper.java
- 1.10 编写接口类对应的xml文件:UserMapper.xml(与接口类同目录)
- 1.11 注册XXXmapper.xml:mybatis-config.xml
- 1.12 编写业务层的接口类UserService.java
- 1.13 编写业务层的实现类BookServiceImpl.java
- 1.14 mybatis小结
- 2. spring层
- 3. springmvc层
- 4 数据的展现:Controller与JSP页面的交互
- 七、Ajax
- 七、拦截器
- 八、总结图
中文网站:https://www.w3cschool.cn/spring_mvc_documentation_linesh_translation/
https://docs.spring.io/spring-framework/docs/4.3.24.RELEASE/spring-framework-reference/html/
线上画图工具:https://www.processon.com/
一、MVC回顾
1. MVC:模型(dao,service),视图(JSP),控制器( servlet)
(1) MVC是一种软件设计规范,mvc降低视图与业务逻辑的双向耦合。
(2) 将业务逻辑、数据、显式分离的方法组织代码,
2. model(模型)
(1) 数据模型,提供要展示的数据,包含数据(dao)和行为(service)。
(2) 真实开发中,可能存在前端、数据传输、实体类;将pojo类细分为vo类(视图层对象)。
(3) model的功能:业务逻辑;保存数据的状态。
3. view(视图)
负责进行模型的展示,一般就是我们所见到的用户界面;客户想要看到的东西。
4. Controller(控制器)
(1) 接受用户请求,委托给模型进行处理;处理完毕后将返回的模型数据返回给视图,由视图进行展示。
(2) JSP本质是一个servlet。
(3) Controller的功能:取得表单数据;调用业务逻辑;转向指定页面。
5. 典型MVC模型:JSP+serlvet+JavaBean
6. 回忆servlet
6.1 servlet的工作过程
(1) Web Client 向Servlet容器(Tomcat)发出Http请求
(2) Servlet容器接收Web Client的请求
(3) Servlet容器创建一个HttpRequest对象,将Web Client请求的信息封装到这个对象中。
(4) Servlet容器创建一个HttpResponse对象
(5) Servlet容器调用HttpServlet对象的doservice方法,把HttpRequest对象与HttpResponse对象作为参数传给HttpServlet 对象。
(6) HttpServlet调用HttpRequest对象的有关方法,获取Http请求信息。
(7) HttpServlet调用HttpResponse对象的有关方法,生成响应数据。
(8) Servlet容器把HttpServlet的响应结果传给Web Client。
6.2 servlet的生命周期:Servlet 加载—>实例化—>服务—>销毁。
(1) init():
在Servlet的生命周期中,仅执行一次init()方法。它是在服务器装入Servlet时执行的,负责初始化Servlet对象。可以配置服务器,以在启动服务器或客户机首次访问Servlet时装入Servlet。无论有多少客户机访问Servlet,都不会重复执行init()。
(2) service():
它是Servlet的核心,负责响应客户的请求。每当一个客户请求一个HttpServlet对象,该对象的Service()方法就要调用,而且传递给这个方法一个“请求”(ServletRequest)对象和一个“响应”(ServletResponse)对象作为参数。在HttpServlet中已存在Service()方法。默认的服务功能是调用与HTTP请求的方法相应的do功能。
(3) destroy():
仅执行一次,在服务器端停止且卸载Servlet时执行该方法。当Servlet对象退出生命周期时,负责释放占用的资源。一个Servlet在运行service()方法时可能会产生其他的线程,因此需要确认在调用destroy()方法时,这些线程已经终止或完成。
6.3 编程shix
(1) 注册servlet:web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.sxsl.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<!--<session-config>-->
<!--<session-timeout>15</session-timeout>-->
<!--</session-config>-->
</web-app>
(2) 编写servlet类继承HttpServlet,重写doGet()方法
package com.sxsl.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 HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1.获取前端参数
String method=req.getParameter("method");
if (method.equals("add")){
req.getSession().setAttribute("msg","执行了add方法");
}
if (method.equals("delete")){
req.getSession().setAttribute("msg","执行了delete方法");
}
//2.调取业务层
//3.视图转发或重定向
req.getRequestDispatcher("WEB-INF/jsp/test.jsp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
(3) 编写两个jsp页面,一个请求页面,一个重定向jsp页面
7、pojo层 Dao层 service层 controller层的作用
7.1 pojo层(model)plain ordinary java object 无规则简单java对象
(1)实体类这一层,与数据库中的属性值基本保持一致。有的开发写成pojo,有的写成model,也有domain,也有dto(这里做参数验证,比如password不能为空等),实体类如果你不懂什么东西的话,那你就想成是范围。
(2)POJO持久化之后==〉PO
(在运行期,由Hibernate中的cglib动态把POJO转换为PO,PO相对于POJO会增加一些用来管理数据库entity状态的属性和方法。PO对于programmer来说完全透明,由于是运行期生成PO,所以可以支持增量编译,增量调试。)
(3)POJO传输过程中==〉DTO
(4)POJO用作表示层==〉VO
(5)PO 和VO都应该属于它。
7.2 DAO层(mapper)【方法名与mapper中id名相同】【impl查询数据库】:
(1)DAO层叫数据访问层,全称为data access object,也叫mapper层 。某个DAO一定是和数据库的某一张表一一对应的,其中封装了CRUD(增加Create、检索Retrieve、更新Update和删除Delete)基本操作,DAO只做原子操作。无论多么复杂的查询,dao只是封装增删改查。至于增删查改如何去实现一个功能,dao是不管的。
(2)Mybatis中,dao(mapper)一般是接口,dao中函数的具体定义在XXXMapper.xml文件,只要dao中的函数名与mapper文件中的id相同,参数类型和个数相同即可。
7.3 Service层【定义接口】【impl–函数进行实现】
(1)Service层叫业务层,被称为服务,粗略的理解就是对一个或多个DAO进行的再次封装,封装成一个服务,所以这里也就不会是一个原子操作了,需要事物控制。管理具体的功能的。
(2)service包含了serviceImpl(service接口的实现类) 是提供给controller 使用的,针对于某些业务将 dao 的对于某些表的crud进行组合,也就是说间接的和数据库打交道。
7.4 Controller层【处理前台发送的请求】
Controler负责请求转发,接受页面过来的参数,传给Service处理,接到返回值,再传给页面。管理业务(Service)调度和管理跳转的。
7.5 util层
工具类啊,用来封装相应的方法,然后将其放在对应的util包下,使用的时候直接调用就可以了。比如,日期转换util,http请求等相关的工具类。获取properties文件属性等等都可能会被放进util
7.6 VO层 value object 值对象 / view object 表现层对象
(1)vo层的存在就是方便前端获取数据,后端将前端的需要的数据做一个整合,打包成一个类。
(2)可以和表对应,也可以不,这根据业务的需要。
7.7 Filter层
Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。
7.8 PO:persistent object 持久对象
(1)有时也被称为Data对象,对应数据库中的entity,可以简单认为一个PO对应数据库中的一条记录。
(2 )在hibernate持久化框架中与insert/delet操作密切相关。
(3)PO中不应该包含任何对数据库的操作。
二、SpringMVC原理及开发步骤
1. SpringMVC原理
Spring MVC框架,与其他很多web的MVC框架一样:请求驱动;所有设计都围绕着一个中央Servlet来展开,它负责把所有请求分发到控制器;同时提供其他web应用开发所需要的功能。不过Spring的中央处理器,DispatcherServlet,能做的比这更多。它与Spring IoC容器做到了无缝集成,这意味着,Spring提供的任何特性,在Spring MVC中你都可以使用。
1.1 Spring Web MVC处理请求的(高层抽象)工作流
1.2 springMVC处理流程
1.3 DispatcherServlet继承关系图
2. SpringMVC的原理开发项目步骤
2.1 配置web.xml,注册DispatcherServlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--注册DispatcherServlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--关联一个SpringMVC的配置文件:[servlet-name]-servlet.xml-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<!--启动级别 1-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--/ 匹配所有请求,不包括(*.jsp)-->
<!--/* 匹配所有请求,包括(*.jsp)-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
2.2 配置springMVC的配置文件,web.xml中指定的springmvc-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
<!--视图解析器:DispatcherServlet给它的ModelAndView-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
<!--注册hander,注意不要忘了hello前的/-->
<bean id="/hello" class="com.sxsl.controller.HelloController"/>
</beans>
2.3 编写控制器类HelloController.java
package com.sxsl.controller;
import org.springframework.lang.Nullable;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloController implements Controller {
@Nullable
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
//模型和视图
ModelAndView mv = new ModelAndView();
//封装对象,放在ModelAndView中,Model
mv.addObject("msg","HelloSpringMVC!");
//封装要跳转的视图,放在ModelAndView中
mv.setViewName("hello");//:/WEB-INF/jsp/hello.jsp
return mv;
}
}
2.4 编写jsp文件,返回的结果放在msg变量中,在jsp页面显示
${msg}
2.5 404错误,缺少jar包的处理
jar包存在,但无法显示输出,在idea中需要手工加载到lib中
File——>Project Structure——>Artifacts——>查看WEB-INF是否存在lib目录——>新建lib目录——>点击+,包依赖的jar包添加到lib中。如下图:
三. 使用注解开发SpringMVC
1. 步骤
1.1 创建一个空项目,导入 web框架。在Project Structure中的Artifacts中新建lib目录,添加依赖的jar包。
1.2 导入相关jar包及maven静态资源过滤pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>SpringMVC</artifactId>
<groupId>com.sxsl</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>lwp</artifactId>
<!--导入依赖包-->
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<!--maven静态资源过滤-->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
1.3 编写web.xml,注册DispatchServlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--注册DispatcherServlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--关联一个SpringMVC的配置文件:[servlet-name]-servlet.xml-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<!--启动级别 1-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--/ 匹配所有请求,不包括(*.jsp)-->
<!--/* 匹配所有请求,包括(*.jsp)-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
1.4 编写SpringMVC配置文件:springmvc-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--自动扫描包,让指定包下的注解生效,由IOC容器统一管理-->
<context:component-scan base-package="com.sxsl.controller"/>
<mvc:default-servlet-handler/>
<mvc:annotation-driven/>
<!--视图解析器:DispatcherServlet给它的ModelAndView-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
1.5 创建对应的控制类,HelloController.java
package com.sxsl.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
@RequestMapping("/hello")
public String hello(Model model){
model.addAttribute("msg","hello springMVC annotation!!");
//封装数据
return "hello"; //会被视图解析器处理
}
}
1.6 完善前段视图/WEB-INF/jsp/hello.jsp与controller之间的对应,测试运行
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
${msg}
</body>
</html>
2. 说明
(1) 使用SpringMVC必须的三大件:处理器映射器、处理器适配器、视图解析器
(2) 注解开发SpringMVC时,我们通常只要手动配置视图解析器,而处理器映射器和处理器适配器只需开启注解驱动即可。
四、Controller、RequestMapping、RestFul、结果跳转等功能详解
1. Controller
1.1 Controller功能:
(1) 控制器提供访问应用程序的行为,通常通过接口定义或注解定义两种方法实现。
(2) 控制器负责解析用户的请求,并将其转换成一个模型。
(3) 在SpringMVC中一个控制器可以包含多个方法。
1.2 实现Controller接口
package com.sxsl.controller;
import org.springframework.lang.Nullable;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloController implements Controller {
@Nullable
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
//模型和视图
ModelAndView mv = new ModelAndView();
//封装对象,放在ModelAndView中,Model
mv.addObject("msg","HelloSpringMVC!");
//封装要跳转的视图,放在ModelAndView中
mv.setViewName("hello");//:/WEB-INF/jsp/hello.jsp
return mv;
}
}
1.3 使用注解定义
package com.sxsl.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller //这个注释代表这个类会被spring接管,
// 被注解类的所有方法返回值是String且有具体页面可跳转,就会被视图解析器解析
public class ControllerTest2 {
@RequestMapping("/t2")
public String test2(Model model){
model.addAttribute("msg","ControllerTest2");
return "test";
}
@RequestMapping("/t1")
public String test1(Model model){
model.addAttribute("msg","ControllerTest1");
return "test"; //return 返回的是前后缀加上的一个JSP页面,即:/WEB-INF/jsp/test.jsp
}
}
1.4 说明
(1) 使用接口定义,一个接口类只能包含一个方法,并在SpringMVC-servlet.xml注册。
(2) 使用注解定义,一个控制器可包含多个方法。
(3) 使用@Controller注释代表这个类会被spring接管,被注解类的所有方法返回值是String且有具体页面可跳转,就会被视图解析器解析。
(4) 使用@Controller注释类的方法的return “test”,return 返回的是前后缀加上的一个JSP页面,即:/WEB-INF/jsp/test.jsp。
(5) 使用@Controller注解定义的控制器多个方法可以return同一个页面,确保页面的复用。
2. RequestMapping
2.1 RequestMapping功能
(1) @RequestMapping注释用于映射url到一个控制器类或一个特定的处理程序方法。
(2) 可用在类上,也可用在方法上。
(3) 用在类上,表示类中所有表示请求的方法都是以该地址作为父路径。
2.2 作用在方法上:调用方式http://localhost:8080/t1
package com.sxsl.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class ControllerTest3 {
@RequestMapping("/t1")
public String test3(Model model){
model.addAttribute("msg","ControllerTest3");
return "test";
}
}
2.3 作用在类上,调用http://localhost:8080/c3/t1
package com.sxsl.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/c3")
public class ControllerTest3 {
@RequestMapping("/t1")
public String test3(Model model){
model.addAttribute("msg","ControllerTest3");
return "test";
}
}
3. RestFul风格
3.1 概念
(1) RestFul就是一种资源定位和资源操作的风格。
(2) 不是标准也不是协议,只是一种风格。
(3) 基于这种风格的软件设计可以更简洁、更有层次,更易于实现缓存等机制。
(4) RestFul好处:简洁、高效、安全。
3.2 功能
(1) 资源:互联网所有的事务都可以抽象为资源。
(2) 资源操作:使用POST、DELETE、PUT、GET,使用不同方法对资源进行操作。
(3) 分别对应增加、删除、修改、查询。
(4) 传统模式通过链接或不同的参数来实现,RestFul可以通过不同的请求方式来实现不同的效果。
3.3 实现代码
package com.sxsl.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
@Controller
public class RestFulController {
//原来模式http://localhost:8080/add?a=2&b=4
//RestFul风格:http://localhost:8080/add/2/4
@RequestMapping(value="/add/{a}/{b}",method = RequestMethod.GET)
//RestFul方式二:@RequestMapping(path="/add/{a}/{b}",method = RequestMethod.GET)
//RestFul方式三:@GetMapping("/add/{a}/{b}")
public String test4(@PathVariable int a, @PathVariable int b, Model model){
int res=a+b;
model.addAttribute("msg","结果为"+res);
return "test";
}
}
4. 结果跳转
4.1 ModelAndView
(1) 设置ModelAndView对象,根据view的名称和视图解析器跳转到指定页面。
(2) 页面:{视图解析器前缀}+viewname+{视图解析器后缀}
4.2 无视图解析器实现跳转
package com.sxsl.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@Controller
public class ModelTest1 {
@RequestMapping("/m1/t1")
public String test1(Model model){
//转发
model.addAttribute("msg","ModelTest1");
//return "/WEB-INF/jsp/test.jsp";
//return "forward:/WEB-INF/jsp/test.jsp";
//重定向
return "redirect:/index.jsp";
}
}
4.3 有视图解析器实现跳转
配置springmvc-servlet.xml
<!--视图解析器:DispatcherServlet给它的ModelAndView-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
package com.sxsl.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@Controller
public class ModelTest1 {
@RequestMapping("/m1/t1")
public String test1(Model model){
//转发,自动加视图解析器的前后缀
model.addAttribute("msg","ModelTest1");
//return "test";
//重定向,直接用redirect:+重定向地址
return "redirect:/index.jsp";
}
}
4.4 说明
(1) 转发,地址栏不会发生变化,重定向地址栏指向重定向地址。
(2) 有无视图解析器,重定向都是直接用redirect:+重定向地址,如 return “redirect:/index.jsp”;。
5. 数据处理
5.1 提交的域名称与处理方法的参数名一致
调用方式:http://localhost:8080/user/t1?name=lwp
package com.sxsl.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/user")
public class UserController {
@GetMapping("/t1")
public String test1(String name,Model model){
//1.接收前段参数
System.out.println(name);
//2. 将返回的结果传递给前端
model.addAttribute("msg",name);
//3. 跳转视图
return "test";
}
}
5.2 提交的域名称与处理方法的参数名不一致
调用方式:http://localhost:8080/user/t1?username=lwp
package com.sxsl.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
@RequestMapping("/user")
public class UserController {
@GetMapping("/t1")
public String test1(@RequestParam("username") String name, Model model){
//1.接收前段参数
System.out.println(name);
//2. 将返回的结果传递给前端
model.addAttribute("msg",name);
//3. 跳转视图
return "test";
}
}
5.3 提交的是一个对象
(1) 脚本
//前端接收一个对象:id ,name,age
/*
1.接收前端用户传递的参数,判断参数的名字,假设名字直接在方法上,可直接使用
2.假设传递的是一个对象User,匹配User对象的字段名,如果一致就匹配成功,否则匹配不成功
*/
@GetMapping("/t2")
public String test2(User user,Model model){
model.addAttribute("msg",user.toString());
System.out.println(user);
return "test";
}
(2) 如果使用对象,传递的参数名与对象名必须一致,否则返回null。
5.4 ModelAndView、Model、ModelMap比较
(1) Model只要寥寥几个方法只适合存储数据,简化了新手对Model对象的操作和理解。
(2) ModelMap继承了LinkedMap,出了实现一些自身的方法,同样也继承了LinkedMap的方法和属性。
(3) ModelAndView可以在存储数据的同时,可以进行设置返回的逻辑视图,进行控制展示层的跳转。
6. 乱码
6.1 自己编写过滤代码
package com.sxsl.filter;
import javax.servlet.*;
import java.io.IOException;
public class EncodingFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
filterChain.doFilter(servletRequest,servletResponse);
}
public void destroy() {
}
}
注册在web.xml中
<filter>
<filter-name>encoding</filter-name>
<filter-class>com.sxsl.filter.EncodingFilter</filter-class>
</filter>
<!--<url-pattern>/*</url-pattern>,要用/*包含.jsp文件,(/)否则执行请求-->
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
6.2 采用SpringMVC自带的过滤代码
<!--配置SpringMVC的乱码过滤-->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
五、JSON
1. 什么是json
(1) JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
(2) 前后端分离时代:后端部署后端,提供接口,提供数据;前端独立部署,负责渲染后端数据。
(3) json与js对象相互转换
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<script type="text/javascript">
//编写一个JavaScript对象
var user={
name:"lwp",
age:28,
sex:"男"
};
//将js对象转换为json对象
var json=JSON.stringify(user);
console.log(json);
//将json对象转换为js对象
var lwp=JSON.parse(json);
console.log(lwp);
</script>
<body>
</body>
</html>
2. Jackson使用
2.1 导入依赖包:pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>SpringMVC</artifactId>
<groupId>com.sxsl</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-05-json</artifactId>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
</dependencies>
</project>
2.2 web.xml,注册DIspatchSerVlet和过滤器
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--注册DispatcherServlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--关联一个SpringMVC的配置文件:[servlet-name]-servlet.xml-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc-servlet.xml</param-value>
</init-param>
<!--启动级别 1-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--/ 匹配所有请求,不包括(*.jsp)-->
<!--/* 匹配所有请求,包括(*.jsp)-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--配置SpringMVC的乱码过滤-->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<!--<url-pattern>/*</url-pattern>,要用/*包含.jsp文件,(/)否则执行请求-->
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
2.3 springmvc-servlet.xml:配置乱码mvc
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--自动扫描包,让指定包下的注解生效,由IOC容器统一管理-->
<context:component-scan base-package="com.sxsl.controller"/>
<!--json乱码问题解决-->
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="utf-8"/>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="failOnEmptyBeans" value="false"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!--视图解析器:DispatcherServlet给它的ModelAndView-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
2.4 编写Controller代码
(1) 通用方法:JsonUtil
package com.sxsl.util;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import java.text.SimpleDateFormat;
public class JsonUtil {
//方法重载,并复用重载的方法,避免重复代码的录入
public static String getJson(Object object){
return getJson(object,"yyyy-MM-dd HH:mm ss");
}
public static String getJson(Object object,String dateFormat){
ObjectMapper mapper=new ObjectMapper();
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
SimpleDateFormat sdf=new SimpleDateFormat(dateFormat);
mapper.setDateFormat(sdf);
try {
return mapper.writeValueAsString(object);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
}
(2) UserController.java代码实现
package com.sxsl.controller;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.sxsl.pojo.User;
import com.sxsl.util.JsonUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
@Controller//会走视图解析器
//@RestController //不会走视图解析器,直接返回一个字符串
public class UserController {
@RequestMapping("/j1")
@ResponseBody //不会走视图解析器, 会直接返回一个字符串,配合@Controller,
public String json1() throws JsonProcessingException {
//jackson对象 ObjectMapper
ObjectMapper mapper = new ObjectMapper();
//创建一个对象
User user = new User("李维平",34,"男");
String string = mapper.writeValueAsString(user);
return string;
}
@RequestMapping("/j2")
@ResponseBody
public String json2() throws JsonProcessingException {
//jackson对象 ObjectMapper
// ObjectMapper mapper = new ObjectMapper();
List<User> userList=new ArrayList<User>();
//创建一个对象
User user1 = new User("李维平1",34,"男");
User user2 = new User("李维平2",33,"男");
User user3 = new User("李维平3",33,"男");
User user4 = new User("李维平4",34,"男");
userList.add(user1);
userList.add(user2);
userList.add(user3);
userList.add(user4);
//String string = mapper.writeValueAsString(userList);
return JsonUtil.getJson(userList);
}
@RequestMapping("/j3")
@ResponseBody //不会走视图解析器, 会直接返回一个字符串,配合@Controller,
public String json3() throws JsonProcessingException {
//jackson对象 ObjectMapper
ObjectMapper mapper = new ObjectMapper();
//不适用时间戳,即关闭时间戳
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
//创建一个对象
Date date = new Date();
//自定义日期格式
// SimpleDateFormat sdf=new SimpleDateFormat("YYYY-MM-DD hh:mm ss");
//mapper.setDateFormat(sdf);
//ObjectMapper,时间解析后的默认格式为TimeStamp,时间戳
//String string = mapper.writeValueAsString(date);//配合mapper.configure和mapper.setDateFormat使用
//String string = mapper.writeValueAsString(sdf.format(date));//下面是纯Java方式,不用上面的 mapper.configure
return JsonUtil.getJson(date,"yyyy-MM-dd HH:mm ss");
}
}
2.5 说明
(1) JsonUtil.Java中的两个getJson的参数不同实现重载,且第一个getJson(Object object)复用第二个getJson(Object object,String dateFormat)代码;只需在调用时补齐第二个参数即可。
(2) @Controller//会走视图解析器,要返回对象字符串,需要与@ResponseBody (不会走视图解析器, 会直接返回一个字符串)配合使用。
(3) @RestController 不会走视图解析器,单独使用直接返回一个字符串。
(4) 在UserController.java中,方法test1()直接将创建ObjectMapper对象,调用ObjectMapper.writeValueAsString(user方法直接写到该方法中;方法test2()和方法test3()实现过程中,将ObjectMapper相关部分写成一个工具类的一个静态方法,方法test2()和方法test3()以不同参数重载方式调用该方法,避免代码的重复编写。
3. fastjson
3.1 Fastjson 简介
(1) Fastjson 是一个 Java 库,可以将 Java 对象转换为 JSON 格式,当然它也可以将 JSON 字符串转换为 Java 对象。
(2) Fastjson 可以操作任何 Java 对象,即使是一些预先存在的没有源码的对象。
(3) Fastjson 源码地址:https://github.com/alibaba/fastjson
(4) Fastjson 中文 Wiki:https://github.com/alibaba/fastjson/wiki/Quick-Start-CN
3.2 使用Fastjosn
(1) 导入依赖包pom.xml
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.3</version>
</dependency>
(2) 代码实现
@RequestMapping("/j4")
@ResponseBody //不会走视图解析器, 会直接返回一个字符串,配合@Controller,
public String json4() throws JsonProcessingException {
List<User> userList=new ArrayList<User>();
//创建一个对象
User user1 = new User("李维平1",34,"男");
User user2 = new User("李维平2",33,"男");
User user3 = new User("李维平3",33,"男");
User user4 = new User("李维平4",34,"男");
userList.add(user1);
userList.add(user2);
userList.add(user3);
userList.add(user4);
System.out.println("******将Java对象转换为Json字符串*****");
String str1=JSON.toJSONString(userList);
System.out.println("JSON.toJSONString(list)===>"+str1);
String str2=JSON.toJSONString(user1);
System.out.println("JSON.toJSONString(user1)===>"+str2);
System.out.println("******将Json字符串转换为Java对象*****");
User jpUser=JSON.parseObject(str2,User.class);
System.out.println("JSON.parseObject(str2,User.class)===>"+jpUser);
System.out.println("******将Java对象转换为Json对象*****");
JSONObject jsonObject1=(JSONObject) JSON.toJSON(user2);
System.out.println("(JSONObject) JSON.toJSON(user2)===>"+jsonObject1.getString("name"));
System.out.println("******将Json对象转换为JJava对象*****");
User to_Java_Json=JSON.toJavaObject(jsonObject1,User.class);
System.out.println("SON.toJavaObject(jsonObject1,User.class)==>"+to_Java_Json);
return "hello";
}
六 、SSM整合
1. mybatis层
1.1 数据库准备
(1) 创建数据库
CREATE DATABASE `ssmbuild` CHARACTER SET utf8 COLLATE utf8_general_ci;
(2) 创建表
CREATE TABLE `ssmbuild`.`books`(
`bookID` INT(10) NOT NULL AUTO_INCREMENT COMMENT '书ID',
`bookName` VARCHAR(100) NOT NULL COMMENT '书名',
`bookCounts` INT(11) NOT NULL COMMENT '数量',
`detail` VARCHAR(200) NOT NULL COMMENT '描述', PRIMARY KEY (`bookid`) )
ENGINE=INNODB CHARSET=utf8 COLLATE=utf8_general_ci;
(3) 增加记录
INSERT INTO `ssmbuild`.`books` (`bookid`, `bookname`, `bookcounts`, `detail`) VALUES ('1', 'java', '1', '从入门到精通');
INSERT INTO `ssmbuild`.`books` (`bookid`, `bookname`, `bookcounts`, `detail`) VALUES (NULL, 'Mysql', '10', 'mysql操作手册');
INSERT INTO `ssmbuild`.`books` (`bookname`, `bookcounts`, `detail`) VALUES ('linux', '5', 'linux使用大全');
1.2 创建一个maven项目
(1) File——>new Project——>Maven——>grooupid com.sxsl,artifactid ssmbuild
(2) 截图
1.3 导入依赖包pom.xml:junit,数据库驱动,连接池,servlet,JSP,mybatis,mybatis-spring,spring
<!--依赖:junit,数据库驱动,连接池,servlet,JSP,mybatis,mybatis-spring,spring-->
<dependencies>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 连接池-->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<!--servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api Jsp -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl jstl-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.6</version>
</dependency>
<!--spring-->
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.3.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc --> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.9</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.9</version>
</dependency>
<!--lombok-->
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
<scope>provided</scope>
</dependency>
<!--aop依赖-->
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
</dependencies>
1.4 静态资源导出问题pom.xml
<!--静态资源导出问题-->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
1.5 创建基本的包架构:com.sxsl.pojo、controller、dao、service
1.6 创建mybatis的核心配置文件mybatis-config.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--configuration核心配置-->
<configuration>
<!--每一个mapper.xml文件都需要在Mybatis核心配置文件中注册-->
</configuration>
1.7 创建spring的核心配置文件applicationContext.xml,点击configure application context
<?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
https://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>
1.8 编写实体类Books.java
package com.sxsl.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Books {
private int bookID;
private String bookName;
private int bookCounts;
private String detail;
}
1.9 编写实体类的接口类BookMapper.java
package com.sxsl.dao;
import com.sxsl.pojo.Books;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface BookMapper {
//增加一本书
int addBook(Books books);
//删除一本书
int deleteBookById(@Param("bookID") int id);
//更新一本书
int updateBook(Books books);
//查询一本书
Books queryBookById(@Param("bookID") int id);
//查询所有书
List<Books> queryAllBook();
}
1.10 编写接口类对应的xml文件:UserMapper.xml(与接口类同目录)
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sxsl.dao.BookMapper">
<insert id="addBook" parameterType="Books">
insert into ssmbuild.books (bookName, bookCounts, detail) values (#{bookName},#{bookCounts},#{detail});
</insert>
<delete id="deleteBookById" parameterType="int">
DELETE FROM ssmbuild.books where bookID=#{bookID};
</delete>
<update id="updateBook" parameterType="Books">
UPDATE ssmbuild.books SET bookName=#{bookName},bookCounts=#{bookCounts},detail=#{detail}
where bookID=#{bookID};
</update>
<select id="queryBookById" resultType="Books">
select * from ssmbuild.books where bookID=#{bookID};
</select>
<select id="queryAllBook" resultType="Books">
select * from ssmbuild.books;
</select>
</mapper>
1.11 注册XXXmapper.xml:mybatis-config.xml
<!--每一个mapper.xml文件都需要在Mybatis核心配置文件中注册-->
<mappers>
<mapper class="com.sxsl.dao.BookMapper"/>
</mappers>
1.12 编写业务层的接口类UserService.java
package com.sxsl.service;
import com.sxsl.pojo.Books;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface BookService {
//增加一本书
int addBook(Books books);
//删除一本书,业务层不需要@Param("bookID"),
int deleteBookById( int id);
//更新一本书
int updateBook(Books books);
//查询一本书
Books queryBookById( int id);
//查询所有书
List<Books> queryAllBook();
}
1.13 编写业务层的实现类BookServiceImpl.java
package com.sxsl.service;
import com.sxsl.dao.BookMapper;
import com.sxsl.pojo.Books;
import java.util.List;
public class BookServiceImpl implements BookService {
//业务层到DAO层,组合DAO层,将DAO层的对象申明为业务层类的一个私有属性
private BookMapper bookMapper;
//首先来个set方法,这样spring就可以托管它
public void setBookMapper(BookMapper bookMapper) {
this.bookMapper = bookMapper;
}
public int addBook(Books books) {
return bookMapper.addBook(books);
}
public int deleteBookById(int id) {
return bookMapper.deleteBookById(id);
}
public int updateBook(Books books) {
return bookMapper.updateBook(books);
}
public Books queryBookById(int id) {
return bookMapper.queryBookById(id);
}
public List<Books> queryAllBook() {
return bookMapper.queryAllBook();
}
}
1.14 mybatis小结
1、建立数据库和表——>编写POJO类——>DAO层接口(BookMapper.java)及BookMapper.xml文件——>业务层接口(BookService.java)及其实现类(BookServiceImpl.java)。
2、mybatis的核心配置文件mybatis-config.xml,主要配置别名及注册mapper(DAO类),数据库连接交给spring容器管理。
3、mybatis通过业务层BookServiceImpl.java调用dao层(BookMapper.java),只需将BookMapper对象申明为BookServiceImpl的一个私有属性即可,同时通过setBookMapper方法完成spring托管BookMapper。
4、编写数据库连接文件database.properties,配置数据库连接信息;注意:如果使用的mysql8.0+,则增加一个时区的配置&serverTimezone=GMT%2B8。
2. spring层
2.1 spring整合dao层,编写spring-dao.xml配置文件
(1) 关联数据库连接配置文件
(2) 配置连接池
(3) 配置SQLSessionFactory
(4) 配置dao接口扫描包,动态实现了dao接口注册到spring容器中
(5) spring-dao.xml内容
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--1、关联数据库连接配置文件-->
<context:property-placeholder location="classpath:database.properties"/>
<!--2、配置连接池
dbcp:半自动化操作,不能自动连接
c3p0:自动化操作(自动化加载配置文件,并且可以自动化设置到对象中)
druid:
hikari:
-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!--c3p0连接池私有属性-->
<property name="maxPoolSize" value="30"/>
<property name="minPoolSize" value="10"/>
<!--关闭连接后不自动commit-->
<property name="autoCommitOnClose" value="false"/>
<!--获取连接超时时间-->
<property name="checkoutTimeout" value="10000"/>
<!--连接失败重试次数-->
<property name="acquireRetryAttempts" value="2"/>
</bean>
<!--3、配置SQLSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--绑定mybatis的配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<!--4、配置dao接口扫描包,动态实现了dao接口注册到spring容器中-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--注入sqlSessionFactory-->
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<!--要扫描的dao包-->
<property name="basePackage" value="com.sxsl.dao"/>
</bean>
</beans>
2.2 spring整合service层,编写spring-service.xml配置文件
(1) 步骤:扫描service下的包——>将我们所有的业务类注入到spring,可以通过配置或注解来实现——>申明式事务配置——>aop事务支持
(2) spring-service.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--1、扫描service下的包-->
<context:component-scan base-package="com.sxsl.service"/>
<!--2、将我们所有的业务类注入到spring,可以通过配置或注解来实现-->
<bean id="BookServiceImpl" class="com.sxsl.service.BookServiceImpl">
<property name="bookMapper" value="com.sxsl.dao.BookMapper"/>
<!--<property name="bookMapper" ref="bookMapper"/>-->
</bean>
<!--3、申明式事务配置-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!--注入数据源-->
<property name="dataSource" ref="dataSource"/>
</bean>
<!--4、aop事务支持-->
</beans>
2.3 将spring-dao.xml、spring-service.xml引入applicationContext.xml中。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--导入spring-dao.xml和spring-service.xml-->
<import resource="classpath:spring-dao.xml"/>
<import resource="classpath:spring-service.xml"/>
</beans>
2.4 spring层小结
(1) spring整合dao层步骤:关联数据库——>配连接池—— >注册SqlSessionFactory——>扫描dao包,动态实现dao接口注入到spring容器中。
(2) spring与mybatis的整合在“注册SqlSessionFactory”这一步。
<!--3、配置SQLSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--绑定mybatis的配置文件,实现spring与mybatis的整合-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
(3) spring整合service层:扫描service下的包——>将service下的类注册到spring容器中,对象作为私有属性时,使用property指定。
(4) 配置事务:DataSourceTransactionManager,如果要用到横切事务还要配置AOP相关选项并导入依赖包;同时要注入数据源。
(5) 在spring-service.xml中:错误
不报错
<bean id="BookServiceImpl" class="com.sxsl.service.BookServiceImpl">
<property name="bookMapper" value="com.sxsl.dao.BookMapper"/>
<!--<property name="bookMapper" ref="bookMapper"/>-->
</bean>
报错:
<bean id="BookServiceImpl" class="com.sxsl.service.BookServiceImpl">
<!--<property name="bookMapper" value="com.sxsl.dao.BookMapper"/>-->
<property name="bookMapper" ref="bookMapper"/>
</bean>
3. springmvc层
3.1 增加web项目:在ssmbuild项目名上按右键,点击add framework support
3.2 配置web.xml文件中的DispatchServlet、乱码过滤器、session-timeout(失效时间),启动优先级load-on-startup
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--DispatchServlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--乱码过滤-->
<!--配置SpringMVC的乱码过滤-->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<!--<url-pattern>/*</url-pattern>,要用/*包含.jsp文件,(/)否则执行请求-->
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<session-config>
<session-timeout>15</session-timeout>
</session-config>
</web-app>
3.3 spring-mvc.xml
(1) 步骤:注解驱动——>静态资源过滤——>扫描包: controller——>视图解析器
(2) spring-mvc.xml内容
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
https://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
<!--1、注解驱动-->
<mvc:annotation-driven/>
<!--2、静态资源过滤-->
<mvc:default-servlet-handler/>
<!--3、扫描包:Controller-->
<context:component-scan base-package="com.sxsl.controller"/>
<!--4、视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WRB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
3.4 将spring-mvc.xml导入applicationContext.xml中
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--导入spring-dao.xml、spring-mvc.xml和spring-service.xml-->
<import resource="classpath:spring-dao.xml"/>
<import resource="classpath:spring-service.xml"/>
<import resource="classpath:spring-mvc.xml"/>
</beans>
3.5 springmvc小结
(1) 在web.xml中配置DispatchServlet、乱码过滤器、session-timeout(失效时间),启动优先级load-on-startup。
(2) 在spring-mvc.xml中配置:注解驱动、静态资源过滤、扫描包:Controller、视图解析器。
(3) 将spring-mvc.xml导入项目主配置文件applicationContext.xml中
4 数据的展现:Controller与JSP页面的交互
4.1 查询数据功能
4.1.1 编写Controller类:BookController.java
import org.springframework.web.bind.annotation.RequestMapping;
import java.util.List;
@Controller
@RequestMapping("/book")
public class BookController {
//Controller层调service层
@Autowired
@Qualifier("BookServiceImpl")
private BookService bookService ;
//查询全部书籍并返回一个书籍展示页面
@RequestMapping("/allbook")
public String list(Model model){
List<Books> list = bookService.queryAllBook();
model.addAttribute("list",list);
return "allbook";
}
}
4.1.2 bean不存在一般排除步骤
(1) 在project setting中Artifacts下WEB-INF下添加lib目录,导入所有依赖的包。
(2) 查看bean(BookServiceImpl)是否注入成功,点击下图图标,能跳转到spring-mvc.xml文件,证明注册成功。
(3) junit单元测试,看编写的代码是否查询出结果:MyTest.java
import com.sxsl.pojo.Books;
import com.sxsl.service.BookService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;
public class MyTest {
@Test
public void test(){
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
BookService bookServiceImpl = context.getBean("BookServiceImpl", BookService.class);
List<Books> list = bookServiceImpl.queryAllBook();
for (Books books : list) {
System.out.println(books);
}
}
}
(4) 检查applicationContext.xml中是否引入spring-service.xml的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--导入spring-dao.xml、spring-mvc.xml和spring-service.xml-->
<import resource="classpath:spring-dao.xml"/>
<import resource="classpath:spring-service.xml"/>
<import resource="classpath:spring-mvc.xml"/>
</beans>
(5) 检查web.xml文件配置所绑定的配置文件是否为项目的总配置文件
原内容:classpath:spring-mvc.xml
<!--DispatchServlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.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>
修改后内容:classpath:applicationContext.xml,没有加载spring-dao.xml
和spring-service.xml中的bean。
<!--DispatchServlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
4.1.3 修改index.jsp页面,具体查询所有书籍的连接
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>首页</title>
<style>
a{
text-decoration: none;
color: black;
font-size: 18px;
}
h3{
width: 180px;
height: 30px;
margin: 100px auto;
text-align: center;
line-height: 38px;
background-color: deepskyblue;
border-radius: 5px;
}
</style>
</head>
<body>
<h3>
<a href="${pageContext.request.contextPath}/book/allbook" >进入书籍页面</a>
</h3>
</body>
</html>
4.1.4 编写查询结果展示页面allbook.jsp,引入了BootStrap前端框架美化网页
(1) allbook.jsp内容
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>书籍展示</title>
<%--BootStrap美化网页--%>
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<h1>书籍展示</h1>
<div class="container">
<div class="row clearfix">
<div class="col-md-12" column>
<div class="page-header">
<h1>
<small>书籍列表——————显示所有书籍</small>
</h1>
</div>
</div>
</div>
<div class="row clearfix">
<div class="col-md-12" column>
<table class="table table-hover table-striped">
<thead>
<tr>
<th>书籍编号</th>
<th>书籍名称</th>
<th>书籍数量</th>
<th>书籍描述</th>
</tr>
</thead>
<%--书籍从数据库中查询出来,存放于list--%>
<tbody>
<c:forEach var="book" items="${list}">
<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>
(2) BootStrap在线引用
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
(3) BootStrap中文网站:https://v3.bootcss.com/
4.2 增加书籍功能
4.2.1 在BookController.java 中增加两个方法
(1) 跳转到增加书籍页面
//跳转到增加书籍页面
@RequestMapping("/toAddBook")
public String toAddPaper(){
return "addbook";
}
(2) 添加书籍的请求,重定向@RequestMapping(“/allbook”)请求,相当于再次触发查询所有书籍.
//添加书籍的请求
@RequestMapping("/addBook")
public String addBook(Books books){
System.out.println("addBooks==>"+books);
bookService.addBook(books);
return "redirect:/book/allbook";//重定向@RequestMapping("/allbook")请求
}
4.2.2 在allbook.jsp页面中增加"新增书籍"书籍按钮
<div class="row">
<div class="col-md-4" column>
<a class="btn btn-primary" href="${pageContext.request.contextPath}/book/toAddBook">新增书籍</a>
</div>
</div>
4.2.3 编写新增书籍(addbook.jsp)页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<%--BootStrap美化网页--%>
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="col-md-12" column>
<div class="page-header">
<h1>
<small>新增书籍</small>
</h1>
</div>
</div>
</div>
<form action="${pageContext.request.contextPath}/book/addBook" method="post">
<div class="form-group">
<label >书籍名称</label>
<input type="text" name="bookName" class="form-control" required>
</div>
<div class="form-group">
<label >书籍数量</label>
<input type="text" name="bookCounts" class="form-control" required >
</div>
<div class="form-group">
<label >书籍描述</label>
<input type="text" name="detail" class="form-control" required >
</div>
<div class="form-group">
<input type="submit" class="form-control" value="添加" >
</div>
</form>
</div>
</body>
</html>
4.3 修改和删除书籍功能
4.3.1 在BookController.java 中方法,修改两个,删除1个
//跳转到修改页面toUpdatePaper
@RequestMapping("/toUpdateBook")
public String toUpdatepaper(int id,Model model){
Books books = bookService.queryBookById(id);
model.addAttribute("Qbooks",books);
return "toupdatebook";
}
//修改书籍内容
@RequestMapping("/updateBook")
public String updateBook(Books books){
System.out.println("updateBook==>"+books);
bookService.updateBook(books);
System.out.println("updateBooked==>"+books);
return "redirect:/book/allbook";//重定向@RequestMapping("/allbook")请求
}
//删除书籍信息
@RequestMapping("/deleteBook/{bookID}")
public String deleteBook(@PathVariable("bookID") int id){
bookService.deleteBookById(id);
return "redirect:/book/allbook";//重定向@RequestMapping("/allbook")请求
}
4.3.2 修改allbook.jsp页面,增加修改|删除连接
<td>
<a href="${pageContext.request.contextPath}/book/toUpdateBook?id=${book.bookID}" >修改</a>
|
<a href="${pageContext.request.contextPath}/book/deleteBook/${book.bookID}" >删除</a>
</td>
4.3.4 增加一个修改书籍页面toupdatebook.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>修改书籍</title>
< <%--BootStrap美化网页--%>
<link href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container">
<div class="row clearfix">
<div class="col-md-12" column>
<div class="page-header">
<h1>
<small>修改书籍</small>
</h1>
</div>
</div>
</div>
<form action="${pageContext.request.contextPath}/book/updateBook" method="post">
<%--出现的问题是我们提交了sql,但修改失败,初次判断是事务未提交,配置事务完毕仍失败。--%>
<%--看一下sql语句,能否执行成功,SQl执行失败,修改不成功--%>
<%--前端传递隐藏域--%>
<input type="hidden" name="bookID" value="${Qbooks.bookID}"/>
<div class="form-group">
<label >书籍名称</label>
<input type="text" name="bookName" class="form-control" value="${Qbooks.bookName}" required>
</div>
<div class="form-group">
<label >书籍数量</label>
<input type="text" name="bookCounts" class="form-control" value="${Qbooks.bookCounts}" required >
</div>
<div class="form-group">
<label >书籍描述</label>
<input type="text" name="detail" class="form-control" value="${Qbooks.detail}" required >
</div>
<div class="form-group">
<input type="submit" class="form-control" value="修改" >
</div>
</form>
</div>
</body>
</html>
4.3.5 小结
- 框架层mybatis、spring、SpringMVC这三层架构搭建完毕后,后面的业务只需在Controller类中增加方法(方法上指定访问路径)及JSP页面即可。
- aop注册方式有三种
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://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/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--注册bean-->
<bean id="userService" class="com.sxsl.service.UserServiceImpl"/>
<bean id="log" class="com.sxsl.log.Log"/>
<bean id="afterLog" class="com.sxsl.log.AfterLog"/>
<!--配置aop,需要导入aop的约束-->
<!--方式一:使用原声Spring API接口-->
<aop:config>
<!--切入点:表达式execution(要执行的位置)-->
<aop:pointcut id="pointcut" expression="execution(* com.sxsl.service.UserServiceImpl.*(..))"/>
<!--执行环绕增加!!-->
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config>
<!--方式二:自定义类-->
<bean id="div" class="com.sxsl.div.DivPointCut"/>
<aop:config >
<!--自定义切片,ref要引用的类-->
<aop:aspect ref="div" >
<!--切入点-->
<aop:pointcut id="point" expression="execution(* com.sxsl.service.UserServiceImpl.*(..))"/>
<!--通知-->
<aop:before method="before" pointcut-ref="point"/>
<aop:after method="after" pointcut-ref="point"/>
</aop:aspect>
</aop:config>
<!--方式三:使用注解-->
<bean id="annotationPointCut" class="com.sxsl.div.AnnotationPointCut"/>
<!--开启注解支持 jdk(expose-proxy="false"),cglib(expose-proxy="true")-->
<aop:aspectj-autoproxy expose-proxy="false"/>
七、Ajax
1. Ajax简介
(1) Ajax即Asynchronous Javascript And XML(异步JavaScript和XML)在 2005年被Jesse James Garrett提出的新术语,用来描述一种使用现有技术集合的‘新’方法,包括: HTML 或 XHTML, CSS, JavaScript, DOM, XML, XSLT, 以及最重要的XMLHttpRequest。
(2) 使用Ajax技术网页应用能够快速地将增量更新呈现在用户界面上,而不需要重载(刷新)整个页面,这使得程序能够更快地回应用户的操作。
(3) Ajax这个术语源自描述从基于 Web 的应用到基于数据的应用。
(4) Ajax 不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的Web应用程序的技术。
(5) 使用Ajax的最大优点,就是能在不更新整个页面的前提下维护数据。这使得Web应用程序更为迅捷地回应用户动作,并避免了在网络上发送那些没有改变的信息。
(6) 进行Ajax开发时,网络延迟——即用户发出请求到服务器发出响应之间的间隔——需要慎重考虑。如果不给予用户明确的回应,没有恰当的预读数据,或者对XMLHttpRequest的不恰当处理,都会使用户感到厌烦。通常的解决方案是,使用一个可视化的组件来告诉用户系统正在进行后台操作并且正在读取数据和内容。
2. SpringMVC框架下Ajax实现步骤
2.1 下载jquery-3.6.0.js,放在web/static/js/目录下
2.2 配置web.xml,配置DispatcherServlet、springmvc的项目陪着文件.
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--注册DispatcherServlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--乱码,配置SpringMVC的乱码过滤-->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<!--<url-pattern>/*</url-pattern>,要用/*包含.jsp文件,(/)否则执行请求-->
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
2.3 配置SpringMVC的项目配置文件:applicationContext.xml,扫描包、静态资源过滤、注册驱动、视图解析器。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--自动扫描包,让指定包下的注解生效,由IOC容器统一管理-->
<context:component-scan base-package="com.sxsl.controller"/>
<!--静态资源过滤-->
<mvc:default-servlet-handler/>
<!--注解驱动-->
<mvc:annotation-driven/>
<!--视图解析器:DispatcherServlet给它的ModelAndView-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
</beans>
2.4 导入与SpringMVC相关的依赖包pom.xml
父pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sxsl</groupId>
<artifactId>SpringMVC</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>spring-01-servlet</module>
<module>spring-02-hellomvc</module>
<module>spring-03-annonation</module>
<module>lwp</module>
<module>spring-04-controller</module>
<module>spring-05-json</module>
<module>spring-o6-ajax</module>
</modules>
<!--导入依赖包-->
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.8</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
</project>
子pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>SpringMVC</artifactId>
<groupId>com.sxsl</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-o6-ajax</artifactId>
<!--静态资源过滤-->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
2.5 编写后端处理程序AjaxController.java
package com.sxsl.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@RestController
public class AjaxController {
@RequestMapping("/t1")
public String test(){
return "hello";
}
@RequestMapping("/a1")
public void a1(String name, HttpServletResponse response) throws IOException {
System.out.println("a1:param==>"+name);
if("lwp".equals(name)){
response.getWriter().print("haha");
}else {
response.getWriter().print("hehe");
}
}
}
2.6 前端处理程序:index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
<script src="${pageContext.request.contextPath}/static/js/jquery-3.6.0.js"></script>
<script>
function a() {
$.post({
url:"${pageContext.request.contextPath}/a1",
data:{"name":$("#username").val()},
success:function (data) {
document.getElementById("username").value=data;
}
})
}
</script>
</head>
<body>
<%--失去焦点的时候,发起一个请求到后台--%>
用户名:<input type="text" id="username" onblur="a()">
</body>
</html>
2.7 小结
(1) 框架方面与一般的SpringMVC项目一样,包括pom.xml、web.xml、applicationContext.xml文件内容。
(2) 后端主要功能:提供前端访问的路径;处理前端传递的数据(键值对方式,其中前端传递的键对应该方法的参数名,值为该参数的具体内容);将处理结果返回前端。
(3) 前端程序:通过鼠标或键盘事件触动一个jQuery函数,该函数以get或post方式访问后端提供的路径;并向后端以键值对方式传出数据;同susses或error(即访问成功或失败)编写回调函数,处理后端返回的数据,并在网页的指定位置显示。
(4) jquery.post()函数的主要参数:url(访问后台的路径)、data(向后台传递的数据)、success(成功时的回调函数)、error(失败时的回调函数)。
(5) 在前端jsp页面需要引入jQuery的文件。
<script src="${pageContext.request.contextPath}/static/js/jquery-3.6.0.js"></script>
七、拦截器
1、拦截器的概念
(1) java里的拦截器是动态拦截Action调用的对象,它提供了一种机制可以使开发者在一个Action执行的前后执行一段代码,也可以在一个Action 执行前阻止其执行,同时也提供了一种可以提取Action中可重用部分代码的方式。
(2) 在AOP中,拦截器用于在某个方法或者字段被访问之前,进行拦截 然后再之前或者之后加入某些操作。
2、拦截器的原理
(1) 大部分时候,拦截器方法都是通过代理的方式来调用的。
(2) Struts2的拦截器实现相对简单。当请求到达Struts2的ServletDispatcher时,Struts2 会查找配置文件,并根据配置实例化相对的拦截器对象,然后串成一个列表(List),最后一个一个的调用列表中的拦截器。
(3) Struts2的拦截器是可插拔的,拦截器是AOP的一个实现。
(4) Struts2拦截器栈就是将拦截器按一定的顺序连接成一条链。在访问被拦截的方法或者字段时,Struts2拦截器链中的拦截器就会按照之前定义的顺序进行调用。
3、自定义拦截器的步骤
第一步:自定义一个实现了Interceptor接口的类,或者继承抽象类AbstractInterceptor。
第二步:在配置文件中注册定义的拦截器。
第三步:在需要使用Action中引用上述定义的拦截器,为了方便也可以将拦截器定义为默认的拦截器,这样在不加特殊说明的情况下,所有的 Action都被这个拦截器拦截。
4、过滤器与拦截器的区别
过滤器可以简单的理解为“取你所想取”,过滤器关注的是web请求;拦截器可以简单的理解为“拒你所想拒”,拦截器关注的是方法调用,比如拦截敏感词汇。
4.1 拦截器是基于java反射机制来实现的,而过滤器是基于函数回调来实现的。(有人说,拦截器是基于动态代理来实现的)
4.2 拦截器不依赖servlet容器,过滤器依赖于servlet容器。
4.3 拦截器只对Action起作用,过滤器可以对所有请求起作用。
4.4 拦截器可以访问Action上下文和值栈中的对象,过滤器不能。
4.5 在Action的生命周期中,拦截器可以多次调用,而过滤器只能在容器初始化时调用一次。
5. 一个完整的登录用户才能跳转到首页拦截器实现
5.1 web.xml 这里的内容针对web容器,及tomcat有效;过滤器在此配置。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!--注册DispatcherServlet-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--关联一个SpringMVC的配置文件:[servlet-name]-servlet.xml-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<!--启动级别 1-->
<load-on-startup>1</load-on-startup>
</servlet>
<!--/ 匹配所有请求,不包括(*.jsp)-->
<!--/* 匹配所有请求,包括(*.jsp)-->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--配置SpringMVC的乱码过滤-->
<filter>
<filter-name>encoding</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<!--<url-pattern>/*</url-pattern>,要用/*包含.jsp文件,(/)否则执行请求-->
<filter-mapping>
<filter-name>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
5.2 applicationContext,spring配置文件,这里的内容针对spring有效;拦截器在此配置。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--自动扫描包,让指定包下的注解生效,由IOC容器统一管理-->
<context:component-scan base-package="com.sxsl.controller"/>
<!--静态资源过滤-->
<mvc:default-servlet-handler/>
<!--json乱码问题解决-->
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<constructor-arg value="utf-8"/>
</bean>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="objectMapper">
<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
<property name="failOnEmptyBeans" value="false"/>
</bean>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!--注解驱动-->
<mvc:annotation-driven/>
<!--视图解析器:DispatcherServlet给它的ModelAndView-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<!--前缀-->
<property name="prefix" value="/WEB-INF/jsp/"/>
<!--后缀-->
<property name="suffix" value=".jsp"/>
</bean>
<!--拦截器配置-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.sxsl.config.MyInterceptor"/>
</mvc:interceptor>
<mvc:interceptor>
<mvc:mapping path="/user/**"/>
<bean class="com.sxsl.config.LoginInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
5.3 编写拦截器代码LoginInterceptor
package com.sxsl.config;
import org.springframework.lang.Nullable;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class LoginInterceptor implements HandlerInterceptor{
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
//判断什么情况下登录
//登录页面也要放行
if(request.getRequestURI().contains("goLogin")){
return true;
}
if(request.getRequestURI().contains("login")){
return true;
}
if (session.getAttribute("userLoginInfo")!=null){
return true;
}
//判断什么情况下没有登录
request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
return false;
}
}
5.4 编写Controller类
package com.sxsl.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpSession;
@Controller
@RequestMapping("/user")
public class LoginController {
@RequestMapping("/main")
public String main(){
return "main";
}
@RequestMapping("/goLogin")
public String goLogin(){
return "login";
}
@RequestMapping("/login")
public String login(HttpSession session,String username, String password,Model model){
//把用户的信息存在session中
System.out.println("login===>已经执行");
session.setAttribute("userLoginInfo",username);
model.addAttribute("username",username);
return "main";
}
@RequestMapping("/goOut")
public String goOut(HttpSession session){
session.removeAttribute("userLoginInfo");
return "main";
}
}
5.5 几个jsp页面
(1) index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<h1>
<a href="${pageContext.request.contextPath}/user/goLogin">登录页面</a>
<a href="${pageContext.request.contextPath}/user/main">首页</a>
</h1>
</body>
</html>
(2) /WEB-INF/jsp/main.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>首页</h1>
<span>
${username}
</span>
<p><a href="${pageContext.request.contextPath}/user/goOut">注销</a></p>
</body>
</html>
(3) /WEB-INF/jsp/login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>登录页面</h1>
<%--在web-inf下的资源只能通过Controller或servlet访问--%>
<form action="${pageContext.request.contextPath}/user/login" method="post">
用户名:<input type="text" name="username"/>
密 码:<input type="text" name="password"/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
八、总结图