maven
maven核心概念:依赖传递
依赖传递
依赖范围的实际应用,就是控制jar包的使用范围,哪些依赖范围会发生传递关系呢,可以通过下面实验验证:
1. projectA依赖junit,依赖范围是test,projectB依赖projectA,问: projectB对junit是否有依赖?
没有
2. projectA依赖junit,依赖范围是compile,projectB依赖projectA,问: projectB对junit是否有依赖?
有
3. projectA依赖junit,依赖范围是provided,projectB依赖projectA,问: projectB对junit是否有依赖?
没有
4. projectA依赖junit,依赖范围是runtime,projectB依赖projectA,问: projectB对junit是否有依赖?
有
哪些依赖范围会发生依赖传递,通过测试得到验证: compile、runtime。
maven核心概念:依赖 B 可选依赖、依赖冲突、依赖排除
可选依赖
<?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>xxx.xxx</groupId>
<artifactId>projectA</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<!--
optional可选依赖
false 默认值,表示会发生依赖传递。别人依赖了当前项目,可以使用junit。
true 不会发生依赖传递,也就是只能当前项目可以使用junit。
应用场景:
如果对一些jar的依赖只能当前项目使用,不允许发生依赖传递,可以通过可选依赖解决。
-->
<optional>true</optional>
</dependency>
</dependencies>
</project>
依赖冲突
说明:
1、如果2个直接依赖:依赖了同一个坐标不同版本的资源,以配置顺序下方为主。
2、如果2个间接依赖:依赖了同一个坐标不同版本的资源,以配置顺序上方为主。
3、如果1个直接依赖与1个间接依赖:依赖了同一个坐标不同版本的资源,以直接依赖为主。
简述:
2个直,下
1直1间,直
2个间,上
<?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>xxx.xxx</groupId>
<artifactId>projectB</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>xxx.xxx</groupId>
<artifactId>projectA</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!--1. 两个直接依赖,依赖了同一个坐标不同版本的资源,以配置顺序的下方为主。
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
-->
<!--2. 一个直接依赖,一个间接依赖,依赖了同一个坐标不同版本的资源,最终以直接依赖为主。-->
<!--间接依赖log4j-1.2.17.jar-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<!--3. 两个间接依赖,依赖了同一个坐标不同版本的资源,以配置顺序的上方为主。-->
<!--间接依赖spring-core-5.0.2.jar-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!--间接依赖spring-core-5.1.8.jar-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
</dependencies>
</project>
依赖排除
第一步:添加依赖包
第二步:添加依赖排除
目前配置:
<!--3. 两个间接依赖,依赖了同一个坐标不同版本的资源,以配置顺序的上方为主。-->
<!--间接依赖spring-core-5.0.2.jar-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
</dependency>
<!--间接依赖spring-core-5.1.8.jar-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
需求:
1. spring-core要使用5.1.8 版本?
2. 通过依赖排除解决。
实现:
<!--3. 两个间接依赖,依赖了同一个坐标不同版本的资源,以配置顺序的上方为主。-->
<!--间接依赖spring-core-5.0.2.jar-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.2.RELEASE</version>
<!--依赖排除:排除对某个包的间接依赖-->
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--间接依赖spring-core-5.1.8.jar-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
maven核心概念:分模块创建项目一继承与聚合
分模块创建项目
Maven多模块项目,适用于一些比较大的项目,通过合理的模块拆分,实现代码的复用,便于维护和管理。尤其是一些开源框架,也是采用多模块的方式,提供插件集成,用户可以根据需要配置指定的模块。
传统分包与分模块对比
传统分包与分模块 对比图:
通过对比,分模块创建项目的好处有:
- 项目架构一目了然
- 分模块创建项目,更易于团队开发维护,提升项目扩展性、可维护性。更可以快速构建项目。
什么是继承与聚合
- 继承
实际项目中,可能正要构建一个大型的系统,但又不想一遍又一遍的重复同样的依赖元素,这种情况是经常出现的。不过还好,maven提供了继承机制,项目可以通过parent元素使用继承,可以避免这种重复。当一个项目声明一个parent的时候,它从父项目的POM中继承信息。它也可以覆盖父POM中的值,或者添加一些新的值。
Maven的继承特性可以将各个模块相同的依赖和插件配置提取出来,在简化POM的同时还可以促进各个模块配置的一致性。
继承:
- 抽取所有项目公用的配置,子项目继承父项目,可以直接使用父项目公用的配置
- 继承作用: 消除重复配置。
- 父项目不写任何一行代码,以及除了pom.xml以外的任何配置。
- 聚合
聚合就是将一个工程拆分为多个模块。
Maven的聚合特性可以帮助我们把项目的多个模块聚合在一起,使用一条命令进行构建,即一条命令实现构建多个项目;
聚合:
- 聚合:聚集合并,把多个子项目聚集合并为一个项目,统一执行命令。
- 聚合作用: 快速构建运行项目(快速构建运行maven的命令)。
最佳实践
在一些最佳实践中我们会发现:一个POM既是聚合POM,又是父POM,这么做主要是为了方便。
maven核心概念:分模块创建项目二继承与聚合代码演示
实现步骤
- 说明
- 第一步:创建父项目 project
父项目中不会写任何一行java代码与除了pom.xml以外的其他配置,所以src目录可以保留,也可以删除
- 第二步: 创建子项目project_domain
步骤1:新建module, 选择聚合项目与父项目
步骤2:最后,观察父项目
观察子项目:
maven核心概念:分模块创建项目三父项目版本锁定
如何实现版本锁定?
dependencyManagement
1、父项目的另外一个作用就是版本锁定
2、版本锁定是什么? 版本锁定就是在父项目中,统一维护项目使用的组件的版本。
<?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>xxx.xxx</groupId>
<artifactId>project</artifactId>
<!--
打包方式:
jar 普通项目
war 表示web项目
pom 表示一个父项目、或者聚合项目
-->
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<!--聚合项目,聚合的模块-->
<modules>
<module>project_domain</module>
<module>project_dao</module>
<module>project_service</module>
</modules>
<!--
dependencyManagement 版本锁定
1. 父项目通过版本锁定,统一控制组件的使用版本;
2. 一旦使用了版本锁定,子项目继承父项目,是没有继承父项目版本锁定的包的,
子项目要用这些包,还需要添加依赖,只是不用指定版本。
-->
<dependencyManagement>
<dependencies>
<!--父项目:抽取所有项目公用的配置-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
</dependencies>
</dependencyManagement>
<!--父项目:抽取公用配置 (这样,父项目既做了版本锁定,又抽取了公用配置)-->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
</dependencies>
</project>
私服(1)介绍
中央仓库的缺点
地址 —— 目前来说,http://repo1.maven.org/maven2/是真正的Maven中央仓库的地址,该地址内置在Maven的源码中,其它地址包括著名的ibiblio.org,都是镜像。
规模 —— 每周有超过来自250,000开发者的70,000,000次访问,2010年的总访问量很有可能超过4,000,000,000。中央仓库存储了超过200,000,000的构件。
索引 —— 中央仓库带有索引文件以方便用户对其进行搜索,完整的索引文件大小约为60M,索引每周更新一次。
黑名单 —— 如果某个IP地址恶意的下载中央仓库内容,例如全公司100台机器使用同一个IP反复下载,这个IP(甚至是IP段)会进入黑名单,因此稍有规模的使用Maven时,应该用Nexus架设私服。
垃圾内容 —— 由于各种历史原因,中央仓库里面确实存在很多垃圾内容,例如不完整的POM,错误的maven-metadata.xml,主要的责任是开源项目上传内容时不太小心,目前中央仓库正致力于更规范的流程以防止新的垃圾内容进入。
背后的公司 —— Maven的托管在Apache的,但中央仓库不是Apache的资源,中央仓库是由Sonatype出资维护的。
私服
1、什么是私服?
- 私服是远程仓库的1种 (搭建在局域网中)
- 私服的作用 (好处)
- 解决访问限制问题
- 即使不能上网也可以下载jar包
- 可以上传自己的jar包
2、私服的作用
图1:查找jar包的过程
图2:上传jar包到私服、从私服下载jar包
私服(2)安装
安装
一键安装:双击install-nexus.bat即完成安装!
再检查服务是否有启动!
1、nexus-2.12.0-01\conf\nexus.properties文件中可以查看访问路径
2、访问路径: http://localhost:8081/nexus
账号密码: admin/admin123
私服(3)上传项目到私服
准备
先配置仓库运行重复部署:
上传配置
项目上传到私服
第一步:settings.xml
<server>
<id>releases</id>
<username>admin</username>
<password>admin123</password>
</server>
<server>
<id>snapshots</id>
<username>deployment</username>
<password>deployment123</password>
</server>
第二步:pom.xml
<distributionManagement>
<repository>
<id>releases</id>
<url>http://localhost:8081/nexus/content/repositories/releases/</url>
</repository>
<snapshotRepository>
<id>snapshots</id>
<url>http://localhost:8081/nexus/content/repositories/snapshots/</url>
</snapshotRepository>
</distributionManagement>
上传:执行deploy部署命令
查看上传结果:
私服(4)私服下载项目、配置阿里云远程仓库
私服下载资源配置
<!-- 远程仓库配置 -->
<mirror>
<!-- ID(唯一) -->
<id>nexus</id>
<!-- 名称 -->
<name>nexus</name>
<!-- 远程仓库的地址 -->
<url>http://127.0.0.1:8081/nexus/content/groups/public/</url>
<!-- 拦截指定仓库的请求 -->
<!-- lib/maven-model-builder-3.6.0.jar/org/apache\maven\model -->
<mirrorOf>central</mirrorOf>
</mirror>
配置阿里云(在自己开发测试时候推荐使用)
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>central</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
分模块构建ssm项目(1)分析
分析
为什么web需要依赖service? 因为在controller中要调用service,所以要依赖。
分模块构建ssm项目(2)父项目、聚合项目
环境准备
准备数据库环境:
创建父项目
图1:创建项目
图2:添加依赖
<?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>xxx.xxx</groupId>
<artifactId>ssm_parent</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--Spring相关依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.8.RELEASE</version>
</dependency>
<!--MyBatis依赖包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.2</version>
</dependency>
<!--数据库驱动包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!--测试、lombok、日志包、jstl、servlet包-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
</dependencies>
</project>
分模块构建ssm项目(3)实体类子模块
作用
实体类: 封装数据。
- 封装表数据
- 封装业务数据
创建工程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RgjvBKAB-1639032576082)(assets/image-20200813115727942.png)]
@Data
public class User {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
// 用户的部门
private Dept dept;
}
@Data
public class Dept {
private Integer id;
private String name;
}
分模块构建ssm项目(4)持久化子模块
步骤
- 创建ssm_dao项目
- 添加依赖: ssm_domain
- 编写dao接口
实现
-
创建ssm_dao项目
-
添加依赖: ssm_domain
<dependencies> <dependency> <groupId>xxx.xxx</groupId> <artifactId>ssm_domain</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>
-
编写dao接口
public interface UserDao { @Select("SELECT u.*,d.name FROM USER u INNER JOIN dept d ON u.dept_id=d.id") @Results({ @Result(column = "id",property = "id"), @Result(column = "username",property = "username"), @Result(column = "birthday",property = "birthday"), @Result(column = "sex",property = "sex"), @Result(column = "address",property = "address"), @Result(column = "dept_id",property = "dept.id"), @Result(column = "name",property = "dept.name"), }) List<User> findAll(); }
分模块构建ssm项目(5)业务逻辑子模块
步骤
- 创建项目:ssm_service
- 添加依赖:ssm_dao
- 编写service接口
- 编写service接口实现
实现
-
创建项目:ssm_service
-
添加依赖:ssm_dao
<dependencies> <dependency> <groupId>xxx.xxx</groupId> <artifactId>ssm_dao</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>
-
编写service接口
public interface UserService { List<User> findAll(); }
-
编写service接口实现
@Service @Transactional //声明式事务的注解实现 public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; @Override public List<User> findAll() { return userDao.findAll(); } }
分模块构建ssm项目(6)表现层子模块
步骤
- 创建项目:ssm_web
- 添加依赖: ssm_service
- 配置web.xml
- applicationContext.xml
- springmvc.xml
- 编写控制器
- 页面显示
- 启动测试
预览
实现
-
创建项目:ssm_web
-
添加依赖: ssm_service
<dependencies> <dependency> <groupId>xxx.xxx</groupId> <artifactId>ssm_service</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>
-
配置web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> <!--Spring提供了一个ServletContext监听器,用来在项目启动时候时候加载spring配置文件--> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <!--springmvc的解决中文乱码的编码过滤器--> <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> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!--配置SpringMVC前端控制器,拦截springmvc的请求--> <servlet> <servlet-name>dispatcherServlet</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcherServlet</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
-
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns: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/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!--1. 开启注解扫描, 注意:这里要扫描到service包,而在springmvc.xml中扫描web包,各司其职互不干扰--> <context:component-scan base-package="xxx.xxx.sevice"/> <!--2. 加载配置文件--> <context:property-placeholder location="classpath:jdbc.properties"/> <!--3. 创建连接池--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <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> <!--4. Spring整合MyBatis配置(1)把SqlSessionFactory对象的创建交给spring容器--> <bean class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> </bean> <!--5.Spring整合MyBatis配置(2) 映射扫描配置 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!--A. 自动加载指定目录下的映射文件 (支持xml中编写sql语句)--> <!--B. 自动加载指定包下的所有的接口文件 (支持注解开发)--> <!--C. 自动对指定包下的所有接口生成代理对象,加入容器(所以,service中可以注入容器中的dao的代理)--> <property name="basePackage" value="xxx.xxx.dao"/> </bean> <!--6. Spring声明式事务配置--> <!--6.1 事务管理器--> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!--6.2 开启事务注解--> <tx:annotation-driven transaction-manager="txManager"/> </beans>
-
springmvc.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!--1. 注解扫描,扫描web包--> <context:component-scan base-package="xxx.xxx.web"/> <!--2. 配置视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/pages/"/> <property name="suffix" value=".jsp"/> </bean> <!--3. 开启springmvc注解驱动--> <mvc:annotation-driven/> <!--4. 放行静态资源的访问(因为web.xml拦截的请求路径是/)--> <mvc:default-servlet-handler/> </beans>
-
编写控制器
@Controller @RequestMapping("/user") public class UserController { // 注入service @Autowired private UserService userService; @RequestMapping("/list") public String list(Model model){ List<User> list = userService.findAll(); model.addAttribute("list",list); return "list"; } }
-
页面显示
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <table> <tr> <th>序号</th> <th>用户编号</th> <th>用户名称</th> <th>性别</th> <th>地址</th> <th>生日</th> <th>所属部门</th> </tr> <c:forEach var="u" items="${list}" varStatus="vs"> <tr> <td>${vs.count}</td> <td>${u.id}</td> <td>${u.username}</td> <td>${u.sex}</td> <td>${u.address}</td> <td> <fmt:formatDate value="${u.birthday}" pattern="yyyy-MM-dd"/> </td> <td>${u.dept.name}</td> </tr> </c:forEach> </table> </body> </html>
-
启动测试
部署ssm_web项目: