绝对路径和相对路径
- 绝对路径:带有协议名称、主机IP以及端口号的地址
- 相对地址:没有协议、主机IP以及端口号开头的地址,相对地址不能独立使用,必须有一个参考地址,通过
参考地址+相对地址
才能指定资源
对于前端
- 对于前端,如果地址不以
/
开头,如:1.html
,则该请求的相当于./1.html
,即向服务器请求当前访问目录下的1.html
资源
- 相当于相对路径
- 如当前访问的地址为
http://localhost:8080/springmvc/index.jsp
,1.html
相当于./1.html
,等于http://localhost:8080/springmvc/1.html
- 对于前端,如果地址以
/
开头,如:/1.html
,则该请求的相当于向服务器请求服务器根目录下的1.html
资源
- 相当于绝对路径
- 如当前访问的地址为
http://localhost:8080/springmvc/index.jsp
,/1.html
相当于http://localhost:8080/1.html
对于后端
- 对于后端,如果地址以
/
开头,则开头的/
相当于当前项目的 webapp 目录
- 相当于绝对路径
- 如当前服务器所在的地址为
http://localhost:8080/springmvc/list
,在服务器要进行请求转发到/1.html
,则转发的地址相当于http://localhost:8080/wabapp/1.html
- 项目部署之后 wabapp 目录就相当于项目的根目录,项目的根目录为 springmvc
@RequestMapping(value = {"/list"}) public ModelAndView list() { ModelAndView modelAndView = new ModelAndView(); modelAndView.setViewName("/1.html"); return modelAndView; }
- 对于后端,如果地址不以
/
开头,则相当于相对路径,相对当前所在目录下寻找资源,与./
效果相同
@RequestMapping(value = {"/list"}) public ModelAndView list() { ModelAndView modelAndView = new ModelAndView(); // 请求访问的地址(当前该方法对应的地址)http://localhost:8080/springmvc/list // 1.html <=> ./1.html // 当前所在目录为 http://localhost:8080/springmvc/ // 对于项目部署之后webapp项目就是项目的根目录 // 当前所在目录相当于 http://localhost:8080/webapp/ // 所以 http://localhost:8080/springmvc/./1.html // <=> http://localhost:8080/webapp/1.html modelAndView.setViewName("1.html"); return modelAndView; }
@RequestMapping(value = {"/list"}) public ModelAndView list() { ModelAndView modelAndView = new ModelAndView(); // static/html/hello.html <=> ./static/html/hello.html // http://localhost:8080/sprinmvc/list // <=> http://localhost:8080/webapp/static/html/hello.html modelAndView.setViewName("static/html/hello.html"); return modelAndView; }
@RequestMapping(value = {"/user/aaa/list"}) public ModelAndView list() { ModelAndView modelAndView = new ModelAndView(); // http://localhost:8080/springmvc/user/aaa/list // ../user.html 回退一层目录 // http://localhost:8080/springmvc/user/aaa/../user.html // <=> http://localhost:8080/springmvc/user/aaa/user.html // <=> http://localhost:8080/webapp/user/aaa/user.html modelAndView.setViewName("../user.html"); return modelAndView; }
项目路径访问
动态获取web项目名 HttpServletRequest.getContextPath()
<!-- ${pageContext.request.contextPath} 动态获取web项目名 --> <a href="${pageContext.request.contextPath}/static/html/hello.html"> ${pageContext.request.contextPath}/static/html/hello.html" </a>
base 标签设置 html 页面访问地址的基地址
- base 标签设置的是所有 html 页面访问地址的基地址
- 使用了base标签之后,html页面中没有以
/
开头的地址,都会以base标签中设置的地址为参考地址
<%-- Created by IntelliJ IDEA. User: cw Date: 2023-05-24 Time: 12:36 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <base href="http://localhost:8080/${pageContext.request.contextPath}/"> </head> <body> <h2>Hello World!</h2> <a href="1.html">跳转链接:1.html</a><br/> <a href="2.html">跳转链接:2.html</a><br/> <a href="./3.html">跳转链接:./3.html</a><br/> <a href="4.html">跳转链接:4.html</a><br/> <a href="static/html/hello.html"> static/html/hello.html" </a> </body> </html>
动态获取请求基地址
<% String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath() + "/"; %> // request.getScheme() 获取请求的协议 // request.getServerName() 获取服务器IP // request.getServerPort() 获取端口号 // request.getContextPath() 获取web项目名
SSM 整合
整合开发思路
- SSM:SpringMVC + Spring + MyBatis
- SpringMVC:视图层,界面层,负责接收请求,显示处理结果
- Spring:业务层,负责管理Service、Dao、工具类等对象
- MyBatis:持久层,负责数据库的访问
- 请求的处理过程:用户发起请求,由SpringMVC接收用户请求,调用Spring中的Service对象进行相应的业务处理,如果需要涉及数据库,则由Service调用MyBatis进行数据库数据访问,MyBatis将查询的数据交给Service进行业务处理,Service处理完成后将处理结果交给SpringMVC,最后由SpringMVC将结果返回给用户
- SSM也叫SSI,因为IBatis是MyBatis的前身
- 整合中有两个容器
- SpringMVC:负责管理Controller控制器对象
- Spring:负责管理Service、Dao、工具类等对象
- 我们进行整合,就需要将使用的对象交给合适的容器进行管理,Controller控制器对象和web相关的对象交给SpringMVC,Service、Dao、工具类等对象交给Spring
- Spring容器与SpringMVC容器之间,有已经确定好的关系,SpringMVC容器是Spring容器的子容器,子容器可以访问父容器,在子容器中的Controller可以访问父容器中的Service对象
- 所以我们不需要构建两个容器之间的关系,我们只需要将使用的对象放到相应的容器中即可
数据库准备
create database ssm; use ssm; create table t_student( id int primary key auto_increment, name varchar(30), age int );
创建项目
- 使用Maven骨架创建web项目
引入依赖
- 需要引入的依赖:SSM三个框架的依赖,MySQL驱动依赖,Druid连接池依赖,Jackson依赖,JSP依赖,Servlet依赖
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!-- servlet 依赖 --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!-- jsp依赖 --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>jsp-api</artifactId> <version>2.2.1-b03</version> <scope>provided</scope> </dependency> <!-- SpringMVC依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.5.RELEASE</version> </dependency> <!-- 事务相关的依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.2.5.RELEASE</version> </dependency> <!-- Spring 内置的JDBC框架 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.2.5.RELEASE</version> </dependency> <!-- Jackson 依赖 --> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.0</version> </dependency> <!-- Spring 整合 MyBatis 依赖 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.1</version> </dependency> <!-- MyBatis 依赖 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.1</version> </dependency> <!-- 数据库连接驱动依赖 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.30</version> </dependency> <!-- 德鲁伊连接池依赖 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.12</version> </dependency> </dependencies>
引入插件
<build> <resources> <!--配置打包构建时识别资源文件所在的目录,将资源文件一起打包--> <resource> <directory>src/main/java</directory><!--所在的目录--> <includes><!--包括目录下的.properties,.xml 文件都会扫描到--> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> <plugins> <!--编译插件--> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.1</version> <configuration> <!--源码和打包后使用的JDK都为8--> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build>
创建 resources 和 java 目录
创建配置文件
- 在resources目录下新建conf目录,用于存放配置文件
SpringMVC 配置文件
<?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"> <!-- springmvc 配置文件,用于声明 controller 和其他 web 相关的对象 --> </beans>
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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- spring 配置文件,创建Service、Dao等对象 --> </beans>
数据库属性配置文件
jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:3306/dbtest jdbc.username=root jdbc.password=123123
MyBatis 配置文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 指定别名 --> <typeAliases> <!-- 实体类的别名,指定包名,自动为包下的所有实体类取别名 --> <package name="cw.springmvc.study.pojo"/> </typeAliases> <mappers> <!-- 指定SqlMapper文件所在的包,SqlMapper文件的文件名和所在的包必须和接口一样 --> <package name="cw.springmvc.study.dao"/> </mappers> </configuration>
配置文件 web.xml
配置注册 DispatchServlet
- 创建SpringMVC容器对象,读取SpringMVC配置文件,创建Controller对象
- 创建 DispatchServlet,接收用户请求
<!-- 注册中央调度器 --> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 配置 SpringMVC 配置文件 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:conf/dispatcherServlet.xml</param-value> </init-param> <!-- tomcat 启动时就创建该对象 --> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
配置注册 Spring 监听器 ContextLoaderListener
- 创建Spring容器对象,读取Spring配置文件,创建Service、Dao等对象
<!-- 注册 spring 监听器 --> <context-param> <param-name>contextConfigLocation</param-name> <!--spring配置文件--> <param-value>classpath:conf/applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
监听容器的创建等事件,SpringMVC容器为Spring容器的子容器,SpringMVC容器Spring容器创建会触发监听器读取Spring配置文件,创建Service、Dao对象放置Spring容器中
配置注册字符集过滤器
- 配置字符集过滤器,设置请求和响应数据的编码
- 解决POST请求乱码问题
<!-- 注册字符集过滤器 --> <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>forceRequestEncoding</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>forceResponseEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <!-- 所有请求都要经过该过滤器 --> <url-pattern>/*</url-pattern> </filter-mapping>
创建包 package
- controller
- service
- dao 或 mapper
- pojo 或 bean 或 domain
编写 SpringMVC 配置文件
controller 组件扫描器
<!-- controller 组件扫描器 --> <context:component-scan base-package="cw.springmvc.study.controller"/>
视图解析器
<!-- 内部资源视图解析器 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 前缀 --> <property name="prefix" value="/WEB-INF/jsp/"/> <!-- 后缀 --> <property name="suffix" value=".jsp"/> </bean>
注解驱动
<!-- 注解驱动 --> <!-- 1. 使处理方法的返回值响应给客户端,处理ajax请求 2. 解决静态资源与@RequestMapping冲突问题 --> <mvc:annotation-driven/>
编写 Spring 配置文件
- 整合之后,Dao相关类的对象放在Spring容器中管理,所以MyBatis数据库等相关配置写在Spring配置文件中
声明数据源
<!-- 从类根路径下加载连接数据库配置属性 --> <context:property-placeholder location="classpath:conf/jdbc.properties"/> <!-- 数据源 druid --> <!-- init-method 初始化方法;destroy-method 销毁方法 --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close" > <property name="driverClassName" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean>
配置 SqlSessionFactoryBean
- 使用MyBatis操作数据库需要通过SqlSessionFactory对象来获取与数据库之间的会话对象
- 配置SqlSessionFactoryBean,其实就是在进行MyBatis的相关配置
<!-- SqlSessionFactoryBean对象 --> <!-- 在spring容器中注册SqlSessionFactory对象 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 数据源 --> <property name="dataSource" ref="dataSource"/> <!-- MyBatis核心配置文件 --> <property name="configLocation" value="classpath:conf/mybatis-config.xml"/> </bean>
MyBatis 组件扫描器
<!-- 声明MyBatis的扫描器 --> <!-- 我们需要使用底层自动生成Mapper接口的代理类对象 声明MyBatis的Mapper扫描器,会自动扫描Mapper接口创建代理类对象 并放到Spring容器中 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- SqlSessionFactoryBean对象的id,使用SqlSessionFactoryBean对象是哪个 --> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> <!-- Mapper接口所在的包 --> <property name="basePackage" value="cw.springmvc.study.dao"/> </bean>
service 组件扫描器
<!-- service 组件扫描器 --> <context:component-scan base-package="cw.springmvc.study.service"/>
事务配置
<!-- 配置事务管理器 --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 数据源 --> <property name="dataSource" ref="dataSource"/> </bean> <!-- 开启事务的注解驱动 --> <tx:annotation-driven transaction-manager="txManager"/>
配置 <mvc:resources/>
标签处理中央调度器路径为 /
- 在 springmvc 配置文件中,配置
<mvc:resources/>
标签
<!-- 配置静态资源访问 --> <mvc:resources mapping="/static/**" location="/static/"/>
- 创建静态资源目录
程序代码
pojo
- 实体类:Student
package cw.springmvc.study.pojo; /** * ClassName: Student * Package: cw.springmvc.study.pojo * Description: * * @Author tcw * @Create 2023-05-28 15:54 * @Version 1.0 */ public class Student { private Integer id; private String name; private Integer age; public Student() { } public Student(Integer id, String name, Integer age) { this.id = id; this.name = name; this.age = age; } @Override public String toString() { return "Student{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}'; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }