Maven 搭建 SSM 项目 (oracle)

简单谈一下maven搭建 ssm 项目 (使用数据库oracle,比 mysql 麻烦一点,所以这里谈一下)

并实现注册登录功能。

在创建maven 的web项目时,常常会缺了main/java , main/test 两个文件夹。

解决方法:

① : 在项目上右键选择properties,然后点击java build path,在Librarys下,编辑JRE System Library,选择workspace default jre就可以了。 (推荐使用这种)

② :手动创建 目录。切换视图采用Navigator视图,直接在src/main目录下建立 Java目录。

项目目录结构:

Maven 搭建 SSM 项目 (oracle)

在这普及一下 mvc 设计模式:

MVC 设计模式:单向

Maven 搭建 SSM 项目 (oracle)

mvc 概念:

MVC模式并不是javaweb项目中独有的,MVC是一种软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller),即为MVC。它是一种软件设计的典范

mvc 详解:

虽然MVC并不是Java当中独有的,但是现在几乎所有的B/S的架构都采用了 MVC 框架模式,但是 MVC 在B/S架构中并没有完全地实现,其实我们根本不需要掌握未实现的部分。

模型 Model:模型代表着一种企业规范,就是业务流程/状态的处理以及业务规则的规定。业务流程的处理过程对其他层来说是不透明的,模型接受视图数据的请求,并返回最终的处理结果。业务模型的设计可以说是MVC的核心。

视图 View:视图即是用户看到并与之交互的界面,比如HTML(静态资源),JSP(动态资源)等等。

控制器 Controller:控制器即是控制请求的处理逻辑,对请求进行处理,负责请 求转发;

MVC 模式被广泛用于 Java 的各种框架中,比如 Struts2、Spring MVC 等等都用到了这种思想

顺带讲一下 MVVM 设计模式:双向

Maven 搭建 SSM 项目 (oracle)

Model : 实体模型(biz/bean)

View : 布局文件(XML)

ViewModel : 对外暴露出公共属性,View和Model的绑定器

1.  可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多View重用这段视图逻辑。 在Android中,布局里可以进行一个视图逻辑,并且Model发生变化,View也随着发生变化。

2.  低耦合。以前Activity、Fragment中需要把数据填充到View,还要进行一些视图逻辑。现在这些都可在布局中完成,甚至都不需要再Activity、Fragment去findViewById()。这时候Activity、Fragment只需要做好的逻辑处理就可以了。

目录结构的解释:

Java web 经典三层架构:

控制层(表现层):controller层(Handler层):

  采用 MVC 模式。 model(模型) view(视图) Controller(控制)
  M称为模型,也就是实体类。用于数据的封装和数据的传输。 
  V为视图,也就是GUI组件,用于数据的展示。 
  C为控制,也就是事件,用于流程的控制。

  负责具体的业务模块流程的控制,

  • 在此层里面要调用Service层的接口来控制业务流程;
  • 控制的配置也同样是在Spring的配置文件里面进行,针对具体的业务流程,会有不同的控制器,我们具体的设计过程中可以将流程进行抽象归纳,设计出可以重复利用的子单元流程模块,这样不仅使程序结构变得清晰,也大大减少了代码量。

持久层(数据层):dao层(mapper):

  DAO层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此,

  • DAO层的设计首先是设计DAO的接口;
  • 然后在Spring的配置文件中定义此接口的实现类;
  • 然后就可在模块中调用此接口来进行数据业务的处理,而不用关心此接口的具体实现类是哪个类,显得结构非常清晰;
  • DAO层的数据源配置,以及有关数据库连接的参数都在Spring的配置文件中进行配置。

业务层:service层:

  Service层主要负责业务模块的逻辑应用设计。

  • 首先设计接口,再设计其实现的类
  • 接着再在Spring的配置文件中配置其实现的关联。这样我们就可以在应用中调用Service接口来进行业务处理。
  • Service层的业务实现,具体要调用到已定义的DAO层的接口,
  • 封装Service层的业务逻辑有利于通用的业务逻辑的独立性和重复利用性,程序显得非常简洁。

实体类:entity:

  每个对象作为一个实体类,一般设置很多的私有属性,并有相应的setter和getter方法。

  做相关数据表的映射

  对象属性的封装,体现了oo思想

核心包:core:包含模拟的核心类和接口类

工具包:util:包含所用到的一些工具类

重要的配置文件:

对象模型配置文件: pom.xml

Spring的配置文件:applicationContext.xml

spring MVC配置文件: springmvc.xml

数据库配置文件: jdbc.properties

日志配置文件: log4j.properties

mybatis配置文件: mybatis-config.xml

网络程序配置文件:web.xml

首先配置pom.xml

pom.xml 主要描述了项目的maven坐标,依赖关系,自动引入jar包

 <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.krry</groupId>
<artifactId>maven_SSM</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>maven_SSM</name>
<url>http://maven.apache.org</url> <dependencies>
<!--引入junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!--引入servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0-alpha-1</version>
<scope>provided</scope>
</dependency>
<!--引入jstl的包 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
<scope>provided</scope>
</dependency> <!--引入jsp的编译依赖 -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency> <!--引入log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency> <!--spring springmvc mybatis -->
<!-- spring和springmvc相关的构建 jar -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.1.RELEASE</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.2.1.RELEASE</version>
</dependency> <!-- springmvc相关 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.1.RELEASE</version>
</dependency> <!--springmvc需要用到json的转换包 jackson -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.5.4</version>
</dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.5.4</version>
</dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.5.4</version>
</dependency> <!--JSR303 后台校验 hibernate validator -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.1.Final</version>
</dependency> <!--上传文件相关的jar包 -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency> <dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency> <dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.3.2</version>
</dependency> <!--跟加密算法相关的codeC -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.9</version>
</dependency> <!--orm或者jdbc组件需要用到的jar包 mybatis -->
<!--oracle数据库驱动 -->
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>12.1.0.2.0</version>
</dependency>
<!--mysql数据库驱动 (这里不用,用的是上面的oracle驱动) -->
<!--
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.0.8</version>
<scope>runtime</scope>
</dependency>
--> <!-- proxool连接池 -->
<dependency>
<groupId>com.cloudhopper.proxool</groupId>
<artifactId>proxool</artifactId>
<version>0.9.1</version>
</dependency>
<dependency>
<groupId>com.cloudhopper.proxool</groupId>
<artifactId>proxool-cglib</artifactId>
<version>0.9.1</version>
</dependency> <!--引入mybatis需要的jar包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.1</version>
</dependency> <dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.4</version>
</dependency> <!-- 分页管理需要的jar包,这里没用到 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.2.1</version>
</dependency> </dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<version>3.0</version>
</configuration>
</plugin>
</plugins>
<finalName>maven_SSM</finalName>
</build>
</project>

这里说一下maven工程利用pom.xml导入oracle驱动包的问题:

由于Oracle授权问题,Maven不提供Oracle JDBC driver,为了在Maven项目中应用Oracle JDBC driver,必须手动添加到本地仓库。

如果电脑中已经装有Oracle数据库,则在安装路径下有数据库的驱动程序,可以直接用。D:\Oracle\oraclexe\app\oracle\product\10.2.0\server\jdbc\lib

也可以直接到Oracle官网上下载Oracle数据库驱动, 使用SQL语句查询数据库驱动的版本: SELECT * FROM v$instance

然后确定版本下载:http://www.oracle.com/technetwork/database/features/jdbc/default-2280470.html

打开windows的命令行界面,进入驱动包ojdbc6的目录,按住shift键后右键,从此处打开命令窗口,然后运行此命令:
mvn install:install-file -DgroupId=com.oracle -DartifactId=ojdbc6 -Dversion=12.1.0.2.0 -Dpackaging=jar -Dfile=ojdbc6.jar
显示"BUILD SUCCESS" 成功,就会自动导入你的maven本地仓库。

然后就可以在maven项目里添加dependency,各坐标对应上面这个命令的个元素,如下:

     <dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>12.1.0.2.0</version>
</dependency>

Spring的配置文件: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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.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/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd
"> <!-- 配置包扫描 -->
<context:component-scan base-package="com.krry"></context:component-scan> <!-- 导入外部资源文件 -->
<!-- <context:property-placeholder location="classpath:jdbc.properties" /> -->
<bean class="com.krry.core.des.EncryptPropertyPlaceholderConfigurer"
p:location="classpath:jdbc.properties" p:fileEncoding="utf-8" /> <!-- proxool连接池 -->
<bean id="dataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource">
<!-- 驱动的名字,mysql -->
<property name="driver" value="${db.driver}"></property>
<!--proxool 的 url连接串,这个必须确定用户名和密码 -->
<property name="driverUrl" value="${db.url}"></property>
<!-- 用户名(proxool没有使用,但是不能没有) -->
<property name="user" value="${db.username}"></property>
<!-- 密码(proxool没有使用,但是不能没有) -->
<property name="password" value="${db.password}"></property>
<!-- proxool自动侦察各个连接状态的时间间隔(毫秒),侦察到空闲的连接就马上回收,超时的销毁 现在设置为4秒) -->
<property name="houseKeepingSleepTime" value="3000"></property><!-- 自动检查连接是否断掉开关 -->
<property name="testBeforeUse" value="true"></property>
<!-- 如果发现了空闲的数据库连接.house keeper 将会用这个语句来测试.这个语句最好非常快的被执行.如果没有定义,测试过程将会被忽略 -->
<property name="houseKeepingTestSql" value="SELECT count(1) from dual"></property>
<!-- 如果housekeeper 检测到某个线程的活动时间大于这个数值.它将会杀掉这个线程.所以确认一下你的服务器的带宽.然后定一个合适的值.默认是5分钟. 现在设置 10 秒-->
<property name="maximumActiveTime" value="10000"></property>
<!-- 最少保持的空闲连接数 (现在设置20个) -->
<property name="prototypeCount" value="20"></property>
<!-- 最大连接数 (现在设置100个) -->
<property name="maximumConnectionCount" value="200"></property>
<!-- 最小连接数 (现在设置50个) -->
<property name="minimumConnectionCount" value="50"></property>
<!-- 如果为true,那么每个被执行的SQL语句将会在执行期被log记录(DEBUG LEVEL).你也可以注册一个ConnectionListener (参看ProxoolFacade)得到这些信息. -->
<property name="trace" value="false"></property>
<property name="verbose" value="true"></property>
</bean> <!-- 注册事务管理器 -->
<bean id="txMgr"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean> <!-- 开启事务注解驱动 -->
<tx:annotation-driven transaction-manager="txMgr" /> <!-- 配置mybatis的sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
</bean> <!-- 配置可以整体扫描Mapper的一个扫描器 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!--如果有多个报路径,用逗号分开即可 -->
<property name="basePackage" value="com.krry.mapper"></property>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean> </beans>

spring MVC配置文件: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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-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/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
"> <!-- 开启注解模式驱动 -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<!-- 开启mvc的注解模式 user 还会注册一个ConversionService 子类FormattingConversionServiceFactoryBean-->
<mvc:annotation-driven>
<mvc:message-converters register-defaults="true">
<bean class="com.krry.core.UTF8StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/plain;charset=UTF-8</value>
<value>text/html;charset=UTF-8</value>
</list>
</property>
</bean>
<bean class="org.springframework.http.converter.BufferedImageHttpMessageConverter"/>
<bean class="org.springframework.http.converter.ByteArrayHttpMessageConverter"/>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
<property name="prefixJson" value="false" />
<property name="objectMapper">
<bean class="com.fasterxml.jackson.databind.ObjectMapper">
<!-- 处理responseBody 里面日期类型 -->
<property name="dateFormat">
<bean class="java.text.SimpleDateFormat">
<constructor-arg type="java.lang.String" value="yyyy-MM-dd HH:mm:ss" />
</bean>
</property>
<!-- 为null字段时不显示 -->
<property name="serializationInclusion">
<value type="com.fasterxml.jackson.annotation.JsonInclude.Include">NON_NULL</value>
</property>
</bean>
</property>
<property name="supportedMediaTypes">
<list>
<value>application/json;charset=UTF-8</value>
<value>application/x-www-form-urlencoded;charset=UTF-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven> <!-- 扫包 -->
<context:component-scan base-package="com.krry.controller"></context:component-scan> <!--对静态资源文件的访问 必须要设置,因为在springmvc的配置中配置了/匹配所有请求,
此工程所有的请求(.do ,addUser,js/image/css)都会被springmvc解析,
必须对所有的静态资源文件进行过滤放行 -->
<!-- 静态资源过滤 下面二选一-->
<!--<mvc:default-servlet-handler/> -->
<mvc:resources mapping="/resourse/**" location="/resourse/" /> <!-- 拦截器定义 -->
<mvc:interceptors>
<mvc:interceptor>
<!-- 个人中心也需要登陆 以admin开头的配置都会进行拦截-->
<mvc:mapping path="/admin/**"></mvc:mapping>
<!-- 这个是设置不会进入拦截器的路径 -->
<mvc:exclude-mapping path="/resourse/**"/>
<!-- 拦截器进入的类,返回false表示不会进入输入的路径 -->
<bean class="com.krry.core.filter.LoginInterceptor" />
</mvc:interceptor>
</mvc:interceptors> <!-- 配置文件解析器 -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
p:defaultEncoding="utf-8">
<property name="uploadTempDir" value="/temp"></property>
<property name="maxUploadSize">
<value>209715200</value><!-- 200MB -->
</property>
<property name="maxInMemorySize">
<value>4096</value><!-- 4KB大小读写 -->
</property>
</bean> <!-- 视图渲染 jsp/freemaker/velocity-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 制定页面存放的路径 -->
<property name="prefix" value="/WEB-INF/pages/"></property>
<!-- 文件的后缀 -->
<property name="suffix" value=".jsp"></property>
</bean> </beans>

数据库配置文件: jdbc.properties

 db.driver=oracle.jdbc.OracleDriver
db.url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
db.username=4m+la23KCA4=
db.password=WWijcIyMPaU\=

我这里使用了加密算法

日志配置文件: log4j.properties

 log4j.rootLogger=DEBUG, CONSOLE, FILE

 log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p [%t] %10l - %m%n log4j.appender.FILE=org.apache.log4j.RollingFileAppender
log4j.appender.FILE.File=D:/logs/log4j.log
log4j.appender.FILE.MaxFileSize=1MB
log4j.appender.FILE.Append = true
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
log4j.appender.FILE.layout.ConversionPattern=%d{yyyy/MM/dd/HH:mm:ss} %-5p [%t] %10l - %m%n

mybatis配置文件: mybatis-config.xml

 <?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>
<settings>
<!-- 全局映射器启用缓存 -->
<setting name="cacheEnabled" value="true" />
<!-- 查询时,关闭关联对象即时加载以提高性能 -->
<setting name="lazyLoadingEnabled" value="true" />
<!-- 设置关联对象加载的形态,此处为按需加载字段(加载字段由SQL指 定),不会加载关联表的所有字段,以提高性能 -->
<setting name="aggressiveLazyLoading" value="false" />
<!-- 对于未知的SQL查询,允许返回不同的结果集以达到通用的效果 -->
<setting name="multipleResultSetsEnabled" value="true" />
<!-- 允许使用列标签代替列名 -->
<setting name="useColumnLabel" value="true" />
<!-- 允许使用自定义的主键值(比如由程序生成的UUID 32位编码作为键值),数据表的PK生成策略将被覆盖 -->
<setting name="useGeneratedKeys" value="true" />
<!-- 给予被嵌套的resultMap以字段-属性的映射支持 -->
<setting name="autoMappingBehavior" value="FULL" />
<!-- 对于批量更新操作缓存SQL以提高性能 -->
<setting name="defaultExecutorType" value="BATCH" />
<!-- 数据库超过25000秒仍未响应则超时 -->
<setting name="defaultStatementTimeout" value="25" />
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings> <typeAliases>
<!--自定义user对象的别名 -->
<!-- <typeAlias type="com.krry.mybatis.sysmanage.entity.User" alias="user"/> -->
<!-- 批量定义别名 -->
<package name="com.krry.entity" />
</typeAliases> </configuration>

网络程序配置文件:web.xml

 <?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1"> <display-name>maven_SSM</display-name> <welcome-file-list>
<welcome-file>index</welcome-file>
</welcome-file-list> <!-- 加载Spring IOC容器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param> <!-- spring上下文监听器 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <!-- Introspector缓存清除监听器 -->
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener> <filter>
<filter-name>encoding</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>encoding</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> <!-- 配置DispatcherServlet -->
<servlet>
<servlet-name>maven_SSM</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置springMVC的配置文件 -->
<!-- 如果不配置下面选项,系统默认加载classpath下面名为[servlet-name]-servlet.xml的文件 springmvc01-servlet.xml -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet> <servlet-mapping>
<servlet-name>maven_SSM</servlet-name>
<url-pattern>/index</url-pattern>
</servlet-mapping> <!-- 可以配*.do, *.action(了解) / (重点): 所有的请求都会被spring mvc解析,但必须对静态资源文件进行过滤放行,建议大家使用这种方式
/* : 不建议大家使用 -->
<servlet-mapping>
<servlet-name>maven_SSM</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping> </web-app>

到这里,基本配置全部完成,jar包也自动依赖。就进行测试和编写后续 java 的代码。

仔细分享一下 src/main/java 的目录结构:

Maven 搭建 SSM 项目 (oracle)

controller层:

首页:KrryController.java

 package com.krry.controller.index;

 import java.sql.Timestamp;
import java.util.Date;
import java.util.HashMap;
import java.util.List; import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView; import com.krry.entity.User;
import com.krry.mapper.UserMapper;
import com.krry.util.TmStringUtils; /**
* KrryController
* controller层,作为请求转发
* @author asusaad
*
*/
@Controller //表示是多例模式,每个用户返回的web层是不一样的
public class KrryController { @RequestMapping("/index")
public String index(){
// ModelAndView modelAndView = new ModelAndView();
// modelAndView.setViewName("index/login"); //跳到此页面
// return modelAndView;
return "index/index";
} }

登录控制层:LoginController.java

 package com.krry.controller.login;

 import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID; import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import com.krry.entity.User;
import com.krry.service.IUserService;
import com.krry.util.TmStringUtils; /**
* Controller层,作为请求转发
* 页面所有路径的访问方法:控制层的命名空间+@RequestMapping的value
* 如这里的/login/index.krry(后缀在xml文件配置)
* */
@Controller //表示是多例模式,每个用户返回的web层是不一样的
@RequestMapping("/login")
public class LoginController { @Autowired
private IUserService userService; /**
* 若在下面的@RequestMapping前面加上@ResponseBody,
* 若方法是String类型则直接返回的是字符串,不会跳转到该字符串的路径jsp文件
*
* 所以要想跳转到某一jsp页面,不能加上@ResponseBody
* 这个@ResponseBody适合ajax返回的数据
*
*/ /**
* 在控制层不加@ResponseBody的情况下,return值默认是转发到某路径,不会显示转发路径,显示的是未转发前的路径
* 若要重定向,加上redirect:这里默认是当前命名空间的转发,要跳转到另一个control层,需要返回上一级../
*
这里使用重定向,返回命名空间的上一级,重定向到命名空间为Krry下的index
return "redirect:../index"; 注意:
转发不会显示转发路径,显示的是未转发前的路径
* 重定向显示的是跳转之后的路径
*/ /**
* 进入登录界面
* @return
*/
@RequestMapping("/index")
public String index(){
// ModelAndView modelAndView = new ModelAndView();
// modelAndView.setViewName("index/login"); //跳到此页面
// return modelAndView;
return "index/login"; //默认是转发,不会显示转发路径
} /**
* 点击登录
* com.krry.controller.login
* 方法名:login
* @author krry
* @param request
* @return String
* @exception
* @since 1.0.0
*/
@RequestMapping(method=RequestMethod.POST,value="/logined")
public String login(HttpServletRequest request){
//获取用户和密码
String username = request.getParameter("username");
String password = request.getParameter("password"); //如果邮箱和密码为null,那么就返回已null标识
if(TmStringUtils.isEmpty(username) )return "index/allError";
if(TmStringUtils.isEmpty(password))return "index/allError"; //密码进行加密处理
password = TmStringUtils.md5Base64(password); //根据邮箱或昵称查询,用户是否存在
User user = userService.getLogin(username); //如果存在
if(user!=null){ User userpas = userService.getpass(username, password);
if(userpas!=null){
//如果密码正确
//将用户信息放入到会话中...
request.getSession().setAttribute("user", user); //这里使用重定向,返回命名空间的上一级,重定向到命名空间为Krry下的index.krry
return "redirect:../index";
}else{
//如果密码错误
System.out.println("密码错误");
return "index/error";
}
}else{
//如果不存在,代码邮箱和密码输入有误
System.out.println("用户不存在");
return "index/error";
}
} /**
* 退出登录控制层
* com.krry.controller.login
* 方法名:logout
* @author krry
* @param request
* @return String
* @exception
* @since 1.0.0
*/
@RequestMapping(method=RequestMethod.GET,value="/logout")
public String logout(HttpServletRequest request){
request.getSession().invalidate(); //清空session值
return "index/index";
} /**
* 打开注册界面层
* @return
*/
@RequestMapping("/rege")
public String rege(){
// ModelAndView modelAndView = new ModelAndView();
// modelAndView.setViewName("index/login"); //跳到此页面
// return modelAndView;
return "index/resgi";
} /**
* 注册控制层
* com.krry.controller.login
* 方法名:resig
* @author krry
* @param request
* @return String
* @exception
* @since 1.0.0
*/
@RequestMapping(method=RequestMethod.POST,value="/resig")
public String resig(HttpServletRequest request){
//获取用户和密码
String name = request.getParameter("username");
String email = request.getParameter("email");
String password = request.getParameter("password"); //如果邮箱和密码为null,那么就返回已null标识
if(TmStringUtils.isEmpty(name) )return "index/allError";
if(TmStringUtils.isEmpty(email))return "index/allError";
if(TmStringUtils.isEmail(password))return "index/allError"; //密码进行加密处理
password = TmStringUtils.md5Base64(password);
//根据昵称查询,用户是否存在
User user1 = userService.getothernameres(name);
//根据账号查询,用户是否存在
User user2 = userService.getemailres(email); //若存在
if(user1 != null){ //昵称重复
return "index/allError";
}
if(user2 != null){ //email重复
return "index/allError";
} //格式化时间类型
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String nowTime = sdf.format(new Date()); String id = UUID.randomUUID().toString();
//执行到这里,说明可以注册
User newUser = new User(id, name, password, email, nowTime);
//调用注册方法
userService.saveUser(newUser); //将信息设置session作用域
request.getSession().setAttribute("user", newUser); /**
* 这里使用重定向,返回命名空间的上一级,重定向到index
*/
return "redirect:../index";
} }

实体entity层:

User.java

 package com.krry.entity;

 import java.sql.Date;
import java.sql.Timestamp; /**
*
* User
* @author krry
* @version 1.0.0
*
*/
public class User { // 主键,自动递增
private String id;
// 用户名
private String username;
// 密码
private String password;
//email
private String email;
//自动生成创建时间
private String createTime; public User(String id,String username,String password,String email,String createTime) {
this.id = id;
this.username = username;
this.email = email;
this.password = password;
this.createTime = createTime;
} public String getCreateTime() {
return createTime;
} public void setCreateTime(String createTime) {
this.createTime = createTime;
} public String getEmail() {
return email;
} public void setEmail(String email) {
this.email = email;
} public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", password="
+ password + ", email=" + email + ", createTime=" + createTime
+ "]";
} }

持久化层mapper:

接口层

