首先感谢原作者的倾囊相授!
资源链接:https://github.com/saysky/ForestBlog
本内容仅为个人对整个项目的分析展示,用作学习,如有错误之处还望指点,本项目前端采用LayUI+前端三件套+jQuery实现,本人没有学过LayUI因此不做前端分析,仅展示部分运行部分的页面效果,打算在后续学习使用Vue框架进行实现,再根据分析经验重新对后端进行新的构建,尽力实现自己学习的第一个SSM项目,加油。
分析学习第一个SSM项目:ForestBlog
文章目录
-
- 首先感谢原作者的倾囊相授!
- 分析学习第一个SSM项目:ForestBlog
-
- 目录基础结构
- 一、分析pom.xml文件和web.xml文件
-
- 1. pox.xml
- 2. src/main/webapp/WEB-INF/web.xml
- 二、分析main文件夹下文件
-
- 1. 分析resources文件夹
-
- 1.1 文件夹结构
- 1.2 db.properties
- 1.3 logback.xml
- 1.4 mybatis/mybatis-config.xml
- 1.5 spring文件夹
-
- 1.5.1 spring-mvc.xml
- 1.5.2 spring-mybatis.xml
- 2. 分析java文件夹
-
- 2.1 文件夹结构
- 2.2 entity实体类
-
- 2.2.0 实例关系分析
- 2.2.1 Article
- 2.2.2 ArticleCategoryRef
- 2.2.3 ArticleTagRef
- 2.2.4 Category
- 2.2.5 Comment
- 2.2.6 Link
- 2.2.7 Menu
- 2.2.8 Notice
- 2.2.9 Options
- 2.2.10 Page
- 2.2.11 Tag
- 2.2.12 User
- 2.3 enums枚举类
-
- 2.3.1 ArticleCommentStatus
- 2.3.2 ArticleStatus
- 2.3.3 CategoryStatus
- 2.3.4 LinkStatus
- 2.3.5 MenuLevel
- 2.3.6 NoticeStatus
- 2.3.7 PageStatus
- 2.3.8 Role
- 2.3.9 UserRole
- 2.4 dto数据传输对象
-
- 2.4.1 ArticleParam
- 2.4.2 JsonResult
- 2.4.3 ResultVO
- 2.4.4 UploadFileVO
- 2.5 util工具类
-
- 2.5.1 MyUtils 我的工具类
- 2.2.11 Tag
- 2.2.12 User
- 2.3 enums枚举类
-
- 2.3.1 ArticleCommentStatus
- 2.3.2 ArticleStatus
- 2.3.3 CategoryStatus
- 2.3.4 LinkStatus
- 2.3.5 MenuLevel
- 2.3.6 NoticeStatus
- 2.3.7 PageStatus
- 2.3.8 Role
- 2.3.9 UserRole
- 2.4 dto数据传输对象
-
- 2.4.1 ArticleParam
- 2.4.2 JsonResult
- 2.4.3 ResultVO
- 2.4.4 UploadFileVO
- 2.5 util工具类
-
- 2.5.1 MyUtils 我的工具类
目录基础结构
一、分析pom.xml文件和web.xml文件
1. pox.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.liuyanzhao</groupId><artifactId>ForestBlog</artifactId><packaging>war</packaging><version>1.0.0-SNAPSHOT</version><name>ForestBlog Maven Webapp</name><url>http://maven.apache.org</url><properties><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><spring.version>4.3.19.RELEASE</spring.version><jackson-databind-version>2.10.1</jackson-databind-version></properties><dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.16.22</version></dependency><!-- 添加sevlet支持 --><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><!-- 添加jsp支持 --><dependency><groupId>javax.servlet.jsp</groupId><artifactId>javax.servlet.jsp-api</artifactId><version>2.3.1</version></dependency><!-- 添加jstl支持 --><dependency><groupId>javax.servlet</groupId><artifactId>jstl</artifactId><version>1.1.2</version></dependency><dependency><groupId>taglibs</groupId><artifactId>standard</artifactId><version>1.1.2</version></dependency><!-- 添加spring支持 --><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>${spring.version}</version></dependency><!--spring test支持--><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>${spring.version}</version></dependency><!--spring mvc支持--><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>${spring.version}</version></dependency><!--spring 事务管理支持--><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>${spring.version}</version></dependency><!--spring jdbc操作支持--><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>${spring.version}</version></dependency><!--spring aop编程支持--><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>${spring.version}</version></dependency><!-- 添加mybatis支持 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.0</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>1.3.0</version></dependency><!-- jdbc驱动包 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.11</version></dependency><!-- 添加阿里巴巴连接池Druid支持 --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.0.16</version></dependency><!-- 添加logback日志 --><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.1.2</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-core</artifactId><version>1.1.2</version></dependency><dependency><groupId>org.logback-extensions</groupId><artifactId>logback-ext-spring</artifactId><version>0.1.1</version></dependency><!-- 添加junit支持 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><dependency><groupId>commons-fileupload</groupId><artifactId>commons-fileupload</artifactId><version>1.3.3</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.4</version></dependency><!-- jackson --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.9.8</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.9.8</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.9.0</version></dependency><dependency><groupId>org.json</groupId><artifactId>json</artifactId><version>20170516</version></dependency><dependency><groupId>com.googlecode.rapid-framework</groupId><artifactId>rapid-core</artifactId><version>4.0.5</version></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>26.0-jre</version></dependency><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>4.2.1</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.72</version></dependency><!-- hutool工具包 --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>4.1.13</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>${jackson-databind-version}</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>${jackson-databind-version}</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>${jackson-databind-version}</version></dependency></dependencies><build><resources><!-- 编译之后包含xml --><resource><directory>src/main/java</directory><includes><include>**/*.xml</include></includes><filtering>true</filtering></resource><!-- 编译之后包含xml和properties --><resource><directory>src/main/resources</directory><includes><include>**/*</include></includes><filtering>true</filtering></resource></resources></build>
</project>
pom.xml文件使用的依赖:
-
lombok
-
添加sevlet支持
- javax.servlet-api
-
添加jsp支持
- javax.servlet.jsp-api
-
添加jstl支持
- jstl
- standard
-
添加spring支持
- spring-core
- spring-beans
- spring-context
- spring-context-support
- spring-web
-
spring test支持
- spring-test
-
spring mvc支持
- spring-webmvc
-
spring 事务管理支持
- spring-tx
-
spring jdbc操作支持
- spring-jdbc
-
spring aop编程支持
- spring-aop
- spring-aspects
-
添加mybatis支持
- mybatis
- mybatis-spring
-
jdbc驱动包
- mysql-connector-java
-
添加阿里巴巴连接池Druid支持
- druid
-
添加logback日志
- logback-classic
- logback-core
- logback-ext-spring
-
添加junit支持
- junit
-
文件上传
- commons-fileupload
- commons-io
-
jackson
- jackson-databind
- jackson-core
- jackson-annotations
-
rapid-framework是谷歌的一个项目,可以实现jsp网页的继承,也就是书写模板页。
- json
- rapid-core
-
Guava是Google的一个开源Java框架,包含许多Google 内部Java项目依赖的核心类,包括:从集合类型、不可变集合、图结构处理、并发工具、I/O、哈希、缓存等等各个方面的工具。Guava是对Java API的补充,对Java开发中常用功能进行更优雅的实现,Guava库经过高度的优化,使得编码更加轻松,代码容易理解。
- guava
-
添加分页插件pagehelper
- pagehelper
- fastjson
-
hutool工具包
- hutool-all
-
<build>
方式<build><resources><!-- 编译之后包含xml --><resource><directory>src/main/java</directory><includes><include>**/*.xml</include></includes><filtering>true</filtering></resource><!-- 编译之后包含xml和properties --><resource><directory>src/main/resources</directory><includes><include>**/*</include></includes><filtering>true</filtering></resource></resources> </build>
2. src/main/webapp/WEB-INF/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" xmlns:mvc="http://www.springframework.org/schema/mvc"xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"><display-name>ForestBlog</display-name><!--post乱码过滤器--><!-- 配置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><!-- 启动过滤器 --><init-param><param-name>forceEncoding</param-name><param-value>true</param-value></init-param></filter><!-- 过滤所有请求 --><filter-mapping><filter-name>CharacterEncodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><!--加载spring容器--><context-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring/spring-*.xml,</param-value></context-param><!--配置监听器,来加载spring容器--><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- logback日志打印 --><context-param><param-name>logbackConfigLocation</param-name><param-value>classpath:logback.xml</param-value></context-param><listener><listener-class>ch.qos.logback.ext.spring.web.LogbackConfigListener</listener-class></listener><!--springmvc前端控制器 --><servlet><servlet-name>ForestBlog</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:spring/spring-mvc.xml</param-value></init-param></servlet><servlet-mapping><servlet-name>ForestBlog</servlet-name><url-pattern>/</url-pattern></servlet-mapping><!--随时获得request--><listener><listener-class>org.springframework.web.context.request.RequestContextListener</listener-class></listener><!-- 4、使用Rest风格的URI,将页面普通的post请求转为指定的delete或者put请求 --><filter><filter-name>HiddenHttpMethodFilter</filter-name><filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class></filter><filter-mapping><filter-name>HiddenHttpMethodFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><filter><filter-name>HttpPutFormContentFilter</filter-name><filter-class>org.springframework.web.filter.HttpPutFormContentFilter</filter-class></filter><filter-mapping><filter-name>HttpPutFormContentFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><filter><filter-name>DruidWebStatFilter</filter-name><filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class><init-param><param-name>exclusions</param-name><param-value>*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*</param-value></init-param></filter><filter-mapping><filter-name>DruidWebStatFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list><!--去掉jsp页面的空白--><jsp-config><jsp-property-group><url-pattern>*.jsp</url-pattern><trim-directive-whitespaces>true</trim-directive-whitespaces></jsp-property-group></jsp-config></web-app>
web.xml文件的作用
-
配置欢迎页面
-
配置springMVC编码过滤器
-
加载spring容器
-
配置监听器,来加载spring容器
-
配置logback日志打印
-
springmvc前端控制器
-
配置监听器,随时获得request
-
使用Rest风格的URI,将页面普通的post请求转为指定的delete或者put请求
-
配置WebStatFilter用于采集web-jdbc关联监控的数据。
-
去掉jsp页面的空白
二、分析main文件夹下文件
1. 分析resources文件夹
1.1 文件夹结构
│ db.properties
│ logback.xml
│
├─mapper
│ ArticleCategoryRefMapper.xml
│ ArticleMapper.xml
│ ArticleTagRefMapper.xml
│ CategoryMapper.xml
│ CommentMapper.xml
│ LinkMapper.xml
│ MenuMapper.xml
│ NoticeMapper.xml
│ OptionsMapper.xml
│ PageMapper.xml
│ TagMapper.xml
│ UserMapper.xml
│
├─mybatis
│ mybatis-config.xml
│
└─spring
spring-mvc.xml
spring-mybatis.xml
mapper 文件夹暂不分析,等分析具体映射时再一起分析
1.2 db.properties
-
此文件为数据库连接配置文件
#MySQL mysql.driver=com.mysql.cj.jdbc.Driver mysql.url=jdbc:mysql://localhost:3306/forest_blog?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC mysql.username=root mysql.password=123
1.3 logback.xml
-
此文件为logback日志配置文件
<?xml version="1.0" encoding="UTF-8"?> <configuration><!-- 尽量别用绝对路径,如果带参数不同容器路径解释可能不同,以下配置参数在pom.xml里 --><property name="log.root.level" value="INFO"/> <!-- 日志级别 --><property name="log.other.level" value="ERROR"/> <!-- 其他日志级别 --><property name="log.base" value="logs"/> <!-- 日志路径,这里是相对路径,默认会输出到tomcat/bin目录 下 --><property name="log.moduleName" value="ForestBlog"/> <!-- 模块名称, 影响日志配置名,日志文件名 --><property name="log.max.size" value="20MB"/> <!-- 日志文件大小 --><!--控制台输出 --><appender name="stdout" class="ch.qos.logback.core.ConsoleAppender"><encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"><Pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread]%logger{56}.%method:%L -%msg%n</Pattern></encoder></appender><!-- 日志文件输出 --><appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender"><File>${log.base}/${log.moduleName}.log</File><!-- 设置日志不超过${log.max.size}时的保存路径,注意如果 是web项目会保存到Tomcat的bin目录 下 --><!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件。--><rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"><FileNamePattern>${log.base}/archive/${log.moduleName}_all_%d{yyyy-MM-dd}.%i.log.zip</FileNamePattern><!-- 当天的日志大小 超过${log.max.size}时,压缩日志并保存 --><timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"><maxFileSize>${log.max.size}</maxFileSize></timeBasedFileNamingAndTriggeringPolicy></rollingPolicy><!-- 日志输出的文件的格式 --><layout class="ch.qos.logback.classic.PatternLayout"><pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread]%logger{56}.%method:%L -%msg%n</pattern></layout></appender> </configuration>
1.4 mybatis/mybatis-config.xml
-
此文件为mybatis配置文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration><!-- 全局配置 --><settings><!--允许 JDBC 支持自动生成主键--><setting name="useGeneratedKeys" value="false"/><!--是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典Java 属性名 aColumn 的类似映射。 --><setting name="mapUnderscoreToCamelCase" value="true"/><!-- 打印查询语句 --> <!-- <setting name="logImpl" value="STDOUT_LOGGING" />--></settings><!-- 注册分页插件PageHelper --><plugins><plugin interceptor="com.github.pagehelper.PageHelper"><!--<property name="dialect" value="mysql"/>--><property name="offsetAsPageNum" value="false"/><property name="rowBoundsWithCount" value="false"/><property name="pageSizeZero" value="true"/><property name="reasonable" value="true"/><property name="supportMethodsArguments" value="false"/><property name="returnPageInfo" value="none"/></plugin></plugins></configuration>
-
主要任务
- 允许 JDBC 支持自动生成主键
- 是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典Java 属性名 aColumn 的类似映射。
- 注册分页插件PageHelper
1.5 spring文件夹
1.5.1 spring-mvc.xml
-
springmvc配置文件
<?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:mvc="http://www.springframework.org/schema/mvc"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-4.2.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-4.2.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-4.2.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><context:component-scan base-package="com.liuyanzhao.ssm.blog"/><!-- 一个配置节解决映射器和适配器的配置注解配置 --><mvc:annotation-driven></mvc:annotation-driven><!-- 配置视图解析器进行jsp解析,默认使用jstl标签,classpath下得有jstl的包--><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"><!--配置前缀和后缀,也可以不指定--><property name="prefix" value="/WEB-INF/view/"/><property name="suffix" value=".jsp"/></bean><!--<!–文件上传–>--><bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><!--设置上传最大尺寸为50MB--><property name="maxUploadSizePerFile" value="52428800"/><property name="defaultEncoding" value="UTF-8"/><property name="resolveLazily" value="true"/></bean><!-- 静态资源映射 --><mvc:resources mapping="/css/**" location="/resource/assets/css/"></mvc:resources><mvc:resources mapping="/js/**" location="/resource/assets/js/"></mvc:resources><mvc:resources mapping="/img/**" location="/resource/assets/img/"></mvc:resources><mvc:resources mapping="/plugin/**" location="/resource/assets/plugin/"></mvc:resources><mvc:interceptors><mvc:interceptor><mvc:mapping path="/**"/><bean class="com.liuyanzhao.ssm.blog.util.interceptor.HomeResourceInterceptor"/></mvc:interceptor><mvc:interceptor><mvc:mapping path="/admin"/><bean class="com.liuyanzhao.ssm.blog.util.interceptor.LoginInterceptor"/></mvc:interceptor><mvc:interceptor><mvc:mapping path="/admin/**"/><bean class="com.liuyanzhao.ssm.blog.util.interceptor.LoginInterceptor"/></mvc:interceptor><mvc:interceptor><mvc:mapping path="/admin/page"/><bean class="com.liuyanzhao.ssm.blog.util.interceptor.AdminInterceptor"/></mvc:interceptor><mvc:interceptor><mvc:mapping path="/admin/page/**"/><bean class="com.liuyanzhao.ssm.blog.util.interceptor.AdminInterceptor"/></mvc:interceptor><mvc:interceptor><mvc:mapping path="/admin/tag"/><bean class="com.liuyanzhao.ssm.blog.util.interceptor.AdminInterceptor"/></mvc:interceptor><mvc:interceptor><mvc:mapping path="/admin/tag/**"/><bean class="com.liuyanzhao.ssm.blog.util.interceptor.AdminInterceptor"/></mvc:interceptor><mvc:interceptor><mvc:mapping path="/admin/category"/><bean class="com.liuyanzhao.ssm.blog.util.interceptor.AdminInterceptor"/></mvc:interceptor><mvc:interceptor><mvc:mapping path="/admin/category/**"/><bean class="com.liuyanzhao.ssm.blog.util.interceptor.AdminInterceptor"/></mvc:interceptor><mvc:interceptor><mvc:mapping path="/admin/user"/><bean class="com.liuyanzhao.ssm.blog.util.interceptor.AdminInterceptor"/></mvc:interceptor><mvc:interceptor><mvc:mapping path="/admin/user/**"/><bean class="com.liuyanzhao.ssm.blog.util.interceptor.AdminInterceptor"/></mvc:interceptor><mvc:interceptor><mvc:mapping path="/admin/menu"/><bean class="com.liuyanzhao.ssm.blog.util.interceptor.AdminInterceptor"/></mvc:interceptor><mvc:interceptor><mvc:mapping path="/admin/menu/**"/><bean class="com.liuyanzhao.ssm.blog.util.interceptor.AdminInterceptor"/></mvc:interceptor><mvc:interceptor><mvc:mapping path="/admin/options"/><bean class="com.liuyanzhao.ssm.blog.util.interceptor.AdminInterceptor"/></mvc:interceptor><mvc:interceptor><mvc:mapping path="/admin/options/**"/><bean class="com.liuyanzhao.ssm.blog.util.interceptor.AdminInterceptor"/></mvc:interceptor><mvc:interceptor><mvc:mapping path="/admin/link"/><bean class="com.liuyanzhao.ssm.blog.util.interceptor.AdminInterceptor"/></mvc:interceptor><mvc:interceptor><mvc:mapping path="/admin/link/**"/><bean class="com.liuyanzhao.ssm.blog.util.interceptor.AdminInterceptor"/></mvc:interceptor></mvc:interceptors> </beans>
-
主要任务
- 配置包扫描器对动态java文件进行扫描实例化
- 配置视图解析器进行jsp解析,默认使用jstl标签,classpath下得有jstl的包
- 配置文件上传限制
- 对静态资源进行映射
- 注册拦截器
1.5.2 spring-mybatis.xml
-
spring与mybatis的配置文件
<?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:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/txhttp://www.springframework.org/schema/tx/spring-tx.xsd"><!--加载db.properties--><context:property-placeholder location="classpath:db.properties"/><!--配置druid连接池--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"><!-- 基本属性 url、user、password --><property name="driverClassName" value="${mysql.driver}" /><property name="url" value="${mysql.url}" /><property name="username" value="${mysql.username}" /><property name="password" value="${mysql.password}" /><!-- 配置初始化大小、最小、最大 --><property name="initialSize" value="1" /><property name="minIdle" value="1" /><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" /><!-- 配置监控统计拦截的filters,去掉后监控界面sql无法统计 --><property name="filters" value="stat" /></bean><!-- mybatis核心配置 --><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><!--数据库连接池--><property name="dataSource" ref="dataSource"/><!--加载mybatis全局配置文件--><property name="configLocation" value="classpath:mybatis/mybatis-config.xml"/><!--mapper.xml所在位置--><property name="mapperLocations" value="classpath*:mapper/*Mapper.xml" /><!--指定需要使用别名的PO类所在的包--><property name="typeAliasesPackage" value="com.liuyanzhao.ssm.blog.entity" /></bean><!--mapper扫描器--><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><!--如果需要扫描多个包,中间使用半角逗号隔开--><property name="basePackage" value="com.liuyanzhao.ssm.blog.mapper"></property><property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/></bean><!-- 对mybatis操作数据事务控制,spring使用jdbc的事务控制类 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><!-- 数据源dataSource在spring-mybatis.xml中配置了 --><property name="dataSource" ref="dataSource"/></bean><!-- 通知 --><tx:advice id="txAdvice" transaction-manager="transactionManager"><tx:attributes><tx:method name="save*" propagation="REQUIRED"/><tx:method name="delete*" propagation="REQUIRED"/><tx:method name="update*" propagation="REQUIRED"/><tx:method name="insert*" propagation="REQUIRED"/><tx:method name="find*" propagation="SUPPORTS" read-only="true"/><tx:method name="get*" propagation="SUPPORTS" read-only="true"/><tx:method name="select*" propagation="SUPPORTS" read-only="true"/></tx:attributes></tx:advice><aop:config><aop:advisor advice-ref="txAdvice" pointcut="execution(* com.liuyanzhao.ssm.blog.service.impl.*.*(..))"/></aop:config> </beans>
-
主要任务
- 加载db.properties数据库信息配置文件
- 配置druid连接池信息
- 基本属性 url、user、password
- 配置初始化大小、最小、最大
- 配置获取连接等待超时的时间
- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
- 配置一个连接在池中最小生存的时间,单位是毫秒
- 打开PSCache,并且指定每个连接上PSCache的大小
- 配置监控统计拦截的filters,去掉后监控界面sql无法统计
- mybatis核心配置
- 数据库连接池
- 加载mybatis全局配置文件
- mapper.xml所在位置
- 指定需要使用别名的PO类所在的包
- mapper扫描器
- 如果需要扫描多个包,中间使用半角逗号隔开
- 对mybatis操作数据事务控制,spring使用jdbc的事务控制类
- 数据源dataSource在spring-mybatis.xml中配置了
- 定义通知advice
- 配置切面
2. 分析java文件夹
2.1 文件夹结构
└─com
└─liuyanzhao
└─ssm
└─blog
├─controller
│ ├─admin
│ │ AdminController.java
│ │ BackArticleController.java
│ │ BackCategoryController.java
│ │ BackCommentController.java
│ │ BackLinkController.java
│ │ BackMenuController.java
│ │ BackNoticeController.java
│ │ BackOptionsController.java
│ │ BackPageController.java
│ │ BackTagController.java
│ │ BackUserController.java
│ │ UploadFileController.java
│ │
│ └─home
│ ArticleController.java
│ CategoryController.java
│ CommentController.java
│ IndexController.java
│ LinkController.java
│ NoticeController.java
│ PageController.java
│ TagController.java
│
├─dto
│ ArticleParam.java
│ JsonResult.java
│ ResultVO.java
│ UploadFileVO.java
│
├─entity
│ Article.java
│ ArticleCategoryRef.java
│ ArticleTagRef.java
│ Category.java
│ Comment.java
│ Link.java
│ Menu.java
│ Notice.java
│ Options.java
│ Page.java
│ Tag.java
│ User.java
│
├─enums
│ ArticleCommentStatus.java
│ ArticleStatus.java
│ CategoryStatus.java
│ LinkStatus.java
│ MenuLevel.java
│ NoticeStatus.java
│ PageStatus.java
│ Role.java
│ UserRole.java
│
├─mapper
│ ArticleCategoryRefMapper.java
│ ArticleMapper.java
│ ArticleTagRefMapper.java
│ CategoryMapper.java
│ CommentMapper.java
│ LinkMapper.java
│ MenuMapper.java
│ NoticeMapper.java
│ OptionsMapper.java
│ PageMapper.java
│ TagMapper.java
│ UserMapper.java
│
├─service
│ │ ArticleService.java
│ │ CategoryService.java
│ │ CommentService.java
│ │ LinkService.java
│ │ MenuService.java
│ │ NoticeService.java
│ │ OptionsService.java
│ │ PageService.java
│ │ TagService.java
│ │ UserService.java
│ │
│ └─impl
│ ArticleServiceImpl.java
│ CategoryServiceImpl.java
│ CommentServiceImpl.java
│ LinkServiceImpl.java
│ MenuServiceImpl.java
│ NoticeServiceImpl.java
│ OptionsServiceImpl.java
│ PageServiceImpl.java
│ TagServiceImpl.java
│ UserServiceImpl.java
│
└─util
│ MyUtils.java
│
└─interceptor
AdminInterceptor.java
HomeResourceInterceptor.java
LoginInterceptor.java
由于包名为com.liuyanzhao.ssm.blog,其余文件都在该目录下进行分类,因此以下分析默认在此目录下进行。
2.2 entity实体类
2.2.0 实例关系分析
-
实体基础需求
- 文章(文章ID,用户ID,文章标题,文章访问量,文章评论数,文章点赞数,文章创建时间,文章更新时间,文章能否评论,文章状态,文章排序值,文章内容,文章摘要,文章缩略图)
- 分类(分类ID,父亲ID,分类名称,分类描述,分类排序值,分类图标)
- 标签(标签ID,标签名称,标签描述)
- 用户(用户ID,用户名,密码,用户昵称,用户邮箱,用户主页url,用户头像,用户上次登录IP,用户注册时间,用户上次登录时间,用户状态,用户角色)
- 评论(评论ID,上级评论人ID,上级评论人名称,评论文章ID,评论人昵称,评论人email,评论人主页url,评论人头像,评论内容,评论浏览器信息,评论IP,评论时间,评论角色,评论用户ID)
------------------------下方为管理员管理内容-------------------------------
- 链接(链接ID,链接url,链接名称,链接头像,链接描述,链接所属人昵称,链接所属人联系方式,链接创建时间,链接更新时间,链接排序值,链接状态)
- 菜单(菜单ID,菜单名称,菜单url,菜单等级,菜单图标,菜单排序值)
- 公告(公告ID,公告标题,公告内容,公告创建时间,公告更新时间,公告状态,公告排序值)
- 基本信息(基本信息ID,站点标题,站点描述,媒体描述,媒体关键字,相关站点头像,相关站点标题,相关站点内容,相关站点微信,相关站点QQ,相关站点GitHub,相关站点微博,基本信息统计,基本信息状态)
- 页面(页面ID,页面别称key,页面标题,页面内容,页面创建时间,页面更新时间,页面访问量,页面评论数,页面状态)
-
关系模式
- 文章:分类 = m:n
- 文章:标签 = m:n
- 文章:用户 = n:1
- 文章:评论 = 1:n
- 父分类:子分类 = 1:1
- 用户:评论 = 1:n
- 父评论:子评论 = 1:1
-
加入关系模式后的实体类设计
- 文章(文章ID,文章标题,文章访问量,文章评论数,文章点赞数,文章创建时间,文章更新时间,文章能否评论,文章状态,文章排序值,文章内容,文章摘要,文章缩略图,用户ID)
- PK:文章ID,用户ID
- FK:用户ID
- 分类(分类ID,父亲分类ID,分类名称,分类描述,分类排序值,分类图标)
- PK:分类ID,父亲分类ID
- FK:父亲分类ID
- 标签(标签ID,标签名称,标签描述)
- PK:标签ID
- FK:
- 用户(用户ID,用户名,密码,用户昵称,用户邮箱,用户主页url,用户头像,用户上次登录IP,用户注册时间,用户上次登录时间,用户状态,用户角色)
- PK:用户ID
- FK:
- 评论(评论ID,评论人昵称,评论人email,评论人主页url,评论人头像,评论内容,评论浏览器信息,评论IP,评论时间,评论角色,上级评论人ID,上级评论人名称,评论文章ID,评论用户ID)
- PK:评论ID,评论文章ID,上级评论人ID,评论用户ID
- FK:评论文章ID,上级评论人ID,评论用户ID
- 文章与分类关系(文章ID,分类ID)
- PK:文章ID,分类ID
- FK:文章ID,分类ID
- 文章与标签关系(文章ID,标签ID)
- PK:文章ID,标签ID
- FK:文章ID,标签ID
------------------------下方为管理员管理内容-------------------------------
- 链接(链接ID,链接url,链接名称,链接头像,链接描述,链接所属人昵称,链接所属人联系方式,链接创建时间,链接更新时间,链接排序值,链接状态)
- PK:链接ID
- FK:
- 菜单(菜单ID,菜单名称,菜单url,菜单等级,菜单图标,菜单排序值)
- PK:菜单ID
- FK:
- 公告(公告ID,公告标题,公告内容,公告创建时间,公告更新时间,公告状态,公告排序值)
- PK:公告ID
- FK:
- 基本信息(基本信息ID,站点标题,站点描述,媒体描述,媒体关键字,相关站点头像,相关站点标题,相关站点内容,相关站点微信,相关站点QQ,相关站点GitHub,相关站点微博,基本信息统计,基本信息状态)
- PK:基本信息ID
- FK:
- 页面(页面ID,页面别称key,页面标题,页面内容,页面创建时间,页面更新时间,页面访问量,页面评论数,页面状态)
- PK:页面ID
- FK:
- 文章(文章ID,文章标题,文章访问量,文章评论数,文章点赞数,文章创建时间,文章更新时间,文章能否评论,文章状态,文章排序值,文章内容,文章摘要,文章缩略图,用户ID)
-
为增加查询效率,增加冗余,最终实体类设计
- 文章(文章ID,文章标题,文章访问量,文章评论数,文章点赞数,文章创建时间,文章更新时间,文章能否评论,文章状态,文章排序值,文章内容,文章摘要,文章缩略图,用户ID,用户,标签列表,分类列表)
- PK:文章ID,用户ID
- FK:用户ID
- 冗余属性:用户,标签列表,分类列表
- 分类(分类ID,父亲分类ID,分类名称,分类描述,分类排序值,分类图标,该分类下的文章数量)
- PK:分类ID,父亲分类ID
- FK:父亲分类ID
- 冗余属性:该分类下的文章总数
- 标签(标签ID,标签名称,标签描述,该标签下的文章数量)
- PK:标签ID
- FK:
- 冗余属性:该标签下的文章总数
- 用户(用户ID,用户名,密码,用户昵称,用户邮箱,用户主页url,用户头像,用户上次登录IP,用户注册时间,用户上次登录时间,用户状态,用户角色,该用户写的文章数量)
- PK:用户ID
- FK:
- 冗余属性:该用户写的文章数量
- 评论(评论ID,评论人昵称,评论人email,评论人主页url,评论人头像,评论内容,评论浏览器信息,评论IP,评论时间,评论角色,上级评论人ID,上级评论人名称,评论文章ID,评论用户ID,文章)
- PK:评论ID,评论文章ID,上级评论人ID,评论用户ID
- FK:评论文章ID,上级评论人ID,评论用户ID
- 冗余属性:文章
- 文章与分类关系(文章ID,分类ID)
- PK:文章ID,分类ID
- FK:文章ID,分类ID
- 文章与标签关系(文章ID,标签ID)
- PK:文章ID,标签ID
- FK:文章ID,标签ID
------------------------下方为管理员管理内容-------------------------------
- 链接(链接ID,链接url,链接名称,链接头像,链接描述,链接所属人昵称,链接所属人联系方式,链接创建时间,链接更新时间,链接排序值,链接状态)
- PK:链接ID
- FK:
- 菜单(菜单ID,菜单名称,菜单url,菜单等级,菜单图标,菜单排序值)
- PK:菜单ID
- FK:
- 公告(公告ID,公告标题,公告内容,公告创建时间,公告更新时间,公告状态,公告排序值)
- PK:公告ID
- FK:
- 基本信息(基本信息ID,站点标题,站点描述,媒体描述,媒体关键字,相关站点头像,相关站点标题,相关站点内容,相关站点微信,相关站点QQ,相关站点GitHub,相关站点微博,基本信息统计,基本信息状态)
- PK:基本信息ID
- FK:
- 页面(页面ID,页面别称key,页面标题,页面内容,页面创建时间,页面更新时间,页面访问量,页面评论数,页面状态)
- PK:页面ID
- FK:
- 文章(文章ID,文章标题,文章访问量,文章评论数,文章点赞数,文章创建时间,文章更新时间,文章能否评论,文章状态,文章排序值,文章内容,文章摘要,文章缩略图,用户ID,用户,标签列表,分类列表)
├─entity
│ Article.java
│ ArticleCategoryRef.java
│ ArticleTagRef.java
│ Category.java
│ Comment.java
│ Link.java
│ Menu.java
│ Notice.java
│ Options.java
│ Page.java
│ Tag.java
│ User.java
-
该目录下的实体类均采用@Data注解,简化代码。
-
@Data 的用途是:注在类上,提供类的get、set、equals、hashCode、toString等方法。
-
使用该注解需要引入lombok依赖,idea中需要引入lombok相关插件。
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.16.22</version> </dependency>
2.2.1 Article
-
com.liuyanzhao.ssm.blog.entity.Article
package com.liuyanzhao.ssm.blog.entity;import lombok.Data;import java.io.Serializable; import java.util.Date; import java.util.List;/*** @author liuyanzhao*/ @Data public class Article implements Serializable{private static final long serialVersionUID = 5207865247400761539L;// 文章IDprivate Integer articleId;// 文章用户IDprivate Integer articleUserId;// 文章标题private String articleTitle;// 文章访问量private Integer articleViewCount;// 文章评论数private Integer articleCommentCount;// 文章点赞数private Integer articleLikeCount;// 文章创建时间private Date articleCreateTime;// 文章更新时间private Date articleUpdateTime;// 文章是否允许评论private Integer articleIsComment;// 文章状态private Integer articleStatus;// 文章排序值private Integer articleOrder;// 文章内容private String articleContent;// 文章摘要private String articleSummary;// 文章缩略图private String articleThumbnail;private User user;private List<Tag> tagList;private List<Category> categoryList; }
-
文章实体类
- 增加了三个非数据库属性
- User:用户
- tagList:标签列表
- categoryList:分类列表
- 增加了三个非数据库属性
-
数据库设计
-
2.2.2 ArticleCategoryRef
-
com.liuyanzhao.ssm.blog.entity.ArticleCategoryRef
package com.liuyanzhao.ssm.blog.entity;import lombok.Data;import java.io.Serializable;/*** 文章分类关联表** @author liuyanzhao*/ @Data public class ArticleCategoryRef implements Serializable{private static final long serialVersionUID = -6809206515467725995L;// 文章IDprivate Integer articleId;// 分类IDprivate Integer categoryId;public ArticleCategoryRef() {}public ArticleCategoryRef(Integer articleId, Integer categoryId) {this.articleId = articleId;this.categoryId = categoryId;} }
-
文章分类关联表实体类
-
数据库设计
-
2.2.3 ArticleTagRef
-
com.liuyanzhao.ssm.blog.entity.ArticleTagRef
package com.liuyanzhao.ssm.blog.entity;import lombok.Data;import java.io.Serializable;/*** 文章和标签关联** @author 言曌* @date 2018/11/17 下午5:20*/ @Data public class ArticleTagRef implements Serializable {private static final long serialVersionUID = -5816783232020910492L;// 文章IDprivate Integer articleId;// 标签IDprivate Integer tagId;public ArticleTagRef() {}public ArticleTagRef(Integer articleId, Integer tagId) {this.articleId = articleId;this.tagId = tagId;} }
-
文章和标签关联实体类
-
数据库设计
-
2.2.4 Category
-
com.liuyanzhao.ssm.blog.entity.Category
package com.liuyanzhao.ssm.blog.entity;import lombok.Data;import java.io.Serializable;/*** @author liuyanzhao*/ @Data public class Category implements Serializable {private static final long serialVersionUID = 6687286913317513141L;// 分类IDprivate Integer categoryId;// 分类父IDprivate Integer categoryPid;// 分类名称private String categoryName;// 分类描述private String categoryDescription;// 分类排序值private Integer categoryOrder;// 分类图标private String categoryIcon;/*** 文章数量(非数据库字段)*/private Integer articleCount;public Category(Integer categoryId, Integer categoryPid, String categoryName, String categoryDescription, Integer categoryOrder, String categoryIcon,Integer articleCount) {this.categoryId = categoryId;this.categoryPid = categoryPid;this.categoryName = categoryName;this.categoryDescription = categoryDescription;this.categoryOrder = categoryOrder;this.categoryIcon = categoryIcon;this.articleCount = articleCount;}public Category(Integer categoryId, String categoryName) {this.categoryId = categoryId;this.categoryName = categoryName;}public Category(Integer categoryId) {this.categoryId = categoryId;}public Category() {}/*** 未分类** @return 分类*/public static Category Default() {return new Category(100000000, "未分类");} }
-
分类实体类
- 增加了一个非数据库属性
- articleCount:该分类下的文章数量
- 设计了构造方法,包括:
- 仅有分类ID
- 有分类ID、分类名称
- 全参
- 设置了一个静态方法:Default(),用于返回一个固定内容的未分类对象
- 增加了一个非数据库属性
-
数据库设计
-
2.2.5 Comment
-
com.liuyanzhao.ssm.blog.entity.Comment
package com.liuyanzhao.ssm.blog.entity;import lombok.Data;import java.io.Serializable; import java.util.Date;/*** 文章评论** @author liuyanzhao*/ @Data public class Comment implements Serializable {private static final long serialVersionUID = -1038897351672911219L;// 评论IDprivate Integer commentId;// 上级评论IDprivate Integer commentPid;// 上级评论名称private String commentPname;// 文章IDprivate Integer commentArticleId;// 评论人名称private String commentAuthorName;// 评论人邮箱private String commentAuthorEmail;// 评论人个人主页private String commentAuthorUrl;// 评论人头像private String commentAuthorAvatar;// 内容private String commentContent;// 浏览器信息private String commentAgent;// IPprivate String commentIp;// 评论时间private Date commentCreateTime;/*** 角色(管理员1,访客0)*/private Integer commentRole;/*** 评论用户ID*/private Integer commentUserId;/*** 非数据库字段*/private Article article; }
-
评论实体类
- 增加了一个非数据库属性:article:文章
-
数据库设计
-
2.2.6 Link
-
com.liuyanzhao.ssm.blog.entity.Link
package com.liuyanzhao.ssm.blog.entity;import lombok.Data;import java.io.Serializable; import java.util.Date;/*** @author liuyanzhao*/ @Data public class Link implements Serializable{private static final long serialVersionUID = -259829372268790508L;// 链接IDprivate Integer linkId;// URLprivate String linkUrl;// 姓名private String linkName;// 头像private String linkImage;// 描述private String linkDescription;// 所属人名称private String linkOwnerNickname;// 联系方式private String linkOwnerContact;// 更新时间private Date linkUpdateTime;// 创建时间private Date linkCreateTime;// 排序号private Integer linkOrder;// 状态private Integer linkStatus;}
-
连接实体类
-
数据库设计
-
2.2.7 Menu
-
com.liuyanzhao.ssm.blog.entity.Menu
package com.liuyanzhao.ssm.blog.entity;import lombok.Data;import java.io.Serializable;/*** @author liuyanzhao*/ @Data public class Menu implements Serializable {private static final long serialVersionUID = 489914127235951698L;// 菜单IDprivate Integer menuId;// 名称private String menuName;// URLprivate String menuUrl;// 等级private Integer menuLevel;// 图标private String menuIcon;// 排序值private Integer menuOrder;}
-
菜单实体类
-
数据库设计
-
2.2.8 Notice
-
com.liuyanzhao.ssm.blog.entity.Notice
package com.liuyanzhao.ssm.blog.entity;import lombok.Data;import java.io.Serializable; import java.util.Date;/*** @author liuyanzhao*/ @Data public class Notice implements Serializable{private static final long serialVersionUID = -4901560494243593100L;// 公告IDprivate Integer noticeId;// 公告标题private String noticeTitle;// 内容private String noticeContent;// 创建时间private Date noticeCreateTime;// 更新时间private Date noticeUpdateTime;// 状态private Integer noticeStatus;// 排序值private Integer noticeOrder; }
-
公告实体类
-
数据库设计
-
2.2.9 Options
-
com.liuyanzhao.ssm.blog.entity.Options
package com.liuyanzhao.ssm.blog.entity;import lombok.Data;import java.io.Serializable;/*** @author liuyanzhao*/ @Data public class Options implements Serializable{private static final long serialVersionUID = -776792869602511933L;// private Integer optionId;// private String optionSiteTitle;// private String optionSiteDescrption;// private String optionMetaDescrption;// private String optionMetaKeyword;// private String optionAboutsiteAvatar;// private String optionAboutsiteTitle;// private String optionAboutsiteContent;// private String optionAboutsiteWechat;// private String optionAboutsiteQq;// private String optionAboutsiteGithub;// private String optionAboutsiteWeibo;// private String optionTongji;// private Integer optionStatus;}
-
系统设置实体类
-
数据库设计
-
2.2.10 Page
-
com.liuyanzhao.ssm.blog.entity.Page
package com.liuyanzhao.ssm.blog.entity;import lombok.Data;import java.io.Serializable; import java.util.Date;/*** @author liuyanzhao*/ @Data public class Page implements Serializable{private static final long serialVersionUID = 3927496662110298634L;// 自定义页面IDprivate Integer pageId;// keyprivate String pageKey;// 标题private String pageTitle;// 内容private String pageContent;// 创建时间private Date pageCreateTime;// 更新时间private Date pageUpdateTime;// 访问量private Integer pageViewCount;// 评论数private Integer pageCommentCount;// 状态private Integer pageStatus;}
-
页面实体类
-
数据库设计
-
2.2.11 Tag
-
com.liuyanzhao.ssm.blog.entity.Tag
package com.liuyanzhao.ssm.blog.entity;import lombok.Data;import java.io.Serializable;/*** @author liuyanzhao*/ @Data public class Tag implements Serializable{private static final long serialVersionUID = 605449151900057035L;// 标签IDprivate Integer tagId;// 标签名称private String tagName;// 描述private String tagDescription;/*** 文章数量(不是数据库字段)*/private Integer articleCount;public Tag() {}public Tag(Integer tagId) {this.tagId = tagId;}public Tag(Integer tagId, String tagName, String tagDescription, Integer articleCount) {this.tagId = tagId;this.tagName = tagName;this.tagDescription = tagDescription;this.articleCount = articleCount;} }
-
标签实体类
- 增加了一个非数据库属性:articleCount:文章数量总计
- 增加了三个构造方法
- 无参
- 单一标签ID
- 全参
-
数据库设计
-
2.2.12 User
-
com.liuyanzhao.ssm.blog.entity.User
package com.liuyanzhao.ssm.blog.entity;import lombok.Data;import java.io.Serializable; import java.util.Date;/*** @author liuyanzhao*/ @Data public class User implements Serializable{private static final long serialVersionUID = -4415517704211731385L;// 用户IDprivate Integer userId;// 用户名private String userName;// 密码private String userPass;// 昵称private String userNickname;// 邮箱private String userEmail;// 个人主页private String userUrl;// 头像private String userAvatar;// 上次登录IPprivate String userLastLoginIp;// 注册时间private Date userRegisterTime;// 上次登录时间private Date userLastLoginTime;// 状态private Integer userStatus;/*** 用户角色:admin/user*/private String userRole;/*** 文章数量(不是数据库字段)*/private Integer articleCount;}
-
用户实体类
- 增加一个非数据库属性:articleCount:发布文章总数
-
数据库设计
-
2.3 enums枚举类
├─enums
│ ArticleCommentStatus.java
│ ArticleStatus.java
│ CategoryStatus.java
│ LinkStatus.java
│ MenuLevel.java
│ NoticeStatus.java
│ PageStatus.java
│ Role.java
│ UserRole.java
2.3.1 ArticleCommentStatus
-
com.liuyanzhao.ssm.blog.enums.ArticleCommentStatus
package com.liuyanzhao.ssm.blog.enums;/*** @author 言曌* @date 2018/11/17 下午4:47*/public enum ArticleCommentStatus {ALLOW(1, "允许"),NOT_ALLOW(0, "不允许");private Integer value;private String message;ArticleCommentStatus(Integer value, String message) {this.value = value;this.message = message;}public Integer getValue() {return value;}public void setValue(Integer value) {this.value = value;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;} }
- 文章是否允许评论
- 1:允许
- 0:不允许
- 文章是否允许评论
2.3.2 ArticleStatus
-
com.liuyanzhao.ssm.blog.enums.ArticleStatus
package com.liuyanzhao.ssm.blog.enums;/*** @author 言曌* @date 2018/11/17 下午4:47*/public enum ArticleStatus {PUBLISH(1, "已发布"),DRAFT(0, "草稿");private Integer value;private String message;ArticleStatus(Integer value, String message) {this.value = value;this.message = message;}public Integer getValue() {return value;}public void setValue(Integer value) {this.value = value;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;} }
- 文章状态
- 1:已发布
- 0:草稿
- 文章状态
2.3.3 CategoryStatus
-
com.liuyanzhao.ssm.blog.enums.CategoryStatus
package com.liuyanzhao.ssm.blog.enums;import lombok.Data;/*** @author 言曌* @date 2018/11/17 下午4:47*/public enum CategoryStatus {NORMAL(1, "正常"),HIDDEN(0, "隐藏");private Integer value;private String message;CategoryStatus(Integer value, String message) {this.value = value;this.message = message;}public Integer getValue() {return value;}public void setValue(Integer value) {this.value = value;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;} }
- 分类状态
- 1:正常
- 0:隐藏
- 分类状态
2.3.4 LinkStatus
-
com.liuyanzhao.ssm.blog.enums.LinkStatus
package com.liuyanzhao.ssm.blog.enums;/*** @author 言曌* @date 2018/11/17 下午4:47*/public enum LinkStatus {NORMAL(1, "显示"),HIDDEN(0, "隐藏");private Integer value;private String message;LinkStatus(Integer value, String message) {this.value = value;this.message = message;}public Integer getValue() {return value;}public void setValue(Integer value) {this.value = value;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;} }
- 链接状态
- 1:显示
- 0:隐藏
- 链接状态
2.3.5 MenuLevel
-
com.liuyanzhao.ssm.blog.enums.MenuLevel
package com.liuyanzhao.ssm.blog.enums;/*** @author 言曌* @date 2018/11/17 下午4:47*/public enum MenuLevel {TOP_MENU(1, "顶部菜单"),MAIN_MENU(2, "主体菜单");private Integer value;private String message;MenuLevel(Integer value, String message) {this.value = value;this.message = message;}public Integer getValue() {return value;}public void setValue(Integer value) {this.value = value;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;} }
- 菜单等级
- 1:顶部菜单
- 2:主体菜单
- 菜单等级
2.3.6 NoticeStatus
-
com.liuyanzhao.ssm.blog.enums.NoticeStatus
package com.liuyanzhao.ssm.blog.enums;/*** @author 言曌* @date 2018/11/17 下午4:47*/public enum NoticeStatus {NORMAL(1, "显示"),HIDDEN(0, "隐藏");private Integer value;private String message;NoticeStatus(Integer value, String message) {this.value = value;this.message = message;}public Integer getValue() {return value;}public void setValue(Integer value) {this.value = value;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;} }
- 通知状态
- 1:显示
- 0:隐藏
- 通知状态
2.3.7 PageStatus
-
com.liuyanzhao.ssm.blog.enums.PageStatus
package com.liuyanzhao.ssm.blog.enums;/*** @author 言曌* @date 2018/11/17 下午4:47*/public enum PageStatus {NORMAL(1, "显示"),HIDDEN(0, "隐藏");private Integer value;private String message;PageStatus(Integer value, String message) {this.value = value;this.message = message;}public Integer getValue() {return value;}public void setValue(Integer value) {this.value = value;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;} }
- 页面状态
- 1:显示
- 0:隐藏
- 页面状态
2.3.8 Role
-
com.liuyanzhao.ssm.blog.enums.Role
package com.liuyanzhao.ssm.blog.enums;/*** @author 言曌* @date 2018/11/17 下午4:47*/public enum Role {OWNER(1, "博主"),VISITOR(0, "其他用户");private Integer value;private String message;Role(Integer value, String message) {this.value = value;this.message = message;}public Integer getValue() {return value;}public void setValue(Integer value) {this.value = value;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;} }
- 浏览角色
- 1:博主
- 0:其他用户
- 浏览角色
2.3.9 UserRole
-
com.liuyanzhao.ssm.blog.enums.UserRole
package com.liuyanzhao.ssm.blog.enums;/*** 角色枚举** @author 言曌* @date 2021/2/25 2:31 下午*/public enum UserRole {ADMIN("admin", "管理员"),USER("user", "用户");private String value;private String message;UserRole(String value, String message) {this.value = value;this.message = message;}public String getValue() {return value;}public void setValue(String value) {this.value = value;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;} }
- 用户角色
- admin:管理员
- user:用户
- 用户角色
2.4 dto数据传输对象
├─dto
│ ArticleParam.java
│ JsonResult.java
│ ResultVO.java
│ UploadFileVO.java
2.4.1 ArticleParam
-
com.liuyanzhao.ssm.blog.dto.ArticleParam
package com.liuyanzhao.ssm.blog.dto;import lombok.Data;import java.util.List;/*** @author 言曌* @date 2018/11/25 下午3:56*/ @Data public class ArticleParam {private Integer articleId;private String articleTitle;private String articleContent;private Integer articleParentCategoryId;private Integer articleChildCategoryId;private Integer articleOrder;private Integer articleStatus;private String articleThumbnail;private List<Integer> articleTagIds;}
- 文章参数
2.4.2 JsonResult
-
com.liuyanzhao.ssm.blog.dto.JsonResult
package com.liuyanzhao.ssm.blog.dto;import lombok.Data;/*** @author 言曌* @date 2017/11/30 下午7:04*/@Data public class JsonResult<T> {/*** 错误码*/private Integer code;/*** 提示信息*/private String msg;/*** 返回的具体内容*/private T data;public JsonResult(Integer code, String msg, T data) {this.code = code;this.msg = msg;this.data = data;}public JsonResult() {}public JsonResult fail() {return new JsonResult(1, "操作失败", null);}public JsonResult fail(String msg) {return new JsonResult(1, msg, null);}public JsonResult ok() {return new JsonResult(0, "操作成功", null);}public JsonResult ok(T data) {return new JsonResult(0, "操作成功", data);} }
- json传输结果
2.4.3 ResultVO
-
com.liuyanzhao.ssm.blog.dto.ResultVO
package com.liuyanzhao.ssm.blog.dto;import lombok.Data;/*** @author 言曌* @date 2017/11/30 下午7:04*/@Data public class ResultVO<T> {/*** 错误码*/private Integer code;/*** 提示信息*/private String msg;/*** 返回的具体内容*/private T data;public ResultVO(Integer code, String msg, T data) {this.code = code;this.msg = msg;this.data = data;}public ResultVO() {} }
- 结果显示层对象
2.4.4 UploadFileVO
-
com.liuyanzhao.ssm.blog.dto.UploadFileVO
package com.liuyanzhao.ssm.blog.dto;import lombok.Data;/*** @author 言曌* @date 2017/11/30 下午7:41*/@Data public class UploadFileVO {private String src;private String title;}
- 上传文件显示层对象
2.5 util工具类
└─util
│ MyUtils.java
│
└─interceptor
AdminInterceptor.java
HomeResourceInterceptor.java
LoginInterceptor.java
2.5.1 MyUtils 我的工具类
-
com.liuyanzhao.ssm.blog.util.MyUtils
package com.liuyanzhao.ssm.blog.util;import javax.servlet.http.HttpServletRequest; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException;/*** 常用的方法* Created by 言曌 on 2017/8/24.*/public class MyUtils {/*** 获得IP地址** @param request* @return*/public static String getIpAddr(HttpServletRequest request) {String ipAddress = request.getHeader("x-forwarded-for");if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("Proxy-Client-IP");}if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("WL-Proxy-Client-IP");}if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getRemoteAddr();}//对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割if (ipAddress != null && ipAddress.length() > 15) {if (ipAddress.indexOf(",") > 0) {ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));}}return ipAddress;}/*** 获得Md5加密** @param str 原字符串* @return 加密后的字符串*/public static String strToMd5(String str) {String md5Str = null;if (str != null && str.length() != 0) {try {MessageDigest md = MessageDigest.getInstance("MD5");md.update(str.getBytes());byte b[] = md.digest();int i;StringBuffer buf = new StringBuffer("");for (int offset = 0; offset < b.length; offset++) {i = b[offset];if (i < 0) {i += 256;}if (i < 16) {buf.append("0");}buf.append(Integer.toHexString(i));}//32位md5Str = buf.toString();//16位//md5Str = buf.toString().substring(8, 24);} catch (NoSuchAlgorithmException e) {e.printStackTrace();}}return md5Str;}/*** 根据email获取gravatar头像** @param email Email* @return 头像URL*/public static String getGravatar(String email) {String emailMd5 = strToMd5(email);//设置图片大小32pxString avatar = "http://cn.gravatar.com/avatar/" + emailMd5 + "?s=128&d=identicon&r=PG";return avatar;}}
-
getIpAddr(HttpServletRequest request)
-
获得IP地址
- @param request HttpServletRequest请求
- @return IP地址
-
源代码
public static String getIpAddr(HttpServletRequest request) {String ipAddress = request.getHeader("x-forwarded-for");if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("Proxy-Client-IP");}if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("WL-Proxy-Client-IP");}if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getRemoteAddr();}//对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割if (ipAddress != null && ipAddress.length() > 15) {if (ipAddress.indexOf(",") > 0) {ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));}}return ipAddress; }
-
自上而下分别从
request.getHeader("x-forwarded-for")
;、request.getHeader("Proxy-Client-IP");
、request.getHeader("WL-Proxy-Client-IP");
和request.getRemoteAddr();
获取IP地址,若未从上方获取则进入下层获取。 -
获取完毕后,若是多个代理的情况,则取第一个IP为客户端真实IP
-
-
String strToMd5(String str)
-
获得Md5加密
- @param str 原字符串
- @return 加密后的字符串
-
源代码
public static String strToMd5(String str) {String md5Str = null;if (str != null && str.length() != 0) {try {MessageDigest md = MessageDigest.getInstance("MD5");md.update(str.getBytes());byte b[] = md.digest();int i;StringBuffer buf = new StringBuffer("");for (int offset = 0; offset < b.length; offset++) {i = b[offset];if (i < 0) {i += 256;}if (i < 16) {buf.append("0");}buf.append(Integer.toHexString(i));}//32位md5Str = buf.toString();//16位//md5Str = buf.toString().substring(8, 24);} catch (NoSuchAlgorithmException e) {e.printStackTrace();}}
-
-
String getGravatar(String email)
-
根据email获取gravatar头像
- @param email Email
- @return 头像URL
-
源代码
public static String getGravatar(String email) {String emailMd5 = strToMd5(email);//设置图片大小32pxString avatar = "http://cn.gravatar.com/avatar/" + emailMd5 + "?s=128&d=identicon&r=PG";return avatar; }
-
-
2.2.11 Tag
-
com.liuyanzhao.ssm.blog.entity.Tag
package com.liuyanzhao.ssm.blog.entity;import lombok.Data;import java.io.Serializable;/*** @author liuyanzhao*/ @Data public class Tag implements Serializable{private static final long serialVersionUID = 605449151900057035L;// 标签IDprivate Integer tagId;// 标签名称private String tagName;// 描述private String tagDescription;/*** 文章数量(不是数据库字段)*/private Integer articleCount;public Tag() {}public Tag(Integer tagId) {this.tagId = tagId;}public Tag(Integer tagId, String tagName, String tagDescription, Integer articleCount) {this.tagId = tagId;this.tagName = tagName;this.tagDescription = tagDescription;this.articleCount = articleCount;} }
-
标签实体类
- 增加了一个非数据库属性:articleCount:文章数量总计
- 增加了三个构造方法
- 无参
- 单一标签ID
- 全参
-
数据库设计
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pbeg5QkS-1675858523534)(C:\Users\ShiningSong\AppData\Roaming\Typora\typora-user-images\image-20230205151553132.png)]
-
2.2.12 User
-
com.liuyanzhao.ssm.blog.entity.User
package com.liuyanzhao.ssm.blog.entity;import lombok.Data;import java.io.Serializable; import java.util.Date;/*** @author liuyanzhao*/ @Data public class User implements Serializable{private static final long serialVersionUID = -4415517704211731385L;// 用户IDprivate Integer userId;// 用户名private String userName;// 密码private String userPass;// 昵称private String userNickname;// 邮箱private String userEmail;// 个人主页private String userUrl;// 头像private String userAvatar;// 上次登录IPprivate String userLastLoginIp;// 注册时间private Date userRegisterTime;// 上次登录时间private Date userLastLoginTime;// 状态private Integer userStatus;/*** 用户角色:admin/user*/private String userRole;/*** 文章数量(不是数据库字段)*/private Integer articleCount;}
-
用户实体类
- 增加一个非数据库属性:articleCount:发布文章总数
-
数据库设计
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AljMObZN-1675858523535)(C:\Users\ShiningSong\AppData\Roaming\Typora\typora-user-images\image-20230205151644431.png)]
-
2.3 enums枚举类
├─enums
│ ArticleCommentStatus.java
│ ArticleStatus.java
│ CategoryStatus.java
│ LinkStatus.java
│ MenuLevel.java
│ NoticeStatus.java
│ PageStatus.java
│ Role.java
│ UserRole.java
2.3.1 ArticleCommentStatus
-
com.liuyanzhao.ssm.blog.enums.ArticleCommentStatus
package com.liuyanzhao.ssm.blog.enums;/*** @author 言曌* @date 2018/11/17 下午4:47*/public enum ArticleCommentStatus {ALLOW(1, "允许"),NOT_ALLOW(0, "不允许");private Integer value;private String message;ArticleCommentStatus(Integer value, String message) {this.value = value;this.message = message;}public Integer getValue() {return value;}public void setValue(Integer value) {this.value = value;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;} }
- 文章是否允许评论
- 1:允许
- 0:不允许
- 文章是否允许评论
2.3.2 ArticleStatus
-
com.liuyanzhao.ssm.blog.enums.ArticleStatus
package com.liuyanzhao.ssm.blog.enums;/*** @author 言曌* @date 2018/11/17 下午4:47*/public enum ArticleStatus {PUBLISH(1, "已发布"),DRAFT(0, "草稿");private Integer value;private String message;ArticleStatus(Integer value, String message) {this.value = value;this.message = message;}public Integer getValue() {return value;}public void setValue(Integer value) {this.value = value;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;} }
- 文章状态
- 1:已发布
- 0:草稿
- 文章状态
2.3.3 CategoryStatus
-
com.liuyanzhao.ssm.blog.enums.CategoryStatus
package com.liuyanzhao.ssm.blog.enums;import lombok.Data;/*** @author 言曌* @date 2018/11/17 下午4:47*/public enum CategoryStatus {NORMAL(1, "正常"),HIDDEN(0, "隐藏");private Integer value;private String message;CategoryStatus(Integer value, String message) {this.value = value;this.message = message;}public Integer getValue() {return value;}public void setValue(Integer value) {this.value = value;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;} }
- 分类状态
- 1:正常
- 0:隐藏
- 分类状态
2.3.4 LinkStatus
-
com.liuyanzhao.ssm.blog.enums.LinkStatus
package com.liuyanzhao.ssm.blog.enums;/*** @author 言曌* @date 2018/11/17 下午4:47*/public enum LinkStatus {NORMAL(1, "显示"),HIDDEN(0, "隐藏");private Integer value;private String message;LinkStatus(Integer value, String message) {this.value = value;this.message = message;}public Integer getValue() {return value;}public void setValue(Integer value) {this.value = value;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;} }
- 链接状态
- 1:显示
- 0:隐藏
- 链接状态
2.3.5 MenuLevel
-
com.liuyanzhao.ssm.blog.enums.MenuLevel
package com.liuyanzhao.ssm.blog.enums;/*** @author 言曌* @date 2018/11/17 下午4:47*/public enum MenuLevel {TOP_MENU(1, "顶部菜单"),MAIN_MENU(2, "主体菜单");private Integer value;private String message;MenuLevel(Integer value, String message) {this.value = value;this.message = message;}public Integer getValue() {return value;}public void setValue(Integer value) {this.value = value;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;} }
- 菜单等级
- 1:顶部菜单
- 2:主体菜单
- 菜单等级
2.3.6 NoticeStatus
-
com.liuyanzhao.ssm.blog.enums.NoticeStatus
package com.liuyanzhao.ssm.blog.enums;/*** @author 言曌* @date 2018/11/17 下午4:47*/public enum NoticeStatus {NORMAL(1, "显示"),HIDDEN(0, "隐藏");private Integer value;private String message;NoticeStatus(Integer value, String message) {this.value = value;this.message = message;}public Integer getValue() {return value;}public void setValue(Integer value) {this.value = value;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;} }
- 通知状态
- 1:显示
- 0:隐藏
- 通知状态
2.3.7 PageStatus
-
com.liuyanzhao.ssm.blog.enums.PageStatus
package com.liuyanzhao.ssm.blog.enums;/*** @author 言曌* @date 2018/11/17 下午4:47*/public enum PageStatus {NORMAL(1, "显示"),HIDDEN(0, "隐藏");private Integer value;private String message;PageStatus(Integer value, String message) {this.value = value;this.message = message;}public Integer getValue() {return value;}public void setValue(Integer value) {this.value = value;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;} }
- 页面状态
- 1:显示
- 0:隐藏
- 页面状态
2.3.8 Role
-
com.liuyanzhao.ssm.blog.enums.Role
package com.liuyanzhao.ssm.blog.enums;/*** @author 言曌* @date 2018/11/17 下午4:47*/public enum Role {OWNER(1, "博主"),VISITOR(0, "其他用户");private Integer value;private String message;Role(Integer value, String message) {this.value = value;this.message = message;}public Integer getValue() {return value;}public void setValue(Integer value) {this.value = value;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;} }
- 浏览角色
- 1:博主
- 0:其他用户
- 浏览角色
2.3.9 UserRole
-
com.liuyanzhao.ssm.blog.enums.UserRole
package com.liuyanzhao.ssm.blog.enums;/*** 角色枚举** @author 言曌* @date 2021/2/25 2:31 下午*/public enum UserRole {ADMIN("admin", "管理员"),USER("user", "用户");private String value;private String message;UserRole(String value, String message) {this.value = value;this.message = message;}public String getValue() {return value;}public void setValue(String value) {this.value = value;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;} }
- 用户角色
- admin:管理员
- user:用户
- 用户角色
2.4 dto数据传输对象
├─dto
│ ArticleParam.java
│ JsonResult.java
│ ResultVO.java
│ UploadFileVO.java
2.4.1 ArticleParam
-
com.liuyanzhao.ssm.blog.dto.ArticleParam
package com.liuyanzhao.ssm.blog.dto;import lombok.Data;import java.util.List;/*** @author 言曌* @date 2018/11/25 下午3:56*/ @Data public class ArticleParam {private Integer articleId;private String articleTitle;private String articleContent;private Integer articleParentCategoryId;private Integer articleChildCategoryId;private Integer articleOrder;private Integer articleStatus;private String articleThumbnail;private List<Integer> articleTagIds;}
- 文章参数
2.4.2 JsonResult
-
com.liuyanzhao.ssm.blog.dto.JsonResult
package com.liuyanzhao.ssm.blog.dto;import lombok.Data;/*** @author 言曌* @date 2017/11/30 下午7:04*/@Data public class JsonResult<T> {/*** 错误码*/private Integer code;/*** 提示信息*/private String msg;/*** 返回的具体内容*/private T data;public JsonResult(Integer code, String msg, T data) {this.code = code;this.msg = msg;this.data = data;}public JsonResult() {}public JsonResult fail() {return new JsonResult(1, "操作失败", null);}public JsonResult fail(String msg) {return new JsonResult(1, msg, null);}public JsonResult ok() {return new JsonResult(0, "操作成功", null);}public JsonResult ok(T data) {return new JsonResult(0, "操作成功", data);} }
- json传输结果
2.4.3 ResultVO
-
com.liuyanzhao.ssm.blog.dto.ResultVO
package com.liuyanzhao.ssm.blog.dto;import lombok.Data;/*** @author 言曌* @date 2017/11/30 下午7:04*/@Data public class ResultVO<T> {/*** 错误码*/private Integer code;/*** 提示信息*/private String msg;/*** 返回的具体内容*/private T data;public ResultVO(Integer code, String msg, T data) {this.code = code;this.msg = msg;this.data = data;}public ResultVO() {} }
- 结果显示层对象
2.4.4 UploadFileVO
-
com.liuyanzhao.ssm.blog.dto.UploadFileVO
package com.liuyanzhao.ssm.blog.dto;import lombok.Data;/*** @author 言曌* @date 2017/11/30 下午7:41*/@Data public class UploadFileVO {private String src;private String title;}
- 上传文件显示层对象
2.5 util工具类
└─util
│ MyUtils.java
│
└─interceptor
AdminInterceptor.java
HomeResourceInterceptor.java
LoginInterceptor.java
2.5.1 MyUtils 我的工具类
-
com.liuyanzhao.ssm.blog.util.MyUtils
package com.liuyanzhao.ssm.blog.util;import javax.servlet.http.HttpServletRequest; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException;/*** 常用的方法* Created by 言曌 on 2017/8/24.*/public class MyUtils {/*** 获得IP地址** @param request* @return*/public static String getIpAddr(HttpServletRequest request) {String ipAddress = request.getHeader("x-forwarded-for");if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("Proxy-Client-IP");}if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("WL-Proxy-Client-IP");}if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getRemoteAddr();}//对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割if (ipAddress != null && ipAddress.length() > 15) {if (ipAddress.indexOf(",") > 0) {ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));}}return ipAddress;}/*** 获得Md5加密** @param str 原字符串* @return 加密后的字符串*/public static String strToMd5(String str) {String md5Str = null;if (str != null && str.length() != 0) {try {MessageDigest md = MessageDigest.getInstance("MD5");md.update(str.getBytes());byte b[] = md.digest();int i;StringBuffer buf = new StringBuffer("");for (int offset = 0; offset < b.length; offset++) {i = b[offset];if (i < 0) {i += 256;}if (i < 16) {buf.append("0");}buf.append(Integer.toHexString(i));}//32位md5Str = buf.toString();//16位//md5Str = buf.toString().substring(8, 24);} catch (NoSuchAlgorithmException e) {e.printStackTrace();}}return md5Str;}/*** 根据email获取gravatar头像** @param email Email* @return 头像URL*/public static String getGravatar(String email) {String emailMd5 = strToMd5(email);//设置图片大小32pxString avatar = "http://cn.gravatar.com/avatar/" + emailMd5 + "?s=128&d=identicon&r=PG";return avatar;}}
-
getIpAddr(HttpServletRequest request)
-
获得IP地址
- @param request HttpServletRequest请求
- @return IP地址
-
源代码
public static String getIpAddr(HttpServletRequest request) {String ipAddress = request.getHeader("x-forwarded-for");if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("Proxy-Client-IP");}if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getHeader("WL-Proxy-Client-IP");}if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress = request.getRemoteAddr();}//对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割if (ipAddress != null && ipAddress.length() > 15) {if (ipAddress.indexOf(",") > 0) {ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));}}return ipAddress; }
-
自上而下分别从
request.getHeader("x-forwarded-for")
;、request.getHeader("Proxy-Client-IP");
、request.getHeader("WL-Proxy-Client-IP");
和request.getRemoteAddr();
获取IP地址,若未从上方获取则进入下层获取。 -
获取完毕后,若是多个代理的情况,则取第一个IP为客户端真实IP
-
-
String strToMd5(String str)
-
获得Md5加密
- @param str 原字符串
- @return 加密后的字符串
-
源代码
public static String strToMd5(String str) {String md5Str = null;if (str != null && str.length() != 0) {try {MessageDigest md = MessageDigest.getInstance("MD5");md.update(str.getBytes());byte b[] = md.digest();int i;StringBuffer buf = new StringBuffer("");for (int offset = 0; offset < b.length; offset++) {i = b[offset];if (i < 0) {i += 256;}if (i < 16) {buf.append("0");}buf.append(Integer.toHexString(i));}//32位md5Str = buf.toString();//16位//md5Str = buf.toString().substring(8, 24);} catch (NoSuchAlgorithmException e) {e.printStackTrace();}}
-
-
String getGravatar(String email)
-
根据email获取gravatar头像
- @param email Email
- @return 头像URL
-
源代码
public static String getGravatar(String email) {String emailMd5 = strToMd5(email);//设置图片大小32pxString avatar = "http://cn.gravatar.com/avatar/" + emailMd5 + "?s=128&d=identicon&r=PG";return avatar; }
-
-