SSH环境的搭建

注意这里的SSH指的是Spring+SpringMVC+Hibernate环境,这里使用的版本均为4.x版本

1.引入jar包

下载Spring4和Hibernate4的jar包如下图所示:


先放上我的整体工程的目录:


2.编写配置文件

1.编写web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <display-name>SSH</display-name>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

    <!-- 配置Spring IOC 容器 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- 配置SpringMVC 的 DispatcherServlet 控制器 -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 配置DispatcherServlet的一个初始化参数:配置SpringMVC配置文件的位置名称 -->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

    <!-- 配置编码方式过滤器,注意一点:要配置在所有过滤器的前面 -->
    <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>*.do</url-pattern>
    </filter-mapping>

    <!-- 为了使用SpringMVC框架实现REST风格,需要配置  HiddenHttpMethodFilter-->
    <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>*.do</url-pattern>
    </filter-mapping>

    <!--hibernate对对象的管理是基于session的,如果开启了延迟加载,
    对于关联对象的查询可能会在渲染jsp的时候才发生,但是这个时候hibernate的当前session默认已经关闭了,
    就会抛异常,所以我们经常需要hibernate在渲染jsp页面的时候还开着session,
    这就需要在web.xml中配置一个拦截所有请求的filter-->
    <filter>
        <filter-name>hibernateFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>hibernateFilter</filter-name>
        <url-pattern>*.do</url-pattern>
    </filter-mapping>
</web-app>

2.编写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: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/context http://www.springframework.org/schema/context/spring-context.xsd"

       default-lazy-init="true">

    <!-- 配置自动扫描的包 -->
    <context:component-scan base-package="cn.limbo"/>

    <!-- 配置数据源 -->
    <context:property-placeholder location="classpath:db.properties"/>

    <!-- 配置DataSource -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="user" value="${jdbc.user}" />
        <property name="password" value="${jdbc.password}" />
        <property name="driverClass" value="${jdbc.driverClass}" />
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}" />
    </bean>

    <!-- 配置SessionFactory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <!-- 配置数据源属性 -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 配置扫描的实体包(pojo) -->
        <property name="namingStrategy">
            <bean class="org.hibernate.cfg.ImprovedNamingStrategy"/>
        </property>
        <property name="packagesToScan" value="cn.limbo.entity"/>

        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>

    <!-- 配置Hibernate 的事物管理器 -->
    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
</beans>

3.编写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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 配置自动扫描的包 -->
    <context:component-scan base-package="cn.limbo"/>

    <!-- 配置视图解析器:如何把handler方法返回值解析为实际的物理视图 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"/>
    <!--<property name="prefix" value="/view/" />-->
    <!--<property name="suffix" value=".jsp" />-->
    <!--</bean>-->
    <!-- 配置静态资源:default-servlet-handler将在SpringMVC上下文中定义DefaultServletHttpRequestHandler,
      它会对进入DispatcherServlet的请求进行筛选,如果发现是没有经过映射的请求,就将该请求交由WEB应用服务器默认的 Servlet处理。如果不是静态资源的请求,才由DispatcherServlet继续处理。 -->
    <mvc:default-servlet-handler/>
    <mvc:annotation-driven/>
</beans>

4.数据库配置文件 db.properties:

jdbc.user=root
jdbc.password=123456
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql:///spring_hibernate

5.日志输出配置log4j.properties

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file hibernate.log ###
#log4j.appender.file=org.apache.log4j.FileAppender
#log4j.appender.file.File=hibernate.log
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=warn, stdout

#log4j.logger.org.hibernate=info
#log4j.logger.org.hibernate=debug
log4j.logger.cn.limbo=debug

3.编写测试类

到第二步为止,基本的框架是搭建起来了,下面就是使用了

上面的项目结构也看出了我使用的是一般的dao设计模式

4.User.java

package cn.limbo.entity;

import javax.persistence.*;
import java.io.Serializable;

/**
 * Created by limbo on 2016/11/8.
 */
@Entity(name = "user")
@Table(name = "user")
public class User implements Serializable {

    private Integer userId;
    private String userName;
    private Integer userAge;
    private String userAddress;


    public User() {
    }

    public User(String userName, Integer userAge, String userAddress) {
        this.userName = userName;
        this.userAge = userAge;
        this.userAddress = userAddress;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "user_id", nullable = false)
    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    @Column(name = "user_name", nullable = false)
    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    @Column(name = "user_age", nullable = false)
    public Integer getUserAge() {
        return userAge;
    }

    public void setUserAge(Integer userAge) {
        this.userAge = userAge;
    }

    @Column(name = "user_address", nullable = false)
    public String getUserAddress() {
        return userAddress;
    }

    public void setUserAddress(String userAddress) {
        this.userAddress = userAddress;
    }

    @Override
    public String toString() {
        return "User{" +
                "userId=" + userId +
                ", userName='" + userName + '\'' +
                ", userAge=" + userAge +
                ", userAddress='" + userAddress + '\'' +
                '}';
    }
}
UserDao.java

package cn.limbo.dao;

import cn.limbo.entity.User;

import java.util.List;

/**
 * Created by limbo on 2016/11/8.
 */
public interface UserDao {