UserMapper.java

 package com.krry.mapper;

 import java.util.List;

 import org.apache.ibatis.annotations.Param;

 import com.krry.entity.User;

 /**
*
* Mapper:操作数据库
* IUserMapper
* @author krry
* @version 1.0.0
*
*/
public interface UserMapper { /**
*
* com.krry.mapper
* 方法名:findUsers
* @author krry
* @return List<User>
* @exception
* @since 1.0.0
*/
public List<User> findUsers(); /**
* 根据用户查询用户是否存在
* com.krry.mapper
* 方法名:getLogin
* @author krry
* @param email
* @param password
* @return User
* @exception
* @since 1.0.0
*/
/*这里用@Param("name")String name适用于单个参数的传递,在web层调用此方法的时候,就可以传递web层从前台获取的参数,
在sql的xml中WHERE email = #{name} or username = #{name}使用此参数,多个参数传递一般使用实体类对象传递 */
public User getLogin(@Param("name")String name); /**
* 用户名存在时,查询密码是否正确
* com.krry.mapper
* 方法名:getpass
* @author krry
* @param email
* @param password
* @return User
* @exception
* @since 1.0.0
*/
public User getpass(@Param("name")String name,@Param("password")String password); /**
* 注册时根据输入的昵称查找用户
* com.krry.mapper
* 方法名:getothername
* @author krry
* @param name
* @return User
* @exception
* @since 1.0.0
*/
public User getothernameres(@Param("name")String name); /**
* 注册时根据输入的账号查找用户
* com.krry.mapper
* 方法名:getemailres
* @author krry
* @param password
* @return User
* @exception
* @since 1.0.0
*/
public User getemailres(@Param("email")String email); /**
* 注册方法
* com.krry.mapper
* 方法名:csaveUser
* @author krry
* @param user void
* @exception
* @since 1.0.0
*/
public void saveUser(User user); }

映射层

UserMapper.xml

 <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.krry.mapper.UserMapper" >
