SSH整合之入门级例子:简易留言板(完整源码)

来源:互联网 发布:软件项目管理工具 编辑:程序博客网 时间:2024/05/26 05:52

一.环境说明

  • ※Windows 10 ver 1703
  • ※IDEA 2017 2.5
  • ※JDK 1.8
  • ※MySQL 5.7
  • ※Maven 3.5

二.框架说明

  • ※Spring 4.3.11
  • ※SpringMVC 4.3.11
  • ※Hibernate 5.2.11
  • ※Bootstrap 3.3.7
  • ※Flat UI 2.3

三.项目说明

利用SSH三大框架,实现一个留言页面,可以展示留言以及添加留言,基于注解.

四.源码

项目结构:
这里写图片描述

实体类:
Msg.class

package com.cs.qsx.domain;import com.alibaba.fastjson.annotation.JSONField;import javax.persistence.*;import java.util.Date;@Entity@Table(name = "tb_msg")public class Msg {    @Id //主键    @GeneratedValue(strategy = GenerationType.IDENTITY) //自增    private Integer id;    @Column(length = 10)    private String name;    @Column(length = 100)    private String context;    @Column(columnDefinition = "DATE") //指定属性在表中的字段类型    @JSONField(format = "yyyy-MM-dd")  //指定json格式化时如何格式化date    private Date createDate;    public Msg() {    }    public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getContext() {        return context;    }    public void setContext(String context) {        this.context = context;    }    public Date getCreateDate() {        return createDate;    }    public void setCreateDate(Date createDate) {        this.createDate = createDate;    }}

数据库连接配置
dbconfig.properties

jdbc.driverclass=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/Msg_Test?characterEncoding=UTF-8jdbc.username=rootjdbc.password=123456

Spring配置文件
applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?><!--Spring的约束文件 使用那些模块就标记那些模块的约束文档 --><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/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/context        http://www.springframework.org/schema/context/spring-context.xsd        http://www.springframework.org/schema/aop        http://www.springframework.org/schema/aop/spring-aop.xsd        http://www.springframework.org/schema/tx        http://www.springframework.org/schema/tx/spring-tx.xsd ">    <!--1、加载外部配置文件 -->    <context:property-placeholder location="classpath:dbconfig.properties" />    <context:component-scan base-package="com.cs.qsx.dao"></context:component-scan>    <context:component-scan base-package="com.cs.qsx.service"></context:component-scan>    <!--2、配置数据库连接池 -->    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"          init-method="init" destroy-method="close">        <!-- 基本属性 url、user、password -->        <property name="driverClassName" value="${jdbc.driverclass}" />        <property name="url" value="${jdbc.url}" />        <property name="username" value="${jdbc.username}" />        <property name="password" value="${jdbc.password}" />        <!-- 配置监控统计拦截的filters -->        <property name="filters" value="stat" />        <!-- 配置初始化大小、最小、最大 -->        <property name="maxActive" value="20" />        <property name="initialSize" value="1" />        <property name="minIdle" value="1" />        <!-- 配置获取连接等待超时的时间 -->        <property name="maxWait" value="60000" />        <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->        <property name="timeBetweenEvictionRunsMillis" value="60000" />        <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->        <property name="minEvictableIdleTimeMillis" value="300000" />        <property name="testWhileIdle" value="true" />        <property name="testOnBorrow" value="false" />        <property name="testOnReturn" value="false" />        <!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->        <property name="poolPreparedStatements" value="true" />        <property name="maxOpenPreparedStatements" value="20" />    </bean>    <!-- 3、配置SessionFactory -->    <bean id="sessionFactory"          class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">        <!--配置数据库连接池 -->        <property name="dataSource" ref="dataSource"></property>        <!--Hibernate的设置信息 -->        <property name="hibernateProperties">            <props>                <!--方言 -->                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL57Dialect</prop>                <!--显示SQL -->                <prop key="hibernate.show_sql">false</prop>                <!--格式化sql语句 -->                <prop key="hibernate.format_sql">false</prop>                <!--ddl自动语句 -->                <prop key="hibernate.hbm2ddl.auto">update</prop>                <!-- <prop key="hibernate.current_session_context_class">thread</prop> -->                <!-- 最好使用Spring中对SessionContext的子类 -->                <prop key="hibernate.current_session_context_class">org.springframework.orm.hibernate5.SpringSessionContext                </prop>            </props>        </property>        <!--扫描Hibernate注解的实体类包 -->        <property name="packagesToScan">            <value>com.cs.qsx.domain</value>        </property>    </bean>    <!--4、配置事务管理对象  -->    <bean id="txManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">        <property name="sessionFactory" ref="sessionFactory"></property>    </bean>    <!--配置AOP注解 -->    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>    <!--设置注解事务的管理对象 -->    <tx:annotation-driven transaction-manager="txManager"></tx:annotation-driven></beans>

SpringMVC配置文件
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:mvc="http://www.springframework.org/schema/mvc"    xmlns:context="http://www.springframework.org/schema/context"    xsi:schemaLocation="        http://www.springframework.org/schema/beans        http://www.springframework.org/schema/beans/spring-beans.xsd        http://www.springframework.org/schema/mvc        http://www.springframework.org/schema/mvc/spring-mvc.xsd        http://www.springframework.org/schema/context        http://www.springframework.org/schema/context/spring-context.xsd">    <mvc:annotation-driven>        <mvc:message-converters register-defaults="false">            <!--解决@Responcebody中文乱码问题 -->            <bean class="org.springframework.http.converter.StringHttpMessageConverter">                <constructor-arg value="UTF-8"></constructor-arg>            </bean>            <!--配合fastjson支持 -->            <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">                <property name="defaultCharset" value="UTF-8"></property>                <property name="supportedMediaTypes">                    <list>                        <value>application/json</value>                        <value>text/html;charset=UTF-8</value>                    </list>                </property>                <property name="fastJsonConfig" ref="fastJsonConfig"></property>            </bean>        </mvc:message-converters>    </mvc:annotation-driven>    <!--fastJsonConfig -->    <bean id="fastJsonConfig" class="com.alibaba.fastjson.support.config.FastJsonConfig">        <!--默认编码格式 -->        <property name="charset" value="UTF-8"></property>        <!--默认日期格式化格式 -->        <property name="dateFormat" value="yyyy-MM-dd"></property>        <property name="serializerFeatures">            <list>                <value>WriteNullListAsEmpty</value>            </list>        </property>    </bean>    <!--fastjson支持配置结束 -->    <!--放行静态资源 -->    <mvc:default-servlet-handler></mvc:default-servlet-handler>    <!--配置扫描包 -->    <context:component-scan base-package="com.cs.qsx.controller"></context:component-scan>    <!--视图解析器 -->    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">        <property name="prefix" value="/WEB-INF/jsp/"></property>        <property name="suffix" value=".jsp"></property>    </bean>     <bean id="multipartResolver"        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">        <!-- 上传文件大小上限,单位为字节(10MB) -->        <property name="maxUploadSize">            <value>10485760</value>        </property>        <!-- 请求的编码格式,必须和jSP的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1 -->        <property name="defaultEncoding">            <value>UTF-8</value>        </property>    </bean></beans>

项目配置文件
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">    <!--配置Spring -->    <listener>        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    </listener>    <context-param>        <param-name>contextConfigLocation</param-name>        <param-value>/WEB-INF/applicationContext*.xml</param-value>    </context-param>    <!--配置springmvc -->    <servlet>        <servlet-name>springmvc</servlet-name>        <servlet-class>            org.springframework.web.servlet.DispatcherServlet        </servlet-class>        <init-param>            <param-name>contextConfigLocation</param-name>            <param-value>/WEB-INF/springmvc-config.xml</param-value>        </init-param>        <load-on-startup>1</load-on-startup>    </servlet>    <servlet-mapping>        <servlet-name>springmvc</servlet-name>        <url-pattern>/</url-pattern>    </servlet-mapping>    <!--配置过滤器,解决post请求乱码 -->    <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>    </filter>    <filter-mapping>        <filter-name>characterEncodingFilter</filter-name>        <url-pattern>/*</url-pattern>    </filter-mapping>    <welcome-file-list>        <welcome-file>index.jsp</welcome-file>    </welcome-file-list></web-app>

Maven依赖
pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">  <modelVersion>4.0.0</modelVersion>  <groupId>com.cs.qsx</groupId>  <artifactId>SSH_Msg</artifactId>  <packaging>war</packaging>  <version>1.0-SNAPSHOT</version>  <name>SSH_Msg Maven Webapp</name>  <url>http://maven.apache.org</url>  <dependencies>    <dependency>      <groupId>junit</groupId>      <artifactId>junit</artifactId>      <version>3.8.1</version>      <scope>test</scope>    </dependency>    <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-aspects</artifactId>      <version>4.3.11.RELEASE</version>    </dependency>    <!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-orm</artifactId>      <version>4.3.11.RELEASE</version>    </dependency>    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-webmvc</artifactId>      <version>4.3.11.RELEASE</version>    </dependency>    <!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->    <dependency>      <groupId>org.hibernate</groupId>      <artifactId>hibernate-core</artifactId>      <version>5.2.11.Final</version>    </dependency>    <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->    <dependency>      <groupId>com.alibaba</groupId>      <artifactId>druid</artifactId>      <version>1.1.3</version>    </dependency>    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->    <dependency>      <groupId>mysql</groupId>      <artifactId>mysql-connector-java</artifactId>      <version>5.1.44</version>    </dependency>    <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->    <dependency>      <groupId>javax.servlet</groupId>      <artifactId>javax.servlet-api</artifactId>      <version>3.1.0</version>      <scope>provided</scope>    </dependency>    <dependency>      <groupId>junit</groupId>      <artifactId>junit</artifactId>      <version>RELEASE</version>    </dependency>    <!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->    <dependency>      <groupId>javax.servlet</groupId>      <artifactId>jstl</artifactId>      <version>1.2</version>    </dependency>    <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->    <dependency>      <groupId>javax.servlet.jsp</groupId>      <artifactId>javax.servlet.jsp-api</artifactId>      <version>2.3.1</version>      <scope>provided</scope>    </dependency>    <!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->    <dependency>      <groupId>commons-fileupload</groupId>      <artifactId>commons-fileupload</artifactId>      <version>1.3.3</version>    </dependency>    <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->    <dependency>      <groupId>com.alibaba</groupId>      <artifactId>fastjson</artifactId>      <version>1.2.38</version>    </dependency>  </dependencies>  <build>    <finalName>SSH_Msg</finalName>    <!--提高编译级别 -->    <plugins>      <plugin>        <groupId>org.apache.maven.plugins</groupId>        <artifactId>maven-compiler-plugin</artifactId>        <version>3.7.0</version>        <configuration>          <source>1.8</source>          <target>1.8</target>          <encoding>UTF-8</encoding>        </configuration>      </plugin>    </plugins>  </build></project>

页面
leaveMessage.jsp

<%--  Created by IntelliJ IDEA.  User: 17535  Date: 2017/10/11  Time: 8:31  To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head>    <title>留言板</title>    <link href="/css/vendor/bootstrap/css/bootstrap.min.css" rel="stylesheet">    <link href="/css/flat-ui.min.css" rel="stylesheet">    <script src="https://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>    <script src="/js/flat-ui.min.js"></script><script type="text/javascript">    function getMsg() {        var url = "${pageContext.request.contextPath}/api/msg";        $.ajax({            url:url,            type:"post",            dataType:"json",            success:function (result) {                var html1 = "<thead><tr><th>留言内容</th><th>留言人</th><th>留言时间</th></tr></thead>";                var innHtml = "";                for (var i=0;i<result.length;i++){                    var jsonObject = result[i];                    innHtml = innHtml + "<tr><td>"+jsonObject.context+"</td><td>"+jsonObject.name+"</td><td>"+jsonObject.createDate+"</td></tr>";                }                $("#msgtable").html(html1 + innHtml);            },            error:function () {                alert("请求失败");            }        });    }</script></head><body onload="getMsg()"><div class="main">    <h2>请输入留言</h2>    <div class="addMsg">        <form action="/addMsg" method="post" class="navbar-form navbar-left">            <div class="form-group">                <input class="form-control" type="text" name="context" placeholder="请输入留言" />&nbsp;&nbsp;&nbsp;&nbsp;                <input class="form-control" type="text" name="name" placeholder="请输入姓名" />&nbsp;&nbsp;&nbsp;&nbsp;                <button class="btn btn-primary btn-small" type="submit">留言</button>&nbsp;&nbsp;                <button class="btn btn-warning btn-small" type="reset">清空</button>            </div>        </form>    </div>    <div class="show">        <table class="table table-bordered table-hover" id="msgtable">        </table>    </div></div></body></html>

业务逻辑层(接口)
MsgService.class

package com.cs.qsx.service;import com.cs.qsx.domain.Msg;import java.util.List;public interface MsgService {    //查询    public List<Msg> findAll();    //新增    public void addMsg(Msg msg);}

业务逻辑层(实现类)
MsgServiceImpl.class

package com.cs.qsx.service.impl;import com.cs.qsx.dao.MsgDao;import com.cs.qsx.domain.Msg;import com.cs.qsx.service.MsgService;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.List;@Servicepublic class MsgServiceImpl implements MsgService {    @Autowired    private MsgDao msgDao;    @Override    public List<Msg> findAll() {        return msgDao.queryAll();    }    @Override    public void addMsg(Msg msg) {        msgDao.insertMsg(msg);    }}

数据持久层(接口)
MsgDao.class

package com.cs.qsx.dao;import com.cs.qsx.domain.Msg;import java.util.List;public interface MsgDao {    //查询    public List<Msg> queryAll();    //新增    public void insertMsg(Msg msg);}

数据持久层(实现类)
MsgDaoImpl.class

package com.cs.qsx.dao.impl;import com.cs.qsx.dao.MsgDao;import com.cs.qsx.domain.Msg;import org.hibernate.SessionFactory;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.orm.hibernate5.support.HibernateDaoSupport;import org.springframework.stereotype.Repository;import javax.annotation.PostConstruct;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.List;@Repository("msgDao")public class MsgDaoImpl extends HibernateDaoSupport implements MsgDao {    @Autowired    private SessionFactory sessionFactory;    @PostConstruct    protected void injectSessionFactory() {        super.setSessionFactory(sessionFactory);    }    @Override    public List<Msg> queryAll() {        return (List<Msg>) getHibernateTemplate().find("from Msg");    }    @Override    public void insertMsg(Msg msg) {        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");        Date date = null;        try {            date = simpleDateFormat.parse(simpleDateFormat.format(new Date()));        } catch (ParseException e) {            e.printStackTrace();        }        msg.setCreateDate(date);        getHibernateTemplate().save(msg);    }}

控制器
MsgController.class

package com.cs.qsx.controller;import com.cs.qsx.domain.Msg;import com.cs.qsx.service.MsgService;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.ResponseBody;import javax.servlet.http.HttpServletResponse;import java.util.List;@Controllerpublic class MsgController {    @Autowired    private MsgService msgService;    @RequestMapping("/msg")    public String showMsg() {        return "leaveMessage";    }    @ResponseBody    @RequestMapping("/api/msg")    public List<Msg> msgapi(HttpServletResponse response) {        List<Msg> msgs = msgService.findAll();        return msgs;    }    @RequestMapping("/addMsg")    public String addMsg(Msg msg){        msgService.addMsg(msg);        return "leaveMessage";    }}

过滤器
HibernateFlushFilter.class

package com.cs.qsx.filter;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.springframework.dao.DataAccessResourceFailureException;import org.springframework.orm.hibernate5.support.OpenSessionInViewFilter;import javax.persistence.FlushModeType;import javax.servlet.annotation.WebFilter;/** * Servlet Filter implementation class HibernateFlushFilter * 为了解决Spring二次修改Hibernate的FlushMode * */@WebFilter("/*")public class HibernateFlushFilter extends OpenSessionInViewFilter {    @Override    protected Session openSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {        // TODO Auto-generated method stub        Session session=sessionFactory.openSession();        session.setFlushMode(FlushModeType.AUTO);        return session;    }}

字符过滤器
EncodingFilter.class

package com.cs.qsx.filter;import javax.servlet.*;import javax.servlet.annotation.WebFilter;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import java.io.File;import java.io.IOException;import java.io.UnsupportedEncodingException;import java.util.Map;@WebFilter(filterName = "EncodeFilter", urlPatterns = "/*")public class EncodeFilter implements Filter {    public void destroy() {    }    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {        //获取请求        HttpServletRequest request = (HttpServletRequest) req;        HttpServletRequest myRequest = new MyRequest(request);        //处理响应乱码        resp.setContentType("text/html;charset=utf-8");        //放行        chain.doFilter(myRequest,resp);    }    //自定义一个请求    class MyRequest extends HttpServletRequestWrapper {        private HttpServletRequest request;        private boolean hasEncode = false;        public MyRequest(HttpServletRequest request) {            super(request);            this.request = request;        }        @Override        public String getParameter(String s) {            //通过自己定义的已经处理过字符编码问题的方法获取map            Map<String,String[]> parameterMap = getParameterMap();            //根据map获取值,值是数组            String[] values = parameterMap.get(s);            if (values == null){                return null;            }            //取一个值,这个值就是数组的第0个元素            return values[0];        }        @Override        public String[] getParameterValues(String s) {            Map<String,String[]> parameterMap = getParameterMap();            String[] values = parameterMap.get(s);            return values;        }        //重写getParmeterMap方法,在内部把map中的中文乱码处理掉        @Override        public Map<String, String[]> getParameterMap() {            //处理中文乱码,区别对待get和post            String method = request.getMethod();            if ("post".equalsIgnoreCase(method)) {                //处理post乱码                try {                    request.setCharacterEncoding("utf-8");                    return request.getParameterMap();                } catch (UnsupportedEncodingException e) {                    e.printStackTrace();                }            } else if ("get".equalsIgnoreCase(method)) {                //处理get乱码                Map<String, String[]> parameterMap = request.getParameterMap();                //对于每一个内容都要重新编码再解码                /*                说明:tomcat8之前的版本,默认编码格式是iso-8859-1                在8之后,就是utf-8了,所以只需要对Tomcat8之前的版本进行处理即可                 */                String servletInfo = request.getServletContext().getServerInfo();                if (!hasEncode) {                    if (servletInfo.substring(servletInfo.lastIndexOf(File.separator) + 1).charAt(0) < 56) {                        for (String parameterName : parameterMap.keySet()) {                            //根据键拿到值,这个值并不确定是几个值                            String[] values = parameterMap.get(parameterName);                            if (values != null) {                                for (int i = 0; i < values.length; i++) {                                    try {                                        values[i] = new String(values[i].getBytes("ISO-8859-1"), "UTF-8");                                    } catch (UnsupportedEncodingException e) {                                        e.printStackTrace();                                    }                                }                            }                        }                        hasEncode = true;                    }                }                return parameterMap;            }            return super.getParameterMap();        }    }    public void init(FilterConfig config) throws ServletException {    }}

附:

Flat UI 官网:
Flat UI 官网

效果图:
这里写图片描述

成功的路上,总有坎坷,走过去,迎接你的将是—下一个坎坷.

Lucifer
2017/10/11