相关文章链接:
SpringMVC搭建一个Web项目
log4j.xml配置详解
logback.xml配置详解
Idea使用Maven搭建SSM框架Web项目
观前提示:
本文可在 SpringMVC搭建一个Web项目 基础上配置,Eclipse版本为Photon Release (4.8.0),Idea版本为ultimate 2019.1,JDK为1.8.0_141,Tomcat为9.0.12。
SSM(Spring+SpringMVC+MyBatis)框架集由Spring、MyBatis两个开源框架整合而成(SpringMVC是Spring中的部分内容)。常作为数据源较简单的web项目的框架。
Spring就像是整个项目中装配bean的大工厂,在配置文件中可以指定使用特定的参数去调用实体类的构造方法来实例化对象。也可以称之为项目中的粘合剂。Spring的核心思想是IoC(控制反转),即不再需要程序员去显式地new一个对象,而是让Spring框架帮你来完成这一切。
SpringMVC在项目中拦截用户请求,它的核心Servlet即DispatcherServlet承担中介或是前台这样的职责,将用户请求通过HandlerMapping去匹配Controller,Controller就是具体对应请求所执行的操作。SpringMVC相当于SSH框架中struts。
mybatis是对jdbc的封装,它让数据库底层操作变的透明。mybatis的操作都是围绕一个sqlSessionFactory实例展开的。mybatis通过配置文件关联到各实体类的Mapper文件,Mapper文件中配置了每个类对数据库所需进行的sql语句映射。在每次与数据库交互时,通过sqlSessionFactory拿到一个sqlSession,再执行sql命令。
页面发送请求给控制器,控制器调用业务层处理逻辑,逻辑层向持久层发送请求,持久层与数据库交互,后将结果返回给业务层,业务层将处理逻辑发送给控制器,控制器再调用视图展现数据。
jar包链接地址:Jar包链接详情点我
按照2.1目录添加配置文件web.xml,spring-mvc.xml,applicationContext.xml,jdbc.properties,log4j.xml。jdbc.properties为连接数据库相关数据,log4j.xml为日志配置。
部分标签解释请看上一篇文章,本文中大部分解释请看代码。
<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_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>MyDemodisplay-name>
<context-param>
<param-name>log4jConfigLocationparam-name>
<param-value>classpath:resource/config/log4j.xmlparam-value>
context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListenerlistener-class>
listener>
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>classpath:resource/spring/applicationContext.xmlparam-value>
context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>
<servlet>
<servlet-name>springServletservlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServletservlet-class>
<init-param>
<param-name>contextConfigLocationparam-name>
<param-value>/WEB-INF/spring/spring-mvc.xmlparam-value>
init-param>
<load-on-startup>1load-on-startup>
servlet>
<servlet-mapping>
<servlet-name>springServletservlet-name>
<url-pattern>/url-pattern>
servlet-mapping>
<filter>
<filter-name>encodingfilter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilterfilter-class>
<init-param>
<param-name>encodingparam-name>
<param-value>UTF-8param-value>
init-param>
filter>
<filter-mapping>
<filter-name>encodingfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
web-app>
<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-4.0.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<context:component-scan base-package="cn.com.mydemo" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.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>
<mvc:annotation-driven/>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="cn.com.mydemo.interceptor.RequestMappingInterceptor">bean>
mvc:interceptor>
mvc:interceptors>
<mvc:default-servlet-handler/>
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8" />
<property name="maxUploadSize" value="10485760000">property>
<property name="maxInMemorySize" value="40960">property>
bean>
<mvc:resources mapping="/static/**" location="/WEB-INF/static/"/>
beans>
<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-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<description>spring配置description>
<context:component-scan base-package="cn.com.mydemo">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
context:component-scan>
<context:property-placeholder location="/WEB-INF/config/jdbc.properties"/>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<property name="initialSize" value="${jdbc.pool.initialPoolSize}"/>
<property name="minIdle" value="${jdbc.pool.minPoolSize}"/>
<property name="maxActive" value="${jdbc.pool.maxPoolSize}"/>
<property name="maxWait" value="${jdbc.pool.maxIdleTime}"/>
<property name="timeBetweenEvictionRunsMillis" value="${jdbc.pool.checkoutTimeout}"/>
<property name="filters" value="wall,stat,log4j"/>
bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:cn/com/mydemo/mapper/*.xml"/>
bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.com.mydemo.dao"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
beans>
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=root
jdbc.pool.initialPoolSize=10
jdbc.pool.minPoolSize=5
jdbc.pool.maxPoolSize=40
jdbc.pool.maxIdleTime=20
jdbc.pool.checkoutTimeout=10000
log4j.xml配置详解:log4j.xml配置详解
<log4j:configuration>
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.TTCCLayout"/>
appender>
<appender name="rollingAppender" class="org.apache.log4j.RollingFileAppender">
<param name="File" value="${catalina.base}/logs/demo/RollingFileAppender.log"/>
<param name="Append" value="true"/>
<param name="MaxBackupIndex" value="10"/>
<param name="MaxFileSize" value="5120KB"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%d{yyyy-MM-dd HH:mm:ss:SSS}] [%-5p] [method:%l]%n%m%n%n"/>
layout>
appender>
<appender name="dailyRollingAppender" class="org.apache.log4j.DailyRollingFileAppender">
<param name="File" value="${catalina.base}/logs/demo/DailyRollingFileAppender.log"/>
<param name="Append" value="true"/>
<param name="Threshold" value="DEBUG" />
<param name="DatePattern" value="yyyy-MM-dd"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="[%p][%d{HH:mm:ss SSS}][%c]-[%m]%n"/>
layout>
appender>
<logger name="org.apache.commons" additivity="false">
<level value="ERROR"/>
<appender-ref ref="dailyRollingAppender"/>
logger>
<logger name="org.mybatis.spring" additivity="false">
<level value="ERROR"/>
<appender-ref ref="dailyRollingAppender"/>
logger>
<logger name="java.sql" additivity="false">
<level value="ERROR"/>
<appender-ref ref="dailyRollingAppender"/>
logger>
<logger name="org.apache.ibatis" additivity="false">
<level value="ERROR"/>
<appender-ref ref="dailyRollingAppender" />
logger>
<logger name="org.springframework" additivity="false">
<level value="ERROR"/>
<appender-ref ref="dailyRollingAppender"/>
logger>
<logger name="com.mchange.v2" additivity="false">
<level value="ERROR"/>
<appender-ref ref="dailyRollingAppender"/>
logger>
<logger name="com.alibaba.druid.filter.stat" additivity="false">
<level value="WARN"/>
<appender-ref ref="dailyRollingAppender"/>
logger>
<logger name="com.alibaba.druid.pool" additivity="false">
<level value="WARN"/>
<appender-ref ref="dailyRollingAppender"/>
logger>
<logger name="druid.sql.Connection" additivity="false">
<level value="WARN"/>
<appender-ref ref="dailyRollingAppender"/>
logger>
<logger name="druid.sql.DataSource" additivity="false">
<level value="WARN"/>
<appender-ref ref="dailyRollingAppender"/>
logger>
<logger name="druid.sql.ResultSet" additivity="false">
<level value="WARN"/>
<appender-ref ref="dailyRollingAppender"/>
logger>
<logger name="druid.sql.Statement" additivity="false">
<level value="WARN"/>
<appender-ref ref="dailyRollingAppender"/>
logger>
<root>
<appender-ref ref="console"/>
<appender-ref ref="rollingAppender"/>
<appender-ref ref="dailyRollingAppender"/>
root>
log4j:configuration>
配置拦截器RequestMappingInterceptor.java
package cn.com.mydemo.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class RequestMappingInterceptor extends HandlerInterceptorAdapter {
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// TODO Auto-generated method stub
super.afterCompletion(request, response, handler, ex);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// TODO Auto-generated method stub
super.postHandle(request, response, handler, modelAndView);
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// TODO Auto-generated method stub
return super.preHandle(request, response, handler);
}
}
package cn.com.mydemo.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import cn.com.mydemo.model.User;
import cn.com.mydemo.service.LoginService;
/**
* @Description 登录Controller
* @author jjy
* @Creation 2019-02-21
*/
@Controller
public class LoginController {
@Autowired
private LoginService loginService;
private static Logger log = LoggerFactory.getLogger(LoginController.class);
/**
* @Description 初始化登录页面
* @param model
* @return
* @Creation 2019-02-21 by jjy
*/
@RequestMapping(value = "/")
public String init(Model model) {
User us = new User("1");
log.debug("搜索用户id为1的用户信息");
User user = loginService.selectByID(us);
model.addAttribute("id", user.getId());
model.addAttribute("name", user.getName());
return "login";
}
}
@Autowired:自动装配,其作用是为了消除代码Java代码里面的getter/setter与bean属性中的property,当Spring发现@Autowired注解时,将自动在代码上下文中找到和其匹配(默认是类型匹配)的Bean,并自动注入到相应的地方去。在application.xml配置为
package cn.com.mydemo.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.com.mydemo.dao.LoginDao;
import cn.com.mydemo.model.User;
/**
* @Description 登录Service
* @author jjy
* @Creation 2019-02-21
*/
@Service
@Transactional(readOnly = true)
public class LoginService {
@Autowired
private LoginDao loginDao;
/**
* @Description 根据用户ID搜索用户
* @param user
* @return
* @Creation 2019-02-21 by jjy
*/
public User selectByID(User user) {
return loginDao.selectByID(user);
}
}
注:@Transactional注解配置需在applicationContext.xml中配置
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
@Transactional 可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。
虽然 @Transactional 注解可以作用于接口、接口方法、类以及类方法上,但是 Spring 建议不要在接口或者接口方法上使用该注解,因为这只有在使用基于接口的代理时它才会生效。另外, @Transactional 注解应该只被应用到 public 方法上,这是由 Spring AOP 的本质决定的。如果你在 protected、private 或者默认可见性的方法上使用 @Transactional 注解,这将被忽略,也不会抛出任何异常。
@Transactional属性
属性 | 类型 | 描述 |
---|---|---|
value | String | 可选的限定描述符,指定使用的事务管理器 |
propagation | enum: Propagation | 可选的事务传播行为设置 |
isolation | enum: Isolation | 可选的事务隔离级别设置 |
readOnly | boolean | 读写或只读事务,默认读写 |
timeout | int (in seconds granularity) | 事务超时时间设置 |
rollbackFor | Class对象数组,必须继承自Throwable | 导致事务回滚的异常类数组 |
rollbackForClassName | 类名数组,必须继承自Throwable | 导致事务回滚的异常类名字数组 |
noRollbackFor | Class对象数组,必须继承自Throwable | 不会导致事务回滚的异常类数组 |
noRollbackForClassName | 类名数组,必须继承自Throwable | 不会导致事务回滚的异常类名字数组 |
package cn.com.mydemo.model;
/**
* @Description 用户实体
* @author jjy
* @Creation 2019-02-21
*/
public class User {
private String id;
private String name;
public User() {
}
public User(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package cn.com.mydemo.dao;
import cn.com.mydemo.model.User;
/**
* @Description 登录Dao
* @author jjy
* @Creation 2019-02-21
*/
public interface LoginDao {
User selectByID(User user);
}
<mapper namespace="cn.com.mydemo.dao.LoginDao">
<select id="selectByID" parameterType="cn.com.mydemo.model.User" resultType="cn.com.mydemo.model.User">
SELECT ID,NAME FROM USER WHERE ID = #{id}
select>
mapper>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Login
具体问题请根据实际原因解决,以下问题为我部署项目时的问题及解决方法,仅供参考。
在配置完log4j.xml文件后启动eclipse,出现了以下所示WARN:
查看了下我最开始的log4j.xml部分配置如下
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j">
修改后如下所示
<log4j:configuration>
查看了下我最开始的web.xml部分配置如下
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>/WEB-INF/spring/applicationContext.xmlparam-value>
context-param>
<context-param>
<param-name>log4jConfigLocationparam-name>
<param-value>/WEB-INF/config/log4j.xmlparam-value>
context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListenerlistener-class>
listener>
修改后如下所示
<context-param>
<param-name>log4jConfigLocationparam-name>
<param-value>/WEB-INF/config/log4j.xmlparam-value>
context-param>
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListenerlistener-class>
listener>
<context-param>
<param-name>contextConfigLocationparam-name>
<param-value>/WEB-INF/spring/applicationContext.xmlparam-value>
context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>
注意:请严格按照修改后的配置顺序。