<!-- 所有的增删查改都在这里定义sql语句 --> <!-- 查询所有的用户信息 -->
<select id="findUsers" resultType="User">
SELECT id,username,password FROM krry_user_test
</select> <!-- 登录时根据输入的昵称或账号查找用户 -->
<select id="getLogin" resultType="User" >
SELECT
id,
username,
password,
email,
create_time as createTime
FROM
krry_user_test
WHERE
email = #{name} or username = #{name}
</select> <!-- 若已存在用户信息,再查询密码是否正确 -->
<select id="getpass" resultType="User" >
SELECT
id,
username,
password,
email,
create_time as createTime
FROM
krry_user_test
WHERE
(email = #{name} or username = #{name}) AND password = #{password}
</select> <!-- 注册时根据输入的昵称查找用户 -->
<select id="getothernameres" resultType="User" >
SELECT
id,
username,
password,
email,
create_time as createTime
FROM
krry_user_test
WHERE
username = #{name}
</select> <!-- 注册时根据输入的账号查找用户 -->
<select id="getemailres" resultType="User" >
SELECT
id,
username,
password,
email,
create_time as createTime
FROM
krry_user_test
WHERE
email = #{email}
</select> <!-- 注册用户信息 -->
<insert id="saveUser" parameterType="User">
INSERT INTO krry_user_test(
id,
username,
email,
password,
create_time
)VALUES(
#{id},
#{username},
#{email},
#{password},
#{createTime}
)
</insert> </mapper>

业务逻辑层service:

接口层:

IUserService.java

 package com.krry.service;

 import java.util.List;

 import javax.servlet.http.HttpServletRequest;

 import org.apache.ibatis.annotations.Param;

 import com.krry.entity.User;

 /**
* service层:处理业务逻辑(impl里面实现)
* @author asusaad
*
*/
public interface IUserService { /**
* 根据用户名查询用户是否存在
* com.krry.service
* 方法名:getLogin
* @author krry
* @param email
* @param password
* @return User
* @exception
* @since 1.0.0
*/
/*这里用@Param("name")String name适用于单个参数的传递,在web层调用此方法的时候,就可以传递web层从前台获取的参数,
在sql的xml中WHERE email = #{name} or username = #{name}使用此参数,多个参数传递一般使用实体类对象传递 */
public User getLogin(@Param("name")String name); /**
* 用户名存在时,查询密码是否正确
* com.krry.service
* 方法名:getpass
* @author krry
* @param email
* @param password
* @return User
* @exception
* @since 1.0.0
*/
public User getpass(@Param("name")String name,@Param("password")String password); /**
* 注册时根据输入的昵称查找用户
* com.krry.service
* 方法名:getothername
* @author krry
* @param name
* @return User
* @exception
* @since 1.0.0
*/
public User getothernameres(@Param("name")String name); /**
* 注册时根据输入的账号查找用户
* com.krry.service
* 方法名:getemailres
* @author krry
* @param password
* @return User
* @exception
* @since 1.0.0
*/
public User getemailres(@Param("email")String email); /**
* 注册方法
* com.krry.service
* 方法名:csaveUser
* @author krry
* @param user void
* @exception
* @since 1.0.0
*/
public void saveUser(User user); }

impl

UserService.java

 package com.krry.service.impl;

 import java.util.List;

 import javax.servlet.http.HttpServletRequest;

 import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import com.krry.entity.User;
import com.krry.mapper.UserMapper;
import com.krry.service.IUserService; /**
* 实现service层接口
* @author asusaad
*
*/
@Service
public class UserService implements IUserService{ @Autowired
private UserMapper userMapper; /**
* 根据用户名查询用户是否存在
*/
public User getLogin(String name) {
User user = userMapper.getLogin(name);
return user;
} public User getpass(String name, String password) {
User userpas = userMapper.getpass(name, password);
return userpas;
} public User getothernameres(String name) {
User user = userMapper.getothernameres(name);
return user;
} public User getemailres(String email) {
//根据账号查询,用户是否存在
User user = userMapper.getemailres(email);
return user;
} public void saveUser(User user) {
userMapper.saveUser(user); } }

view 视图:

common.jsp

 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
int port = request.getServerPort();
String basePath = null;
if(port==80){
basePath = request.getScheme()+"://"+request.getServerName()+path;
}else{
basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path;
}
pageContext.setAttribute("basePath", basePath);
%>

index.jsp

 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@include file="../common/common.jsp" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>首页</title>
</head> <body>
<p class="title">用户名:<span class="username">${user.username}</span>已登录</p><br>
<a href="${basePath}/login/logout" id="login">退出登录</a> <script type="text/javascript" src="${basePath}/resourse/js/jquery-1.11.2.min.js"></script>
<script type="text/javascript">
var basePath = "${basePath}";
if(isEmpty($(".username").text())){
$(".title").text("未登录");
$("#login").attr("href",basePath+"/login/index");
$("#login").text("点击登陆");
}
/**
* 判断非空
*
* @param val
* @returns {Boolean}
*/
function isEmpty(val) {
val = $.trim(val);
if (val == null)
return true;
if (val == undefined || val == 'undefined')
return true;
if (val == "")
return true;
if (val.length == 0)
return true;
if (!/[^(^\s*)|(\s*$)]/.test(val))
return true;
return false;
} </script>
</body>
</html>

login.jsp

 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@include file="../common/common.jsp" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head> <title>登录界面</title>
</head>
<body>
<form action="${basePath}/login/logined" method="post">
用户名:<input type="text" name="username"/><br>
密&nbsp;码:<input type="password" name="password"/>
<input type="submit"><br><br>
<a href="${basePath}/login/rege">点我注册</a>
</form>
</body>
</html>

resgi.jsp

 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@include file="../common/common.jsp" %> <!DOCTYPE HTML>
<html>
<head>
<base href="<%=basePath%>"> <title>注册界面</title> </head> <body>
<form action="${basePath}/login/resig" method="post">
用户名:<input type="text" name="username"/><br>
邮&nbsp;箱:<input type="text" name="email"/><br>
密&nbsp;码:<input type="password" name="password"/><br>
<input type="submit">
</form>
</body>
</html>

allError.jsp

 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@include file="../common/common.jsp" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head> <title>错误</title> </head> <body>
发生错误<br><br>
<a href="${basePath}">返回首页</a>
</body>
</html>

error.jsp

 <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@include file="../common/common.jsp" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head> <title>错误</title> </head> <body>
用户名或密码错误<br><br>
<a href="${basePath}/login/index">返回登录</a>
</body>
</html>

到这里,maven 构建的 ssm 工程实现注册登录完成。

核心包 core 和工具包 util 包这里就不展示了,代码太长。

该博客作为自己的总结,也是一种分享

相关链接:

GitHub:https://github.com/Krryxa

音乐博客:https://www.ainyi.com

上一篇:lucene 专业名词作用整理


下一篇:Codeforces#371 Div2