第一部分记录课程中项目部署方式(通过Maven项目);
第二部分讲解SpringMVC项目执行流程和项目各部分的功能;
第三部分讲解直接使用老师提供的项目应当注意的环境问题;
一、项目内容
文档结构:
1.新建项目
(1) 新建Maven项目,勾选web项目:
(2) 在新建项目中的src包下添加main.java
(3) 删除SpringBoot项目管理:ctrl+Alt+shift+s --> Facts -->删除第一个Spring (后面改成mvc)
(4) 在Maven项目中选择add Framework Support,添加Spring SpringMVC
此时你会发现项目中在webapp包中新增了几个配置文件(web.xml, application.xml,dispatcher-servlet.xml),它们的功能后续讲解。
(5)配置tomcat:
详细的配置方式可以参考:
【SpringMVC】SpringMVC入门实例-CSDN博客
这个博客也对项目进行了实现(不过没有servlet)。
2.导入Maven依赖
在pom.xml中应该导入mybatis、web-servlet和mysql服务器等依赖:
3.设计思想(三层架构)
在完成这个项目前,应该了解这个系统的设计逻辑--三层架构思想:
(1) 表示层(Presentation Layer):
表示层是用户与系统交互的界面,负责接收用户输入和向用户展示数据。它包括用户界面、用户输入处理和展示逻辑。在Web应用中,通常是用户界面(前端)。
(2) 业务逻辑层(Business Logic Layer):
业务逻辑层是系统的核心,负责处理应用程序的业务逻辑。它包括了对数据的处理、业务规则的实现和系统的核心功能。这一层通常包含了服务、领域模型、业务服务等。
(3) 数据访问层(Data Access Layer):
数据访问层负责与数据存储(数据库、文件系统等)进行交互,执行数据的读取、存储和更新等操作。它隐藏了底层数据存储的细节,提供了对数据的抽象访问接口。在这一层通常包含了数据访问对象(DAO)、数据库操作等。
在接下来的文件详解中,你应该了解到它们属于哪个层级。
二、文件详解(按照执行顺序)
首先,我们先关注与WEB-INF这个文件夹。每个web请求都基于servlet,在运行tomcat服务器后它会自动读取WEB-INF包下的web.xml。而SpringMVC处理器本身是一个普通的方法,所以它要在web.xml文件中进行注册,然后才能被调用。(这个文件通常被命名为dispatcher-servlet.xml)
在项目中,负责mybatis功能实现的配置文件application.xml也是同理。
1.web.xml文件的配置
(1) 概念:
web.xml 是一个标准的Java EE部署描述符,用于配置Web应用程序的部署信息。它包含有关Servlet、Filter、Listener等的配置。
在Spring MVC中,web.xml 通常用于配置 DispatcherServlet,它是整个Spring MVC框架的入口,负责处理所有的HTTP请求并将其分发给相应的处理器(Controller)。
在 web.xml 中配置 DispatcherServlet 包括映射URL、加载上下文配置等(applicationContext就是上下文的配置)。
<?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">
<!-- web.xml文件主要完成两个配置:注册dispatcher和application
首先,我们知道,Tomcat启动时先读取这个文件(web.xml)
接下来,web.xml配置dispatcher-servlet.xml文件和application.xml文件
SpringMVC的处理器本身是一个普通的方法,所以dispatcher要在web.xml中注册后才能使用-->
<display-name>Archetype Created Web Application</display-name>
<!--设置项目启动的欢迎页面,即在虚拟路径下的页面-->
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<!--配置springmvc DispatcherServlet-->
<servlet>
<servlet-name>springMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!--配置dispatcher.xml作为mvc的配置文件-->
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>springMVC</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--把applicationContext.xml加入到配置文件中(上下文参数)-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/applicationContext.xml</param-value>
</context-param>
<!-- 配置ContextLoaderListener用以初始化Spring IoC容器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
(1) <welcome-file-list>: 设置浏览器的欢迎页面,根目录为webapp,所以这里直接写文件名即可。
(2) <servlet>: 配置你要绑定的xml文件,这里绑定的是springMVC的服务器配置文件dispatcher.xml, 在<init-param>中书写初始化的参数,para-value是你配置的xml文件的路径。
如果你没有设置<init-param>标签,则系统会默认读取WEB-INF中的名为dispatcher-sevlet.xml文件(注意:未设置时只会读取这个名称的文件)。
(3) <servlet-mapping>: 绑定过滤器,url-partten标签中的/表明它识别任何请求。
(4) <listener>: 监听器,参考:Listener(监听器)的简单介绍_<listener>-CSDN博客
(5) <context-param>:上下文配置。
2.dispatcher-servlet.xml的配置
dispatcher-servlet 是 Spring MVC 框架中的前端控制器(Front Controller)。这个配置文件定义了 Spring 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"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--此文件负责整个mvc中的配置-->
<!--启用spring的一些annotation -->
<context:annotation-config/>
<!-- 配置注解驱动 可以将request参数与绑定到controller参数上 -->
<mvc:annotation-driven/>
<!--静态资源映射-->
<!--本项目把静态资源放在了webapp的statics目录下,资源映射如下-->
<mvc:resources mapping="/css/**" location="/static/css/"/>
<mvc:resources mapping="/js/**" location="/static/js/"/>
<mvc:resources mapping="/image/**" location="/static/images/"/>
<mvc:default-servlet-handler />
<!-- 对模型视图名称的解析,即在模型视图名称添加前后缀(如果最后一个还是表示文件夹,则最后的斜杠不要漏了) 使用JSP-->
<!-- 默认的视图解析器 在上边的解析错误时使用 (默认使用html)- -->
<bean id="defaultViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/jsp/"/><!--设置JSP文件的目录位置-->
<property name="suffix" value=".jsp"/>
<property name="exposeContextBeansAsAttributes" value="true"/>
</bean>
<!-- 自动扫描装配,将会扫描controller包下所有的文件,找到带有@Controller注解的类-->
<context:component-scan base-package="com.test.controller"/>
<!-- 如果有配置数据库事务,需要开启注解事务的,需要开启这段代码 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
(下面是参考的流程图)SpringMVC的执行流程以及运行原理_springmvc执行流程-CSDN博客
如图DispatcherServlet部分,就是我们dispatcher-servket.xml实现的功能。
3.ApplicationContext.xml的配置
上下文参数(Context Parameters)是用于在Web应用程序的整个生命周期内共享配置信息的一种机制。它们是在web.xml文件中定义的全局参数,可以被整个Web应用程序访问。这些参数通常用于配置和定制Web应用程序的行为。
这个上下文参数(ApplicationContext.xml)主要用于集成mybatis框架。
<?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.test"/>
<!-- 使用注解驱动 -->
<context:annotation-config />
<!-- 数据库连接池 记得导包或引入依赖common.dbcp-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/chapter14" />
<property name="username" value="root" />
<property name="password" value="yourpassword" />
<property name="maxActive" value="255" />
<property name="maxIdle" value="5" />
<property name="maxWait" value="10000" />
</bean>
<!-- 集成mybatis -->
<bean id="SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:com/test/mybatis/mybatis-config.xml" />
</bean>
<!-- 配置数据源事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 采用自动扫描方式创建mapper bean -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="main.java.com.ssm.chapter14" />
<property name="SqlSessionFactory" ref="SqlSessionFactory" />
<property name="annotationClass" value="org.springframework.stereotype.Repository" />
</bean>
</beans>
4.mybatis核心配置文件
在刚才的上下文(ApplicationContext)中,我们集成了mybatis框架,接下来我们将配置Mybatis核心配置文件,在刚才的代码中,我们发现集成mybatis(设置mybatis的bean)时,引入了一个配置文件的地址: <property name="configLocation" value="classpath:com/test/mybatis/mybatis-config.xml" /> 。这是mybatis的核心配置文件,它标记出了所有与Dao层接口绑定的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>
<!--这个配置文件是mybatis的核心配置文件,绑定mapper中实现接口RoleDao功能的配置文件RoleMapper.xml-->
<!-- 指定映射器路径 -->
<mappers>
<mapper resource="com/test/mapper/RoleMapper.xml" />
</mappers>
</configuration>
5.实体类Role
(1)位置:
(2)代码:
package com.test.pojo;
/***
*这个类用于储存数据库中t_role表格的信息
*/
public class Role {
private long id;
private String roleName;
private String note;
public long getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
}
(3) 作用:使用mybatis查询数据库时,若要储存数据库返回的一行信息,则需要创建一个实体类,用其对象对返回的信息进行接收。该类的属性应该与数据库对应表格的列名保持一致。
6.业务逻辑层接口(RoleService)与其实现(RoleServiceImpl)
(1) 位置:
(2) 代码:
package com.test.service;
import com.test.pojo.Role;
public interface RoleService {
//通过id获取Role信息
public Role getRole(long id);
}
package com.test.service.impl;
import com.test.dao.RoleDao;
import com.test.pojo.Role;
import com.test.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
/***
* 首先,这个类实现接口RoleService提供的功能: getRole(int id),查询表中id为指定值的列信息
* 如果说RoleDao接口和RoleMapper.xml实现了对数据库的操作,那么RoleService接口和他的实现,就是将获取到的信息封装成Role对象
* 使其他类可以调用这个类(RoleServiceImpl)来指定(RoleDao提供的)方法(来操作数据库),并获取查询结果(Role对象)
*/
@Service
public class RoleServiceImpl implements RoleService {
//这里的roleDao对象进行初始化(无参构造),使用的是反射
//现在注入的是RoleDao对象(RoleDao被@Repository标记,自动创建bean)
@Qualifier("roleDao")
private RoleDao roleDao = null;
//这个方法调用了RoleDao中的同名方法,完成的就是RoleMapper.xml中实现的功能
//但是它能够将信息封装成Role对象,让其他类能够获取到这个信息
@Override
public Role getRole(long id){
return roleDao.getRole(id);
}
//在这个类中,还可以继续指定RoleDao中其他被实现的功能,在这里只提供了getRole方法
}
(3) 解析:
每个程序都应该根据它的接口来提供服务,所以我们现定义服务的接口RoleService,确定它所提供的功能,并对这些功能进行实现。
在实现类RoleService中,我们要实现getRole(long id)方法,这个方式是根据指定Id返回表中相关的Role信息。这个功能需要涉及对数据库的操作。
在这个方法中,可以发现我们注入了一个dao层的Bean RoleDao,调用它的功能实现查询。接下来我们就来定义这个Bean。
7.Dao层的接口与其实现
(1)概念:
DAO,全称为数据访问对象(Data Access Object),是一种设计模式,用于将数据存取逻辑和业务逻辑分离。DAO 的主要目的是提供一个抽象接口,使应用程序能够访问各种不同类型的数据存储,如关系数据库、文件系统或其他数据源,而不暴露底层细节。DAO 层通常被用于与数据库进行交互,负责处理数据的存取操作。这样,业务逻辑层可以专注于业务规则和处理,而不需要关心数据的存取细节。
(2)代码:
package com.test.dao;
import com.test.pojo.Role;
import org.springframework.stereotype.Repository;
@Repository
public interface RoleDao {
public Role getRole(long id);
}
<?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">
<!--namespace指定了它要实现的接口-RoleDao
它可以视为一个RoleDao接口的实现类-->
<mapper namespace="com.test.dao.RoleDao">
<!-- id属性:RoleDao接口中的方法;parameterType:方法中的参数类型;resultType:方法的返回值类型-->
<select id="getRole" parameterType="long" resultType="com.test.pojo.Role">
select id, role_name as roleName, note from t_role where id = #{id}
</select>
</mapper>
在这个项目中,xml文件与接口一一对应,它们之间的连接由mapper namespace进行绑定。除了<select>标签外,还根据增删改,有<insert>,<delete>等标签,它们的属性可以进一步了解。
8.表示层(RoleController)的实现:
(1)代码:
package com.test.controller;
import com.test.pojo.Role;
import com.test.service.RoleService;
import com.test.service.impl.RoleServiceImpl;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;
@Controller("RoleController")
@RequestMapping("/role")
public class RoleControl {
//注入roleService类,提供能够返回role值的方法@Qualifier
@Qualifier("RoleServiceImpl")
private RoleServiceImpl roleService = null;
@RequestMapping(value = "/getRole")
public ModelAndView getRole(){
//先通过调用roleService获得指定id的列的信息,储存在Role对象中
long id = 1L;
Role role = roleService.getRole(id);
//创建数据模型
ModelAndView mv = new ModelAndView();
//设置它将数据输出的目标(roleDetails.jsp,在WEB-INF的jsp包下,之前在dispatcher.xml中配置过)
mv.setViewName("roleDetails");
//为数据模型添加Role对象,使它获取到role中的信息
mv.addObject("role", role);
return mv;
}
@RequestMapping(value = "/getRole2", method = RequestMethod.GET)
public ModelAndView getRole2(@RequestAttribute("id") long id){
Role role = roleService.getRole(id);
ModelAndView mv = new ModelAndView();
mv.addObject("role", role);
// 指定视图类型
mv.setView(new MappingJackson2JsonView());
return mv;
}
}
(2) 解析:它的作用是,在收到用户的请求后(被重定向的请求),这些类通过调用业务逻辑层的bean进行处理,将处理结果与要返回的信息交给ModelAndView对象,再交给dispatchet传递给视图解析器进行解析。这样,用户发送的请求通过处理,就能够变成一个可视化的处理结果,完成服务的提供。
8.前端jsp页面的配置
如果要提交数据,应使用form表单。接收ModelAndView对象中信息的写法如下:
<%@ page pageEncoding="utf-8"%>
<%--使用这个标签应该在Maven中引入javax-servlet jstl依赖--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<title>out标签的使用</title>
</head>
<body>
</body>
<center>
<table border="1">
<tr>
<td>标签</td>
<td>值</td>
</tr>
<tr>
<td>角色编号</td>
<%--c:out 用于在JSP中显示数据
这里在浏览器页面中输出rolo.id, role.roleName, role.note三个属性
也可以使用thyteleaf来进行试图解析--%>
<td><c:out value="${role.id}"></c:out></td>
</tr>
<tr>
<td>角色名称</td>
<td><c:out value="${role.roleName}"></c:out></td>
</tr>
<tr>
<td>角色备注</td>
<td><c:out value="${role.note}"></c:out></td>
</tr>
</table>
</center>
</html>
三、总结
本次实验主要内容在于理解三层架构思想,并且较为核心的知识点是前端控制器dispatcher与上下文的配置。通过业务逻辑层,来结合mybatis等框架,完成前后端的交互工作,共同实现对用户请求的处理与响应。
参考博客:
【SpringMVC】| SpringMVC 入门_spring mvc 入门_@每天都要敲代码的博客-CSDN博客
Spring MVC系列(二)、Spring MVC应用及ModelAndView(模型视图)_springmvc的modelandview-CSDN博客