最近接觸了 Java 開(kāi)發(fā),相比 Android 開(kāi)發(fā),技術(shù)棧的差異還是蠻大的,許多新的知識(shí)需要學(xué)習(xí),這里記錄一下開(kāi)發(fā)環(huán)境的搭建過(guò)程,對(duì)于新手來(lái)說(shuō)這個(gè)過(guò)程可能并不會(huì)太容易,開(kāi)發(fā)工具自然是 IntelliJ IDEA,畢竟和 Android Studio 的體驗(yàn)類似,個(gè)人感覺(jué)比 eclipse 更好用。
一、創(chuàng)建 Maven web 項(xiàng)目
首先創(chuàng)建基于 Maven 的 web 項(xiàng)目,以方便后續(xù)的項(xiàng)目管理,然后再整合 SSM 框架。由于 IntelliJ IDEA 已經(jīng)集成了 Maven 插件,可以不用額外安裝,創(chuàng)建 Maven web 項(xiàng)目基本的步驟如下:
1、選擇 maven-archetype-webapp

2、GroupId 可以按照包名的規(guī)則填寫(xiě),ArtifactId 可以填寫(xiě)項(xiàng)目名稱

3、選擇 Maven 路徑

4、確定最終的項(xiàng)目名稱及路徑等信息

5、上一步 Finish 后就開(kāi)始 Maven web 項(xiàng)目構(gòu)建了,注意右下角會(huì)有如下提示,選擇 Enable Auto-Import 即可,構(gòu)建可能要一小段時(shí)間,不妨起來(lái)活動(dòng)下身體。

6、構(gòu)建成功后的項(xiàng)目結(jié)構(gòu)如下,這里需要再手動(dòng)完善下目錄結(jié)構(gòu),在 main 下創(chuàng)建 java、resources目錄(按需創(chuàng)建即可)

7、為了創(chuàng)建的目錄更好的被編譯器識(shí)別,打開(kāi) Project Structure 分別標(biāo)記先創(chuàng)建的目錄

8、Java web 項(xiàng)目要運(yùn)行自然需要一個(gè) web 容器,這里使用 Tomcat,要先安裝好,然后通過(guò) Edit Configurations 選項(xiàng)打開(kāi)如下頁(yè)面進(jìn)行配置

9、Tomcat 配置,給 Tomcat 取個(gè)名字,選擇已安裝的 Tomcat 版本,運(yùn)行 web 項(xiàng)目的瀏覽器,占用的端口號(hào)等

10、切換到 Deployment 標(biāo)簽

11、部署 Tomcat,還可以配置 Application context 即 web 項(xiàng)目的默認(rèn)訪問(wèn)路徑,這里先不配置,到這里 web 項(xiàng)目就可以運(yùn)行了

12、可點(diǎn)擊編譯器上邊的綠三角還運(yùn)行項(xiàng)目,不出意外的話可以看到如下頁(yè)面,這就成功的邁出了第一步。如果上一步配置了Application context,例如 /myjavaee,則通過(guò) http://localhost:8080/myjavaee 同樣可以訪問(wèn)到如下頁(yè)面。

