一.SSM环境搭建
1.新建Web项目,导入相关jar包
2.配置web.xml
3.配置文件(/resource)
- database.properties
- Log4j.properties
- mybatis-config.xml
- 配置typeAliases
- 设置全局性依赖加载
- applicationContext-mybatis.xml
- springmvc-servlet.xml
二.配置文件详细
1.database.properties
driver=com.mysql.jdbc.Driver url=jdbc:mysql://127.0.0.1:3306/smbms?useUnicode=true&characterEncoding=utf-8 user=root password=root minIdle=45 maxIdle=50 initialSize=5 maxActive=100 maxWait=100 removeAbandonedTimeout=180 removeAbandoned=true |
2.Web.xml
<display-name>springMVC</display-name> <welcome-file-list> <welcome-file>/WEB-INF/jsp/login.jsp</welcome-file>项目默认登录页面 </welcome-file-list> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext-*.xml</param-value>spring配置文件导入 </context-param> <filter>jSP与Java使用不同编码时,针对编码问题进行过滤 <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> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>spring</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>前端控制器实现 <init-param> <param-name>contextConfigLocation</param-name>spring-mvc配置文件导入 <param-value>classpath:springmvc-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup>标记容器是否在启动的时加载这个servlet,>0表示是,正数越大优先越高 </servlet> <servlet-mapping> <servlet-name>spring</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>SpringMVC容器初始化 </listener> <context-param> <param-name>log4jConfigLocation</param-name>Log4j日志配置 <param-value>classpath:log4j.properties</param-value> </context-param> <context-param> <param-name>webAppRootKey</param-name> <param-value>SMBMS_C12_09.root</param-value>在Eclipse调试Web项目时,项目的路径是一个临时路径 </context-param> <listener> <listener-class> org.springframework.web.util.Log4jConfigListenerlog监听器,spring5以上被废弃 </listener-class> </listener> </web-app> |
3.mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <!– 是否使用 懒加载 关联对象 同 hibernate中的延迟加载 一样 default:true –> <setting name="lazyLoadingEnabled" value="false" /> </settings> <typeAliases> <!--这里给实体类取别名,方便在mapper配置文件中使用--> <package name="cn.smbms.pojo"/> </typeAliases> </configuration> |
4.applicationContext-mybatis.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:aop="http://www.springframework.org/schema/aop" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="cn.smbms.service"/> 扫描service层组件 <context:component-scan base-package="cn.smbms.dao"/> 扫描dao层组件
<!-- 读取数据库配置文件 --> <context:property-placeholder location="classpath:database.properties"/>
<!-- JNDI获取数据源(使用dbcp连接池) --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" scope="singleton"> <property name="driverClassName" value="${driver}" /> <property name="url" value="${url}" /> <property name="username" value="${user}" /> <property name="password" value="${password}" /> <property name="initialSize" value="${initialSize}"/> <property name="maxActive" value="${maxActive}"/> <property name="maxIdle" value="${maxIdle}"/> <property name="minIdle" value="${minIdle}"/> <property name="maxWait" value="${maxWait}"/> <property name="removeAbandonedTimeout" value="${removeAbandonedTimeout}"/> <property name="removeAbandoned" value="${removeAbandoned}"/> <!-- sql 心跳 --> <property name= "testWhileIdle" value="true"/> <property name= "testOnBorrow" value="false"/> <property name= "testOnReturn" value="false"/> <property name= "validationQuery" value="select 1"/> <property name= "timeBetweenEvictionRunsMillis" value="60000"/> <property name= "numTestsPerEvictionRun" value="${maxActive}"/> </bean>
<!-- 事务管理 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean>
<!-- 配置mybitas SqlSessionFactoryBean--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="configLocation" value="classpath:mybatis-config.xml"/> </bean>
<!-- AOP 事务处理 开始 --> <aop:aspectj-autoproxy /> <aop:config proxy-target-class="true"> <aop:pointcut expression="execution(* *cn.smbms.service..*(..))" id="transService"/> <aop:advisor pointcut-ref="transService" advice-ref="txAdvice" /> </aop:config> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="smbms*" propagation="REQUIRED" rollback-for="Exception" /> </tx:attributes> </tx:advice> <!-- AOP 事务处理 结束 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="cn.smbms.dao" /> 自动扫描 将Mapper接口生成代理注入到Spring </bean>
</beans> |
连接池相关属性详细
5.springmvc-servlet.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:p="http://www.springframework.org/schema/p" 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 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<context:component-scan base-package="cn.smbms.controller"/>扫描控制器层组件 <!-- 解决JSON数据乱码和日期转换问题 --> <mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.StringHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>application/json;charset=UTF-8</value> </list> </property> </bean> <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>text/html;charset=UTF-8</value> <value>application/json</value> </list> </property> <property name="features"> <list> <!-- Date的日期转换器 --> <value>WriteDateUseDateFormat</value> </list> </property> </bean> </mvc:message-converters> </mvc:annotation-driven>
<mvc:resources location="/statics/" mapping="/statics/**"></mvc:resources>指定路径静态资源
<!-- 配置多视图解析器:允许同样的内容数据呈现不同的view --> <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver"> <property name="favorParameter" value="true"/> <property name="defaultContentType" value="text/html"/> <property name="mediaTypes"> <map> <entry key="html" value="text/html;charset=UTF-8"/> <entry key="json" value="application/json;charset=UTF-8"/> <entry key="xml" value="application/xml;charset=UTF-8"/> </map> </property> <property name="viewResolvers"> <list> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" > <property name="prefix" value="/WEB-INF/jsp/"/> <property name="suffix" value=".jsp"/> </bean> </list> </property> </bean>
<!-- 配置interceptors -->拦截器(bean中的那个类)SysInterceptor.java <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/sys/**"/> <bean class="cn.smbms.interceptor.SysInterceptor"/> </mvc:interceptor> </mvc:interceptors>
<!-- 配置MultipartResolver,用于上传文件,使用spring的CommonsMultipartResolver --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <property name="maxUploadSize" value="5000000"/> <property name="defaultEncoding" value="UTF-8"/> </bean> </beans> |
三.(案例)实现登录注销(案例超市订单管理系统)
创建login.jsp <section class="loginCont"> <form class="loginForm" action="${pageContext.request.contextPath }/dologin.html" name="actionForm" id="actionForm" method="post" > <div class="info">${error }</div> <div class="inputbox"> <label for="user">用户名:</label> <input type="text" class="input-text" id="userCode" name="userCode" placeholder="请输入用户名" required/> </div> <div class="inputbox"> <label for="mima">密码:</label> <input type="password" id="userPassword" name="userPassword" placeholder="请输入密码" required/> </div> <div class="subBtn"> <input type="submit" value="登录"/> <input type="reset" value="重置"/> </div> </form> </section> |
1.实体类(User.java)必须在cn.smbms.pojo.*包下
public class User { private Integer id; //id
@NotEmpty(message="用户编码不能为空") private String userCode; //用户编码
@NotEmpty(message="用户名称不能为空") private String userName; //用户名称
@NotNull(message="密码不能为空") @Length(min=6,max=10,message="用户密码长度为6-10") private String userPassword; //用户密码
@Past(message="必须是一个过去的时间") //@DateTimeFormat(pattern="yyyy-MM-dd") //@JSONField(format="yyyy-MM-dd") private Date birthday; //出生日期
private Integer gender; //性别 private String phone; //电话 private String address; //地址 private Integer userRole; //用户角色 private Integer createdBy; //创建者 private Date creationDate; //创建时间 private Integer modifyBy; //更新者 private Date modifyDate; //更新时间
private Integer age;//年龄
private String userRoleName; //用户角色名称
private String idPicPath; //证件照路径
private String workPicPath; //工作证照片路径
public String getWorkPicPath() { return workPicPath; }
public void setWorkPicPath(String workPicPath) { this.workPicPath = workPicPath; }
public String getIdPicPath() { return idPicPath; }
public void setIdPicPath(String idPicPath) { this.idPicPath = idPicPath; }
public User(){}
public User(Integer id,String userCode,String userName,String userPassword,Integer gender,Date birthday,String phone, String address,Integer userRole,Integer createdBy,Date creationDate,Integer modifyBy,Date modifyDate){ this.id = id; this.userCode = userCode; this.userName = userName; this.userPassword = userPassword; this.gender = gender; this.birthday = birthday; this.phone = phone; this.address = address; this.userRole = userRole; this.createdBy = createdBy; this.creationDate = creationDate; this.modifyBy = modifyBy; this.modifyDate = modifyDate; } public String getUserRoleName() { return userRoleName; } public void setUserRoleName(String userRoleName) { this.userRoleName = userRoleName; } public Integer getAge() { /*long time = System.currentTimeMillis()-birthday.getTime(); Integer age = Long.valueOf(time/365/24/60/60/1000).IntegerValue();*/ Date date = new Date(); Integer age = date.getYear()-birthday.getYear(); return age; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUserCode() { return userCode; } public void setUserCode(String userCode) { this.userCode = userCode; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPassword() { return userPassword; } public void setUserPassword(String userPassword) { this.userPassword = userPassword; } public Integer getGender() { return gender; } public void setGender(Integer gender) { this.gender = gender; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public Integer getUserRole() { return userRole; } public void setUserRole(Integer userRole) { this.userRole = userRole; } public Integer getCreatedBy() { return createdBy; } public void setCreatedBy(Integer createdBy) { this.createdBy = createdBy; } public Date getCreationDate() { return creationDate; } public void setCreationDate(Date creationDate) { this.creationDate = creationDate; } public Integer getModifyBy() { return modifyBy; } public void setModifyBy(Integer modifyBy) { this.modifyBy = modifyBy; } public Date getModifyDate() { return modifyDate; } public void setModifyDate(Date modifyDate) { this.modifyDate = modifyDate; } } |
2.Dao层(在cn.smbms.dao.*包下)
>创建UserMapper.java接口 |
|
public interface UserMapper { /** * 通过userCode获取User * @param userCode * @return * @throws Exception */ public User getLoginUser(@Param("userCode")String userCode)throws Exception; } |
|
>创建UserMapper.xml |
|
<mapper namespace="cn.smbms.dao.user.UserMapper"> <select id="getLoginUser" resultType="User"> select * from smbms_user u <trim prefix="where" prefixOverrides="and | or"> <if test="userCode != null"> and u.userCode = #{userCode} </if> </trim> </select> <mapper> |
|
3.Service层(必须在cn.smbms.service.*包下)
>创建UserService.java接口 |
|
public interface UserService {
/** * 用户登录 * @param userCode * @param userPassword * @return */ public User login(String userCode,String userPassword) throws Exception; |
|
>创建UserServiceImp.java实现类 |
|
@Service public class UserServiceImpl implements UserService {
@Resource private UserMapper userMapper;
@Override public User login(String userCode, String userPassword) throws Exception { // TODO Auto-generated method stub User user = null; user = userMapper.getLoginUser(userCode); //匹配密码 if(null != user){ if(!user.getUserPassword().equals(userPassword)) user = null; } return user; } |
4.拦截器(Interceptor)创建cn.smbms.interceptor.SysInterceptor类
public class SysInterceptor extends HandlerInterceptorAdapter { private Logger logger = Logger.getLogger(SysInterceptor.class);
public boolean preHandle(HttpServletRequest request,HttpServletResponse response,Object handler) throws Exception{ logger.debug("SysInterceptor preHandle =========================="); HttpSession session = request.getSession();
User user = (User)session.getAttribute(Constants.USER_SESSION);
if(null == user){ response.sendRedirect(request.getContextPath()+"/401.jsp"); return false; } return true; } } |
5.Controller层(必须在cn.smbms.controller.*包下)
>创建LoginController.java |
@Controller public class LoginController { private Logger logger = Logger.getLogger(LoginController.class);
@Resource private UserService userService;
@RequestMapping(value="/login.html") public String login(){ logger.debug("LoginController welcome SMBMS=================="); return "login"; }
@RequestMapping(value="/dologin.html",method=RequestMethod.POST)验证登录 public String doLogin(@RequestParam String userCode,@RequestParam String userPassword,HttpServletRequest request,HttpSession session) throws Exception{ logger.debug("doLogin===================================="); //调用service方法,进行用户匹配 User user = userService.login(userCode,userPassword); if(null != user){//登录成功 //放入session session.setAttribute(Constants.USER_SESSION, user); //页面跳转(frame.jsp) return "redirect:/sys/main.html"; }else{ //页面跳转(login.jsp)带出提示信息--转发 request.setAttribute("error", "用户名或密码不正确"); return "login"; } }
@RequestMapping(value="/logout.html")注销 public String logout(HttpSession session){ //清除session session.removeAttribute(Constants.USER_SESSION); return "login"; } @RequestMapping(value="/sys/main.html")主页跳转 public String main(){ return "frame"; }
@RequestMapping(value="/syserror.html") public String sysError(){ return "syserror"; } |