Eclipse编写 SSM项目


项目说明

项目计划使用spring+springMVC+shiro+log4j2进行简单搭建,并完成增删改查目标,数据访问层采用
mybatishibernate两种方式分别与上述环境组合,适应不同的企业开发环境。


eclipse版本(4.6.3)

Eclipse Java EE IDE for Web Developers.
Version: Neon.3 Release (4.6.3)
Build id: 20170314-1500

eclipse版本

MySQL版本(5.7.17)

Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1552
Server version: 5.7.17-log MySQL Community Server (GPL)

mysql版本

JDK版本(1.8.0_111)

java version “1.8.0_111”
Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)

JDK版本

Maven版本(3.5.0)

Apache Maven 3.5.0 (ff8f5e7444045639af65f6095c62210b5713f426; 2017-04-04T03:39:06+08:00)
Maven home: D:\apache-maven-3.5.0\bin..
Java version: 1.8.0_111, vendor: Oracle Corporation
Java home: C:\Java\jdk1.8.0_111\jre
Default locale: zh_CN, platform encoding: GBK
OS name: “windows 10”, version: “10.0”, arch: “amd64”, family: “windows”

maven版本

用Maven创建项目注意事项

1、打开eclipse工程的Navigator视图,找到新建maven项目的.settings目录,修改如下:

  • 修改org.eclipse.jdt.core.prefs的版本为JDK版本
  • 修改org.eclipse.wst.common.project.facet.core.xml版本3.0
  • 添加maven项目必须的目录source folder:src/test/resources
  • java build path选项source下,四个文件夹要全
  • 修改src/test/resources的output folder为test-classes
  • 修改libraries的JRE为当前JDK版本
  • pom.xml添加javax.servlet-api(或者指定tomcat目录下的server runtime)

(大概就是新建maven项目所需要的流程)
修改完项目编译器版本,动态网站为最新的3.0版本,使用新特性,然后添加maven的四个默认文件
夹,在项目的java build path查看是否有默认的四个文件夹,缺少哪个就添加哪个。同时指定输出文件夹。
JRE版本一定要与JDK版本对应,不然会存在项目报错却找不到错误点的情况。
综上如此,项目基本不会报错了。


2、pom.xml添加jar包
项目必须的jar包如下。
pom文件

pom.xml如下

<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/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.wangjikai</groupId>
	<artifactId>ssm</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>

	<dependencies>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>4.3.9.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>1.0.18</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>4.3.11.Final</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>4.3.9.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.38</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
			<version>4.3.9.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.mongodb</groupId>
			<artifactId>mongo-java-driver</artifactId>
			<version>3.2.2</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-mongodb -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-mongodb</artifactId>
			<version>1.10.4.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
		<!-- log配置:Log4j2 + Slf4j -->
		<dependency>
		    <groupId>org.apache.logging.log4j</groupId>
		    <artifactId>log4j-api</artifactId>
		    <version>2.2</version>
		</dependency>
		<dependency>
		    <groupId>org.apache.logging.log4j</groupId>
		    <artifactId>log4j-core</artifactId>
		    <version>2.2</version>
		</dependency>
		<dependency> <!-- 桥接:告诉Slf4j使用Log4j2 -->
		    <groupId>org.apache.logging.log4j</groupId>
		    <artifactId>log4j-slf4j-impl</artifactId>
		    <version>2.2</version>
		</dependency>
		<dependency> <!-- 桥接:告诉commons logging使用Log4j2 -->
		    <groupId>org.apache.logging.log4j</groupId>
		    <artifactId>log4j-jcl</artifactId>
		    <version>2.2</version>
		</dependency>
		<!-- 单元测试包 -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.8.1</version>
		</dependency>
		<dependency>
			<groupId>taglibs</groupId>
			<artifactId>standard</artifactId>
			<version>1.1.2</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
		<dependency>
		    <groupId>javax.servlet.jsp</groupId>
		    <artifactId>javax.servlet.jsp-api</artifactId>
		    <version>2.3.1</version>
		    <scope>provided</scope>
		</dependency>
		
	</dependencies>

	<build>
		<finalName>ssm</finalName>
	</build>
</project>

3、Eclipse编码设置

Eclipse的所有项目编码:
Window->Preferences->General->Workspace->Text file encoding->UTF-8->Apply->OK
项目JSP文件的默认编码
Window->Preferences->Web->JSP Files->Encoding>ISO10646/Unicode(UTF-8)->Apply->OK


项目配置

1、首先是web.xml的配置,它是web项目最先执行的配置文件。

<?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_3_0.xsd"
         metadata-complete="true" version="3.0">
  <!-- 项目的基本描述 -->
  <display-name>Archetype Created Web Application</display-name>
  <description>spring项目</description>
  <!-- web项目最先扫描的两个节点之一,加载spring等配置文件 -->
  <context-param>
  	<param-name>contextConfigLocation</param-name>
  	<param-value>classpath:application-context.xml</param-value>
  </context-param>
  <!-- 保证hibernate懒加载不出现异常,service完成之后事务关闭session也会关闭,会出现session异常 -->  
  <filter>  
    <filter-name>openSession</filter-name>  
    <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>  
  </filter>  
  <filter-mapping>  
    <filter-name>openSession</filter-name>  
    <url-pattern>/*</url-pattern>  
  </filter-mapping> 
   <!-- 编码过滤器 -->
  <filter>
  	<filter-name>encodingFilter</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>forceEncoding</param-name>
  		<param-value>true</param-value>
  	</init-param>
  </filter>
  <filter-mapping>
  	<filter-name>encodingFilter</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
  <!-- springMVC 前端控制器 -->
  <servlet>
  	<servlet-name>spring_ssm</servlet-name>
  	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  	<init-param>
  		<param-name>contextConfigLocation</param-name>
  		<param-value>classpath:application-web.xml</param-value>
  	</init-param>
  	<load-on-startup>0</load-on-startup>
  </servlet>
  <servlet-mapping>
  	<servlet-name>spring_ssm</servlet-name>
  	<url-pattern>/</url-pattern>
  </servlet-mapping>
  <servlet>  
  	<servlet-name>DruidStatView</servlet-name>  
    <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>  
  </servlet>  
  <servlet-mapping>  
    <servlet-name>DruidStatView</servlet-name>  
    <url-pattern>/druid/*</url-pattern>  
  </servlet-mapping> 
  <!-- spring容器的监听器 -->
  <listener>
  	<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <!-- 404页面 -->
  <error-page>
  	<error-code>404</error-code>
  	<location>/errorPages/404error.html</location>
  </error-page>
  <!-- 500页面 -->
  <error-page>
  	<error-code>500</error-code>
  	<location>/errorPages/500error.html</location>
  </error-page>
  <!-- 空指针页面 -->
  <error-page>
  	<exception-type>java.lang.NullException</exception-type>
  	<location>/errorPages/nullParam.html</location>
  </error-page>
  <!-- session追踪方式 -->
  <session-config>
  	<tracking-mode>COOKIE</tracking-mode>
  </session-config>
</web-app>

2、spring配置文件,application-context.xml(ORM:hibernate)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:util="http://www.springframework.org/schema/util" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
	xmlns:cache="http://www.springframework.org/schema/cache"
	xsi:schemaLocation="http://www.springframework.org/schema/context  
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/beans  
       http://www.springframework.org/schema/beans/spring-beans.xsd  
       http://www.springframework.org/schema/tx  
       http://www.springframework.org/schema/tx/spring-tx.xsd  
       http://www.springframework.org/schema/jdbc  
       http://www.springframework.org/schema/jdbc/spring-jdbc.xsd  
       http://www.springframework.org/schema/cache  
       http://www.springframework.org/schema/cache/spring-cache.xsd  
       http://www.springframework.org/schema/aop  
       http://www.springframework.org/schema/aop/spring-aop.xsd  
       http://www.springframework.org/schema/util  
       http://www.springframework.org/schema/util/spring-util.xsd">
	<!-- spring扫描包,创建beans。但是去除controller的扫描,让springMVC扫描 -->
	<context:component-scan base-package="com">
		<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
	</context:component-scan>
	<!-- 引入mysql/mongo数据库参数文件,用户名密码等信息 -->
	<context:property-placeholder location="classpath:jdbc.properties" />
	<!-- 数据库连接池 -->
	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
		<!-- 数据库连接的基本属性 自动检测驱动 -->
		<property name="driverClassName" value="${jdbc.driverClassName}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		<!-- 配置监控统计拦截的filters,去掉后监控界面sql无法统计 -->
		<property name="filters" value="stat" />
		<!-- 配置初始化大小、最小、最大 -->
		<property name="initialSize" value="1" />
		<property name="minIdle" value="10" />
		<property name="maxActive" value="20" />
		<!-- 配置获取连接等待超时的时间 -->
		<property name="maxWait" value="60000" />
		<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
		<property name="timeBetweenEvictionRunsMillis" value="60000" />
		<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
		<property name="minEvictableIdleTimeMillis" value="300000" />
		<property name="validationQuery" value="SELECT 'x'" />
		<property name="testWhileIdle" value="true" />
		<property name="testOnBorrow" value="false" />
		<property name="testOnReturn" value="false" />
		<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
		<property name="poolPreparedStatements" value="true" />
		<property name="maxPoolPreparedStatementPerConnectionSize" value="20" />
	</bean>
	<!-- 整合spring与hibernate -->
	<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<!-- hibernate.cfg.xml配置信息 -->
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.format_sql">true</prop>
			</props>
		</property>
		<!-- 扫描包含pojo对象注解的包 -->
		<property name="packagesToScan">
			<list>
				<value>com.domain</value>
			</list>
		</property>
	</bean>
	<!-- 事务管理器,spring为hibernate适配的 -->
	<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory"></property>
	</bean>
	<!-- 事务的传播特性 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="save" propagation="REQUIRED" rollback-for="Exception"/>
            <tx:method name="*" propagation="REQUIRED" />
        </tx:attributes>
    </tx:advice>
    <!-- 哪些类的哪些方法参与事务 -->
    <aop:config expose-proxy="true">  
    	<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.service.*.*(..))" />
    </aop:config>
</beans>

3、springMVC配置文件,application-web.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:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/aop
		http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
		http://www.springframework.org/schema/tx
		http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
		http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context-3.0.xsd
		http://www.springframework.org/schema/mvc
		http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
		http://www.springframework.org/schema/util
		http://www.springframework.org/schema/util/spring-util-3.0.xsd">
	<!-- 配置静态页面不拦截策略 -->
	<mvc:resources location="/errorPages/" mapping="/errorPages/**" />
	<!-- 注册springMVC注解功能 -->
	<mvc:annotation-driven />
	<!-- 扫描com包下的包含controller注解的类,不使用默认的filter -->
	<context:component-scan base-package="com" use-default-filters="false">
		<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
	</context:component-scan>
	<!-- springMVC视图解析器 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/views/"></property>
		<property name="suffix" value=".jsp"></property>
	</bean>
	<!-- 全局异常配置 -->
	<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
		<property name="exceptionMappings">
			<props>
				<!-- 表示当抛出NumberFormatException的时候就返回名叫number的视图 -->
				<prop key="NumberFormatException">/errorPages/defaultError</prop>
				<prop key="NullPointerException">/errorPages/nullParam</prop>
			</props>
		</property>
		<!-- 表示当抛出异常但没有在exceptionMappings里面找到对应的异常时返回名叫exception的视图 -->
		<property name="defaultErrorView" value="exception" />
		<!-- 定义在发生异常时视图跟返回码的对应关系 -->
		<property name="statusCodes">
			<props>
				<!-- 表示在发生NumberFormatException时返回视图number,然后这里定义发生异常时视图number对应的HttpServletResponse的返回码是500 -->
				<prop key="/errorPages/defaultError">500</prop>
				<prop key="/errorPages/nullParam">405</prop>
			</props>
		</property>
		<!-- 表示在发生异常时默认的HttpServletResponse的返回码是多少,默认是200 -->
		<property name="defaultStatusCode" value="404" />
	</bean>
</beans>

4、log4j2配置文件,log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>

<Configuration status="WARN">
	<Appenders>
		<!-- 输出到控制台 -->
		<Console name="Console" target="SYSTEM_OUT">
			<!-- 拦截器,只允许debug的信息输出 -->
			<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
			<!-- 输出格式 -->
			<PatternLayout pattern="%d{HH:mm:ss.SSS}  %-5level %logger{36} - %msg%n" />
		</Console>
	</Appenders>
	<Loggers>
		<Root level="fatal">
			<AppenderRef ref="Console" />
		</Root>
		<!-- name为具体类所在的包名,所有在com包下的logger都会遵循此logger,additivity避免重复输出 -->
        <logger name="com" level="info" additivity="false">
            <AppenderRef ref="Console"/>
        </logger>
	</Loggers>
</Configuration>

5、数据库连接参数,jdbc.properties

useSSL=false 是mysql5.7要求使用更安全的验证方式的体现。

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/wjk?characterEncoding=utf8&useSSL=false
jdbc.username=root
jdbc.password=root


包结构

| – com
: | – controller(控制层)
: | – service(服务层)
: | – dao(数据访问层)
| – domain(领域对象)

代码编写

1、domain领域对象–pojo实体类

package com.domain;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "user")
public class User {
	@Id
	@Column(name = "id")
	@GeneratedValue(strategy = GenerationType.AUTO)
	private String id;
	
	@Column(name = "name")
	private String name;
	
	@Column(name = "age")
	private String age;
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getAge() {
		return age;
	}
	public void setAge(String age) {
		this.age = age;
	}
}

对应的数据库模型:

数据库

2、dao数据访问层

package com.dao;

import java.io.Serializable;
import java.util.List;
import javax.annotation.Resource;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Repository;
import com.domain.User;

@Repository
public class UserSaveDao implements Serializable{
	private static final long serialVersionUID = 1L;
	@Resource
	private SessionFactory sessionFactory;
	/**
	 *用户数据保存
	 */
	public void saveUserDao(User user){
		getSession().save(user);
	}
		
	/**
	 * 公共获取session方法
	 * @return
	 */
	public Session getSession(){
		return sessionFactory.getCurrentSession();
	}
}

3、service数据服务层

package com.service;

import java.util.List;

import javax.annotation.Resource;
import org.springframework.stereotype.Service;

import com.dao.MongoSearchDao;
import com.dao.UserSaveDao;
import com.domain.MongoUser;
import com.domain.User;

@Service
public class UserSaveService {
	@Resource
	private UserSaveDao userSaveDao;
	
	public void saveUserService(User user) {
		userSaveDao.saveUserDao(user);
	}
}

4、controller控制器层

package com.controller;

import javax.annotation.Resource;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import com.domain.MongoUser;
import com.domain.User;
import com.service.UserSaveService;

@Controller
public class UserSaveController {
	//日志
	private static Logger logger = LogManager.getLogger(UserSaveController.class.getName());
	@Resource
	private UserSaveService usersaveservice;
	@RequestMapping(value="/")
	public String aa(){
		logger.info("springMVC");
		return "index";
	}
	@RequestMapping(value="addUser")
	public String addUserPage(String name,String age) {
	    logger.info("info level");  
//		User user = new User();
//		user.setName(name);
//		user.setAge(age);
//		usersaveservice.saveUserService(user);
		return "addUser";
	}
	@RequestMapping(value="addUser",method=RequestMethod.POST)
	public String addUser(String add_name,String add_age) {
		User user = new User();
		user.setName(add_name);
		user.setAge(add_age);
		usersaveservice.saveUserService(user);
		return "index";
	}
}

