使用 IntelliJ IDEA 搭建基于 Maven+SSM 的 Java Web 开发法框架

最近接触了 Java 开发,相比 Android 开发,技术栈的差异还是蛮大的,许多新的知识需要学习,这里记录一下开发环境的搭建过程,对于新手来说这个过程可能并不会太容易,开发工具自然是 IntelliJ IDEA,毕竟和 Android Studio 的体验类似,个人感觉比 eclipse 更好用。

一、创建 Maven web 项目

首先创建基于 Maven 的 web 项目,以方便后续的项目管理,然后再整合 SSM 框架。由于 IntelliJ IDEA 已经集成了 Maven 插件,可以不用额外安装,创建 Maven web 项目基本的步骤如下:

1、选择 maven-archetype-webapp

1

2、GroupId 可以按照包名的规则填写,ArtifactId 可以填写项目名称

2g

3、选择 Maven 路径

3

4、确定最终的项目名称及路径等信息

4

5、上一步 Finish 后就开始 Maven web 项目构建了,注意右下角会有如下提示,选择 Enable Auto-Import 即可,构建可能要一小段时间,不妨起来活动下身体。

5

6、构建成功后的项目结构如下,这里需要再手动完善下目录结构,在 main 下创建 java、resources目录(按需创建即可)

6

7、为了创建的目录更好的被编译器识别,打开 Project Structure 分别标记先创建的目录

7

8、Java web 项目要运行自然需要一个 web 容器,这里使用 Tomcat,要先安装好,然后通过 Edit Configurations 选项打开如下页面进行配置

8

9、Tomcat 配置,给 Tomcat 取个名字,选择已安装的 Tomcat 版本,运行 web 项目的浏览器,占用的端口号等

9

10、切换到 Deployment 标签

10

11、部署 Tomcat,还可以配置 Application context 即 web 项目的默认访问路径,这里先不配置,到这里 web 项目就可以运行了

11

12、可点击编译器上边的绿三角还运行项目,不出意外的话可以看到如下页面,这就成功的迈出了第一步。如果上一步配置了Application context,例如 /myjavaee,则通过 http://localhost:8080/myjavaee 同样可以访问到如下页面。

12

一、整合 SSM 框架

上边已经成功的创建了 Maven web 项目,下面开始整合 SSM 框架,即 Spring MVC + Spring + MyBatis,这里采用 xml 的配置方式,最终的目录结构如下,需要的文件自行创建。


13

1、首先在 pom.xml 中引入相关库的 Maven 依赖,关键的部分如下:

  <properties>
    <spring.version>4.3.23.RELEASE</spring.version>
  </properties>

  <dependencies>
    <!--Spring IoC、Bean装配-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!--事务-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!--Spring整合数据库连接-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!--web开发-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!--web开发的mvc支持-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <!--MyBatis持久化框架-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.1</version>
    </dependency>
    <!--MyBatis整合Spring的框架-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.3.2</version>
    </dependency>
     <!--日志-->
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.17</version>
    </dependency>
    <!--数据库连接-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.15</version>
    </dependency>
    <!--数据库连接池-->
    <dependency>
      <groupId>commons-dbcp</groupId>
      <artifactId>commons-dbcp</artifactId>
      <version>1.4</version>
    </dependency>
    <!--JSTL支持-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>4.0.1</version>
      <scope>provided</scope>
    </dependency>
    <!--Spring默认的JSON解析框架-->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.9.8</version>
    </dependency>
  </dependencies>

2、web.xml、dispatcher-servlet.xml、applicationContext.xml是比较关键的几个配置文件

web.xml 作为 Web 应用的核心配置文件,会加载其它两个:

  <!--Spring IoC配置文件路径-->
  <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>
  <!--配置DispatcherServlet-->
  <!--注意:Spring MVC框架会根据servlet-name配置,找到/WEB-INF/dispatcher-servlet.xml作为配置文件载入Web工程中-->
  <servlet>
    <servlet-name>dispatcher</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>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

