下面会按照我亲身搭建项目的过程一步步做介绍,唉,,,只能说基础不扎实,坑一个个的往下跳呀~~~
1、配置文件
对于用Intellij创建maven项目的操作此处不再一一介绍,直接跳到XML文件的配置。首先对项目的文件结构图做一个展示(不能说这是最标准的web项目文件结构,但也差不多~~)
(1)web.xml
可以说是web项目的根基文件,对spring mvc、spring的主配置文件、jsp展示首页等等进行了配置。具体代码如下:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<!--系统上下文配置 spring主配置文件-->
<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>
<!-- 配置spring核心servlet -->
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-servlet.xml</param-value>
</init-param>
<!-- load-on-startup元素标记容器是否在启动的时候就加载这个servlet(实例化并调用其init()方法) -->
<load-on-startup>1</load-on-startup>
</servlet>
<!-- url-pattern配置为斜杠,会造成其它静态文件(js,css等)不能访问。如配为*.do,则不影响静态文件的访问 -->
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- charactor encoding -->
<filter>
<filter-name>encodingFilter</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>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
坑点:
1、决定了spring mvc的配置文件名称,之后在resources中新建时一定要命名为xxx-servlet.xml
2、决定了可访问的文件格式,一般为“/”
3、spring的核心servlet—DispatcherServlet一定要配置。
该配置文件指定了两个需要配置的xml文件applicationContext.xml和xxx-servlet.xml,均放在resources文件目录下。
(2)applicationContext.xml
这是一个系统级别的配置文件,定义了注入bean的标准以及方式,还有一些数据库配置文件、mabatis、事务管理等等,相当的重要!!! 博主在这个文件上被坑的很惨~~~ 先上代码:
<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-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<!--支持注解-->
<context:annotation-config/>
<!-- proxy-target-class默认"false",更改为"ture"使用CGLib动态代理 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
<!-- 采用注释的方式配置bean,当配置扫描包的时候,可以省去配置这个context:annotation-config -->
<!--<context:annotation-config />-->
<!-- 组件扫描 -->
<context:component-scan base-package="com.hester.study"/>
<bean id="ViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/web/"></property> <!-- 视图文件的前缀 -->
<property name="suffix" value=".jsp"></property> <!-- 视图文件的后缀名 -->
<!-- view是用什么显示,这里是jsp,还可以用velocity之类的 -->
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
</bean>
<!-- 加载数据库配置文件 -->
<context:property-placeholder location="classpath:mydb.properties"/>
<!-- 配置数据源,使用dbcp -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${db.driver}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
</bean>
<!--Mybatis的SqlSessionFactory-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean" scope="prototype">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:sqlMapConfig.xml"/>
</bean>
<!--<!–sqlSessionTemplate–>
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate" scope="prototype">
<constructor-arg index="0" ref="sqlSessionFactory"/>
</bean>-->
<!--事务管理-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<!--basePackage 指定Spring自动扫描什么包;sqlSessionTemplateBeanName 指定spring中定义删去了Template的bean名称;
annotationClass-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.hester.study"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="annotationClass" value="org.springframework.stereotype.Repository"/>
</bean>
</beans>
坑点:
1、 组件扫描这里,由于一开始没有理解这里边参数的具体含义,有些bean一直提示无法注入,心累~~ 如果项目不是很大,建议还是不要写的很复杂,直接配置要扫描的根目录就好了,不要再去搞什么exclude-filter和include-filter,当然这个如果原理很懂得话,大神请随便玩~~
2、ViewResolver这个bean配置一下,后面与前台交互的时候用的上,里面的两个属性有注释,应该可以看懂!
3、数据库的配置,这边博主是另外写了一个properties(定义了一些常量,方便以后管理),然后导入到这里。
4、sqlSessionFactory的配置,这边注释掉了sqlSessionTemplate的配置了,因为后者会覆盖前者,这里面加了两个重要属性,一个是数据源,两一个是mabatis的配置(文件导入法)。
(3)spring-servlet.xml
主要代码:
<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-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
<!-- 启动注解驱动的Spring MVC功能,注册请求url和注解POJO类方法的映射-->
<!--<mvc:annotation-driven/>-->
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"/>
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 启动包扫描功能,以便注册带有@Controller、@service、@repository、@Component等注解的类成为spring的bean -->
<context:component-scan base-package="com.hester.study.*"/>
<!-- 对模型视图名称的解析,在请求时模型视图名称添加前后缀 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/web/"/> <!-- 前缀 -->
<property name="suffix" value=".jsp"/> <!-- 后缀 -->
</bean>
</beans>
坑点
1、这个文件的一些基本配置跟applicationContext.xml有点相似,有一点不同是加了一个,这是在前台调试的时候添上的,json无法转换,然后上网搜的说这样配置一下就可以,(可能还有其他解决方案)
(4)sqlMapConfig.xml
这个是mabatis的配置文件(必配)。代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "http://mabatis.org//DTD Config3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!--这个配置使全局的映射器启用或禁用缓存-->
<setting name="cacheEnabled" value="true"/>
<!--允许JDBC 生成主键。需要驱动器支持。如果设为了true,
这个设置将强制使用被生成的主键,有一些驱动器不兼容不过仍然可以执行。-->
<setting name="useGeneratedKeys" value="true"/>
<!--配置和设定执行器,
SIMPLE 执行器执行其它语句;
REUSE 执行器可能重复使用prepared statements 语句;
BATCH 执行器可以重复执行语句和批量更新-->
<setting name="defaultExecutorType" value="REUSE"/>
<!--全局性设置懒加载。如果设为‘false’,则所有相关联的都会被初始化加载。-->
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
<typeAliases>
<typeAlias alias="UserMapper" type="com.hester.study.entity.User"/>
</typeAliases>
<mappers>
<mapper resource="mappers/UserMapper.xml"/>
</mappers>
</configuration>
坑点
1、typeAliases类型别名,用alias的值来取代type中冗余的值。需要注意的时,一旦这样定义之后,后面对entity中的bean的引用都要用alias里定义的值来取代。(不要跳坑哦~~)
2、mappers映射器,指定了映射SQL 语句的文件。注意路径要写正确,不然会找不到的。
(5)UserMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "http://mabatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 1.命名空间是唯一的,根据你的Dao接口来定制的,Select标签的id对应方法名称-->
<mapper namespace="com.hester.study.dao.IUserDao">
<select id="findById" parameterType="int" resultType="UserMapper">
select id,username as name,age,address from "user" where id = #{id}
</select>
</mapper>
坑点
1、注意看resultType,这边就是我们在mybatis配置文件中定义的alias值。
2、SQL语句要写对哦,看清大小写和引号。(不然坑的你自己都不认识~~~)
2、Dao层实现
这边博主只写了一个dao类的接口用于测试,代码如下:
package com.hester.study.dao;
import com.hester.study.entity.User;
import org.springframework.stereotype.Repository;
/**
*Created By wangjie27
*@Description:
*@Date: Created in 2017/8/9 13:42
*/
@Repository
public interface IUserDao {
public User findById(Integer id);
}
坑点
1、千万不要忘记在接口前面加@Repository注解,然后spring不会给你注入的。
3、services层实现
这边有两部分,分别是service接口和实现类。
services接口的定义:
package com.hester.study.services;
import com.hester.study.entity.User;
/**
* @Author: wangjie27
* @Description:
* @Date: Created in 2017/8/9 13:48
* @Modified By:
*/
public interface IUserServices {
public User getUserfindById(Integer id);
}
services实现类的定义:
package com.hester.study.services.impl;
import com.hester.study.dao.IUserDao;
import com.hester.study.entity.User;
import com.hester.study.services.IUserServices;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* @Author: wangjie27
* @Description:
* @Date: Created in 2017/8/9 13:50
* @Modified By:
*/
@Service("UserServiceImpl")
public class UserServiceImpl implements IUserServices{
@Resource
private IUserDao userDao;
public User getUserfindById(Integer id) {
return userDao.findById(id);
}
}
4、controller层
具体代码如下:
package com.hester.study.action;
import com.hester.study.entity.User;
import com.hester.study.services.IUserServices;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
/**
* @Author: wangjie27
* @Description:
* @Date: Created in 2017/8/10 19:34
* @Modified By:
*/
@Controller
public class UserController {
@Autowired
private IUserServices userServices;
{
userServices = null;
}
public UserController() {
}
@RequestMapping(value="/test/{id}")
@ResponseBody
/**
* @Author: wangjie27
* @Description: url的访问路径为http://localhost:8090/test/XX
* @Date: 15:19
*/
public ModelAndView findUserById(@PathVariable("id") int id){
User user=userServices.getUserfindById(id);
ModelAndView mvc=new ModelAndView();
mvc.setViewName("welcome");
mvc.addObject("users",user);//方法一
// mvc.getModel().put("users",user);方法二
return mvc;
}
@RequestMapping(value="/test")
@ResponseBody
/**
* @Author: wangjie27
* @Description: url的访问路径为http://localhost:8090/test?id=XX
* @Date: 15:18
*/
public ModelAndView findUserById2(int id){
User user=userServices.getUserfindById(id);
ModelAndView mvc=new ModelAndView();
mvc.setViewName("welcome");
mvc.addObject("users",user);
// mvc.getModel().put("users",user);
return mvc;
}
}
坑点
1、这边要注意一些springmcv的注解书写形式,它决定了url访问路径的格式。@controller、@RequsetMapping、@pathVarible等的具体用法就不一一描述了。
2、对ModelAndView一些附带参数的绑定,包括view的设置,一些数据的携带。
5、jsp
<!--isELIgnored设定为真,那么JSP中的表达式被当成字符串处理,false则反之,表示支持EL-->
<%@ page contentType="text/html;charset=UTF-8" isELIgnored="false" language="java" %>
<html>
<head>
<title>hester</title>
</head>
<body>
${requestScope.users}
<br/>
</body>
</html>
坑点
1、这边在写的时候,由于对EL表达式不太了解,在坑里待了很久,结果在网友帮助下,加了isELIgnored=”false” 这一句,使得jsp能够支持EL,读懂${}这种形式,而不再当做字符串。
终于get到点,成功调试出来了。
完整代码在此: https://github.com/HesterWj/newWord
博主是个小菜鸟,以上是艰辛的探索史,有些坑还是值得参考的,阅读愉快!