5、前台addUser.jsp页面

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ page isELIgnored="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:set var="ctx" value="${pageContext.request.contextPath}" />

<!DOCTYPE>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>新增用户</title>
<script type="text/javascript">
	function addUser() {
		var form = document.forms[0];
		form.action = "${ctx}/addUser";
		form.method = "post";
		form.submit();
	}
</script>
</head>
<body>
<h2>请填写</h2>    
<form name="addUserForm">
	<a>name</a><input type="text" name="add_name"><br/>
	<a>age</a><input type="text" name="add_age"><br/>
	<input type="button" value="确定" onclick="addUser()">
</form>
</body>
</html>

项目大概结构就是这样的,随着业务的不断增加,基本上都是在此结构上增加的。配置文件的代码注释是目前已知的都加上了,方便他人查阅,同时自己做一个备忘。


文章作者: 王吉凯
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 王吉凯 !
 上一篇
Java-RandomAccess源码分析 Java-RandomAccess源码分析
标记接口,Marker interface,它们是一类没有定义任何接口方法的接口,表现为一个空接口没有接口方法意味着实现该接口的类无需实现任何接口方法,仅仅作为一种标记,以供其他方法判断作用就是当某个类实现这个接口后即拥有了这个接口的功能
2018-06-02 王吉凯
本篇 
Eclipse编写 SSM项目 Eclipse编写 SSM项目
2017-07-17 王吉凯
  目录