dispatcher-servlet.xml 主要是 Spring MVC 相关的配置:

    <!-- 使用注解驱动 Spring MVC -->
    <mvc:annotation-driven/>
    <!-- 扫描控制器包中的类 -->
    <context:component-scan base-package="com.shh.myjavaee.controller"/>
    <!-- 静态资源处理
    对进入DispatcherServlet的URL进行筛查,
    如果发现是静态资源的请求,就将该请求转由Web应用服务器默认的Servlet处理,
    如果不是静态资源的请求,才由DispatcherServlet继续处理-->
    <mvc:default-servlet-handler/>
    <!--配置拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="com.shh.myjavaee.interceptor.CommonInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
    <!-- 定义视图解析器 -->
    <!-- 找到Web工程/WEB-INF/JSP文件夹,且文件结尾为jsp的文件作为映射 -->
    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          p:prefix="/WEB-INF/jsp/" p:suffix=".jsp"/>

applicationContext.xml 主要进行了 MyBatis 数据持久化相关Bean的配置,以及 Service Bean 的初始化:

    <!--扫描service目录下的类,并将对象存储在IoC容器中-->
    <context:component-scan base-package="com.shh.myjavaee.service"/>
    <!--使用注解驱动-->
    <!--<context:annotation-config/>-->
    <!--加载数据库配置的属性文件-->
    <context:property-placeholder location="classpath:jdbc.properties" ignore-resource-not-found="true"/>
    <!--配置数据库连接池-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${database.driver}"/>
        <property name="url" value="${database.url}"/>
        <property name="username" value="${database.username}"/>
        <property name="password" value="${database.password}"/>
        <!--连接池的最大数据库连接数 -->
        <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"/>
        <!--MyBatis配置文件-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!--MyBatis映射器目录-->
        <property name="mapperLocations" value="classpath:mapper/*Mapper.xml"/>
    </bean>
    <!--采用自动扫描方式创建 mapper bean-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--扫描的目录-->
        <property name="basePackage" value="com.shh.myjavaee.dao"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!--扫描使用了Repository注解的类-->
        <property name="annotationClass" value="org.springframework.stereotype.Repository"/>
    </bean>
    <!--配置数据源事务管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!--配置声明式事物的注解驱动-->
    <tx:annotation-driven transaction-manager="transactionManager"/>

3、MyBatis 映射器

applicationContext.xml 中已经完成了 MyBatis 的相关配置,这里将 RoleMapper.xml 映射器文件放到了 resources目录下,和接口文件分开:

<mapper namespace="com.shh.myjavaee.dao.RoleDao">
    <resultMap id="roleMap" type="role">
        <id property="id" column="id"/>
        <result property="roleName" column="role_name"/>
        <result property="note" column="note"/>
    </resultMap>

    <insert id="insertRole" parameterType="role" useGeneratedKeys="true" keyProperty="id">
        insert into t_role (role_name, note)
        values (#{roleName}, #{note})
    </insert>

    <select id="getRole" parameterType="long" resultMap="roleMap">
        select id, role_name, note
        from t_role
        where id = #{id}
    </select>

    <select id="getAllRole" resultMap="roleMap">
        select id, role_name, note
        from t_role
    </select>

    <update id="updateRole" parameterType="role">
        update t_role
        set role_name = #{roleName},
            note      = #{note}
        where id = #{id}
    </update>

    <delete id="deleteRole" parameterType="long">
        delete
        from t_role
        where id = #{id}
    </delete>
</mapper>

对应的接口文件 RoleDao 如下:

@Repository
public interface RoleDao {
    public int insertRole(Role role);
    public Role getRole(Long id);
    public List<Role> getAllRole();
    public  int deleteRole(Long id);
    public  int updateRole(Role role);
}

使用了 @Repository 注解会被 Spring 扫描以生成 Mapper 对象,即 RoleDao 对象,方便依赖注入。

使用 MyBatis 时,我们有时候难以避免的在 xml 文件和接口文件之间切换跳转,查找对应的关系,Free Mybatis 可以非常方便的帮我们完成这个工作,值得一试。

使用 MyBatis 时,一般用 log4j 打印 sql 日志,但是需要提取 sql 并完成参数的填充还是一件麻烦事。没关系,MyBatis log 框架就是专门干这个事的,值得拥有。

4、服务类

在 Spring MVC 中一般通过服务类来进行具体的数据库操作逻辑,然后在控制器中使用服务类。服务类一般通过接口模式实现,方便扩展:

public interface RoleService {
    public Role getRole(Long id);
    public List<Role> getAllRole();
}
@Service
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleDao roleDao = null;
    
    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
    public Role getRole(Long id) {
        return roleDao.getRole(id);
    }

    @Override
    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
    public List<Role> getAllRole() {
        return roleDao.getAllRole();
    }

}