    public void save(User user);

    public List<User> findAll();

}
UserDaoImpl.java

package cn.limbo.dao.impl;

import cn.limbo.dao.UserDao;
import cn.limbo.entity.User;
import org.hibernate.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * Created by limbo on 2016/11/8.
 */
@Repository
public class UserDaoImpl implements UserDao {

    @Autowired
    private SessionFactory sessionFactory;

    @Override
    public void save(User user) {
        sessionFactory.getCurrentSession().save(user);
    }

    @Override
    public List<User> findAll() {
        //Criteria较hq语句显得更加面向对象,但是没有hql语句的适用面广
        Criteria criteria = sessionFactory.getCurrentSession().createCriteria(User.class);
        return criteria.list();
    }
}
UserService.java

package cn.limbo.service;

import cn.limbo.entity.User;

import java.util.List;

/**
 * Created by limbo on 2016/11/8.
 */
public interface UserService {

    public void save(User user);

    public List<User> getAllUsers();

}
UserServiceImpl.java

package cn.limbo.service.impl;

import cn.limbo.dao.UserDao;
import cn.limbo.entity.User;
import cn.limbo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * Created by limbo on 2016/11/8.
 */
@Service
@Transactional
public class UserServiceImpl implements UserService{

    @Autowired
    private UserDao userDao;

    @Override
    public void save(User user) {
        userDao.save(user);
    }

    @Override
    public List<User> getAllUsers() {

        return userDao.findAll();

    }
}
UserController.java

package cn.limbo.controller;

import cn.limbo.entity.User;
import cn.limbo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * Created by limbo on 2016/11/8.
 */

@Controller
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping("/showUsers.do")
    public String showUsers(HttpServletRequest request){
        request.setAttribute("list",userService.getAllUsers());
        return "/index.jsp";
    }

    @RequestMapping("/addUser.do")
    public String addUser(HttpServletRequest request){
        String userName = request.getParameter("userName");
        Integer userAge = Integer.valueOf(request.getParameter("userAge"));
        String userAddress = request.getParameter("userAddress");

        User user = new User(userName,userAge,userAddress);
        userService.save(user);
        return "showUsers.do";
    }
}
index.jsp

<%--
  Created by IntelliJ IDEA.
  User: limbo
  Date: 2016/11/8
  Time: 下午4:18
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
  <head>
    <title></title>
  </head>
  <body>

  <table border="1">
    <tr>
      <td>id</td>
      <td>姓名</td>
      <td>年龄</td>
      <td>地址</td>
    </tr>
    <c:forEach items="${requestScope.list}" var="user">
      <tr>
        <td>${user.userId}</td>
        <td>${user.userName}</td>
        <td>${user.userAge}</td>
        <td>${user.userAddress}</td>
      </tr>
    </c:forEach>
  </table>
  <a href="addUser.jsp">添加</a>
  </body>
</html>
addUser.jsp

<%--
  Created by IntelliJ IDEA.
  User: limbo
  Date: 2016/11/8
  Time: 下午9:41
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="user/addUser.do"  method="post">
    姓名:<input type="text" name="userName" /><br>
    年龄:<input type="text" name="userAge" /><br>
    地址:<input type="text" name="userAddress" /><br>
    <input type="submit" value="OK" />
</form>
</body>
</html>
ok,接下来只要开启服务器跑就好了。

4.总结

搭建项目的时候绕了不少的弯路,受到了一些阻碍,好在在万能的谷歌下我独自完成了项目的搭建,分享一下我遇到的问题和我的心得吧。

1.XML头的问题:

这个问题很坑,真的。如果你要使用类似于mvc,context等命名空间的话,一定要正确的引入这些东西,还有就是在xsi:schemaLocation里面指定好xsd文件的位置,XML文件的文档标识有dtd和xsd两种,后者是前者的替代,关于两者的区别联系就不再赘述。对了,如果报错提示‘xx通配符的匹配很全面 但无法找到元素’,绝对是你XML文件头的问题

2.Spring和Hibernate的配置文件问题:

a).spring配置与hibernate相关的bean的时候记得一定要是和hibernate4有关的类,不过具体看你用的hibernate的版本,如果是3就用3,5就用5,我知道我讲到这里肯定有人看的懵逼,就像这样的org.springframework.orm.hibernate4.LocalSessionFactoryBean看到了中间的4了吗?就是这个意思

b).hibernate自动创建表的问题,我刚刚搭建完的时候发现表不存在,我明明给hibernate创建表的那个配置上写的是update啊,找了一圈发现问题出在这里

<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>因为我用的MySQL版本是5.x版本,所以要配置的是那个带5的。

3.心得:

OK,到这里就都好了,我配置的时候遇到的问题不多,项目还有很大的改进空间,比如使用Gradle来管理项目啊,引入Spring Security框架来做权限控制啊什么的,我搭了两遍才成功。写到后来发现,只要吧XML配置文件写清楚了就好了,写下来发现自己对整体流程还有XML的文件结构有了更加深刻的了解,接下来我想试着看看Spring的源码,了解一下所谓最棒的Java开源项目代码,也满足以下我的好奇心吧

附上源工程

http://download.csdn.net/detail/a1610770854/9688924





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值