一、整合 SSM 框架
上邊已經(jīng)成功的創(chuàng)建了 Maven web 項(xiàng)目,下面開(kāi)始整合 SSM 框架,即 Spring MVC + Spring + MyBatis,這里采用 xml 的配置方式,最終的目錄結(jié)構(gòu)如下,需要的文件自行創(chuàng)建。
1、首先在 pom.xml 中引入相關(guān)庫(kù)的 Maven 依賴,關(guān)鍵的部分如下:
<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>
<!--事務(wù)-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<!--Spring整合數(shù)據(jù)庫(kù)連接-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<!--web開(kāi)發(fā)-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!--web開(kāi)發(fā)的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>
<!--數(shù)據(jù)庫(kù)連接-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.15</version>
</dependency>
<!--數(shù)據(jù)庫(kù)連接池-->
<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默認(rèn)的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是比較關(guān)鍵的幾個(gè)配置文件
web.xml 作為 Web 應(yīng)用的核心配置文件,會(huì)加載其它兩個(gè):
<!--Spring IoC配置文件路徑-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<!--配置ContextLoaderListener用來(lái)初始化Spring IoC容器-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--配置DispatcherServlet-->
<!--注意:Spring MVC框架會(huì)根據(jù)servlet-name配置,找到/WEB-INF/dispatcher-servlet.xml作為配置文件載入Web工程中-->
<servlet>
<servlet-name>dispatcher</servlet-name>
<!--攔截用戶請(qǐng)求的前端控制器-->
<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>
<!--攔截所有請(qǐng)求-->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
dispatcher-servlet.xml 主要是 Spring MVC 相關(guān)的配置:
<!-- 使用注解驅(qū)動(dòng) Spring MVC -->
<mvc:annotation-driven/>
<!-- 掃描控制器包中的類 -->
<context:component-scan base-package="com.shh.myjavaee.controller"/>
<!-- 靜態(tài)資源處理
對(duì)進(jìn)入DispatcherServlet的URL進(jìn)行篩查,
如果發(fā)現(xiàn)是靜態(tài)資源的請(qǐng)求,就將該請(qǐng)求轉(zhuǎn)由Web應(yīng)用服務(wù)器默認(rèn)的Servlet處理,
如果不是靜態(tài)資源的請(qǐng)求,才由DispatcherServlet繼續(xù)處理-->
<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文件夾,且文件結(jié)尾為jsp的文件作為映射 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/" p:suffix=".jsp"/>
applicationContext.xml 主要進(jìn)行了 MyBatis 數(shù)據(jù)持久化相關(guān)Bean的配置,以及 Service Bean 的初始化:
<!--掃描service目錄下的類,并將對(duì)象存儲(chǔ)在IoC容器中-->
<context:component-scan base-package="com.shh.myjavaee.service"/>
<!--使用注解驅(qū)動(dòng)-->
<!--<context:annotation-config/>-->
<!--加載數(shù)據(jù)庫(kù)配置的屬性文件-->
<context:property-placeholder location="classpath:jdbc.properties" ignore-resource-not-found="true"/>
<!--配置數(shù)據(jù)庫(kù)連接池-->
<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}"/>
<!--連接池的最大數(shù)據(jù)庫(kù)連接數(shù) -->
<property name="maxActive" value="255"/>
<!--最大等待連接中的數(shù)量 -->
<property name="maxIdle" value="5"/>
<!--最大等待毫秒數(shù) -->
<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>
<!--采用自動(dòng)掃描方式創(chuàng)建 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>
<!--配置數(shù)據(jù)源事務(wù)管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--配置聲明式事物的注解驅(qū)動(dòng)-->
<tx:annotation-driven transaction-manager="transactionManager"/>
3、MyBatis 映射器
applicationContext.xml 中已經(jīng)完成了 MyBatis 的相關(guān)配置,這里將 RoleMapper.xml 映射器文件放到了 resources目錄下,和接口文件分開(kāi):
<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>
對(duì)應(yīng)的接口文件 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 注解會(huì)被 Spring 掃描以生成 Mapper 對(duì)象,即 RoleDao 對(duì)象,方便依賴注入。
使用 MyBatis 時(shí),我們有時(shí)候難以避免的在 xml 文件和接口文件之間切換跳轉(zhuǎn),查找對(duì)應(yīng)的關(guān)系,Free Mybatis 可以非常方便的幫我們完成這個(gè)工作,值得一試。
使用 MyBatis 時(shí),一般用 log4j 打印 sql 日志,但是需要提取 sql 并完成參數(shù)的填充還是一件麻煩事。沒(méi)關(guān)系,MyBatis log 框架就是專門干這個(gè)事的,值得擁有。
4、服務(wù)類
在 Spring MVC 中一般通過(guò)服務(wù)類來(lái)進(jìn)行具體的數(shù)據(jù)庫(kù)操作邏輯,然后在控制器中使用服務(wù)類。服務(wù)類一般通過(guò)接口模式實(shí)現(xiàn),方便擴(kuò)展:
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 注解,同樣會(huì)被 Spring 掃描生成 Bean 保存在 IoC 容器中,為后續(xù)的依賴注入準(zhǔn)備。同時(shí)用 @Autowired 注解實(shí)現(xiàn)了 roleDao 對(duì)象的注入。@Transactional 是 Spring 事務(wù)配置注解。
5、控制器
控制器是 Spring MVC 的核心,主要的功能是獲取請(qǐng)求參數(shù),根據(jù)參數(shù)處理業(yè)務(wù)邏輯,最后綁定模型和視圖并返回。我們編寫(xiě)的控制器類如下:
@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 注解標(biāo)注,之前已經(jīng)在 dispatcher-servlet.xml 中配置要掃描控制器類。同時(shí)還在類和方法上使用了 @RequestMapping 注解,用來(lái)指定 URI 對(duì)應(yīng)哪個(gè)請(qǐng)求處理方法。
6、視圖渲染
Spring MVC 默認(rèn)使用 JstlView 進(jìn)行視圖渲染,前邊控制器類的第一個(gè)方法里,通過(guò) mv.setViewName("role")設(shè)置了邏輯視圖名 role,根據(jù) dispatcher-servlet.xml 中視圖解析器的配置,會(huì)用 /WEB-INF/jsp/role.jsp文件去相應(yīng)對(duì)應(yīng)請(qǐng)求,通過(guò) mv.addObject("roles", roles) 添加了模型數(shù)據(jù)會(huì)傳遞到 jsp 中,用 EL 讀取。例如:${roles}
role.jsp 的內(nèi)容如下:
<%@ 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>編號(hào)</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>
就是顯示一個(gè) table。啟動(dòng) web 應(yīng)用,在瀏覽器輸入 http://localhost:8080/role/getRoles 就可以看到如下頁(yè)面:
返回 JSON 格式的數(shù)據(jù)也是比較常見(jiàn)的,在控制器類的第二個(gè)方法中使用了 @ResponseBody 注解,這樣會(huì)把返回的數(shù)據(jù)通過(guò) JSON視圖轉(zhuǎn)換成JSON格式的數(shù)據(jù),在瀏覽器輸入 http://localhost:8080/role/getRole/1 可以看到:
到這里,已經(jīng)完成了框架的整合,基本的流程已經(jīng)走通了,當(dāng)然這些只是基礎(chǔ)內(nèi)容,SSM 框架中還有更多的內(nèi)容值得我們?nèi)ド钊肓私狻?/p>
文中demo地址:https://github.com/SheHuan/MyJavaEE