使用了 @Service 注解,同样会被 Spring 扫描生成 Bean 保存在 IoC 容器中,为后续的依赖注入准备。同时用 @Autowired 注解实现了 roleDao 对象的注入。@Transactional 是 Spring 事务配置注解。

5、控制器

控制器是 Spring MVC 的核心,主要的功能是获取请求参数,根据参数处理业务逻辑,最后绑定模型和视图并返回。我们编写的控制器类如下:

@Controller
@RequestMapping("/role")
public class RoleController {
    @Autowired
    private RoleService roleService;

    @RequestMapping("/getRoles")
    public ModelAndView getRoles() {
        List<Role> roles = roleService.getAllRole();
        ModelAndView mv = new ModelAndView();
        mv.setViewName("role");
        mv.addObject("roles", roles);
        return mv;
    }

    @RequestMapping("/getRole/{id}")
    @ResponseBody
    public Object getRole(@PathVariable("id") long id) {
        Role role = roleService.getRole(id);
        return role;
    }
}

首先控制器类要用 @Controller 注解标注,之前已经在 dispatcher-servlet.xml 中配置要扫描控制器类。同时还在类和方法上使用了 @RequestMapping 注解,用来指定 URI 对应哪个请求处理方法。

6、视图渲染

Spring MVC 默认使用 JstlView 进行视图渲染,前边控制器类的第一个方法里,通过 mv.setViewName("role")设置了逻辑视图名 role,根据 dispatcher-servlet.xml 中视图解析器的配置,会用 /WEB-INF/jsp/role.jsp文件去相应对应请求,通过 mv.addObject("roles", roles) 添加了模型数据会传递到 jsp 中,用 EL 读取。例如:${roles}

role.jsp 的内容如下:

<%@ page pageEncoding="utf-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>角色信息</title>
</head>
<body>
<table border="1">
    <thead>
    <tr>
        <td>编号</td>
        <td>名称</td>
        <td>备注</td>
    </tr>
    </thead>
    <c:forEach items="${roles}" var="role">
        <tr>
            <td><c:out value="${role.id}"/></td>
            <td><c:out value="${role.roleName}"/></td>
            <td><c:out value="${role.note}"/></td>
        </tr>
    </c:forEach>
</table>
</body>
</html>

就是显示一个 table。启动 web 应用,在浏览器输入 http://localhost:8080/role/getRoles 就可以看到如下页面:

14

返回 JSON 格式的数据也是比较常见的,在控制器类的第二个方法中使用了 @ResponseBody 注解,这样会把返回的数据通过 JSON视图转换成JSON格式的数据,在浏览器输入 http://localhost:8080/role/getRole/1 可以看到:

15

到这里,已经完成了框架的整合,基本的流程已经走通了,当然这些只是基础内容,SSM 框架中还有更多的内容值得我们去深入了解。

文中demo地址:https://github.com/SheHuan/MyJavaEE

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容