s:Spring
Spring : 春天 —>给软件行业带来了春天
2002年,Rod Jahnson首次推出了Spring框架雏形interface21框架。
2004年3月24日,Spring框架以interface21框架为基础,经过重新设计,发布了1.0正式版。
官网 : Spring | Home
s:SpringMVC
MVC是模型(Model)、视图(View)、控制器(Controller)的简写,是一种软件设计规范。
是将业务逻辑、数据、显示分离的方法来组织代码。
MVC主要作用是降低了视图与业务逻辑间的双向偶合。
MVC不是一种设计模式,MVC是一种架构模式。当然不同的MVC存在差异。
m:MyBatis
MyBatis 是一款优秀的持久层框架。
MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的过程。
MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 实体类 【Plain Old Java Objects,普通的 Java对象】映射成数据库中的记录。
Mybatis官方文档 : mybatis – MyBatis 3 | 简介
整合所需jar包
asm-3.3.1.jar cglib-2.2.2.jar com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar com.springsource.org.aopalliance-1.0.0.jar com.springsource.org.apache.commons.logging-1.1.1.jar com.springsource.org.apache.log4j-1.2.15.jar com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar commons-fileupload-1.2.2.jar commons-io-2.4.jar fastjson-1.2.47.jar jackson-annotations-2.4.0.jar jackson-core-2.4.2.jar jackson-databind-2.4.2.jar javassist-3.17.1-GA.jar jsqlparser-1.0.jar jstl-1.2.jar log4j-1.2.17.jar log4j-api-2.0-rc1.jar log4j-core-2.0-rc1.jar mybatis-3.2.7.jar mybatis-spring-1.2.2.jar mysql-connector-java-5.1.7-bin.jar pagehelper-5.0.0.jar slf4j-api-1.7.5.jar slf4j-log4j12-1.7.5.jar spring-aop-4.2.4.RELEASE.jar spring-aspects-4.2.4.RELEASE.jar spring-beans-4.2.4.RELEASE.jar spring-context-4.2.4.RELEASE.jar spring-core-4.2.4.RELEASE.jar spring-expression-4.2.4.RELEASE.jar spring-jdbc-4.2.4.RELEASE.jar spring-test-4.2.4.RELEASE.jar spring-tx-4.2.4.RELEASE.jar spring-web-4.2.4.RELEASE.jar spring-webmvc-4.2.4.RELEASE.jar
resource配置文件
mybatis
SqlMapConfig.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> <!-- 取别名 --> <typeAliases> <!-- 批量别名定义,扫描整个包下的类,别名为类名(大小写不敏感) --> <package name="com.wh.pojo" /> </typeAliases> <!-- 分页 --> <plugins> <!-- com.github.pagehelper为PageHelper类所在包名 --> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 --> <property name="helperDialect" value="mysql" /> </plugin> </plugins> </configuration>
spring
applicationContext-dao.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:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" 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.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd"> <!-- 配置 读取properties文件 jdbc.properties --> <context:property-placeholder location="classpath:jdbc.properties" /> <!-- 数据库连接池 c3p0 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driver}"></property> <property name="jdbcUrl" value="${jdbc.url}"></property> <property name="user" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </bean> <!-- 配置SqlSessionFactory --> <bean class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 设置MyBatis核心配置文件 --> <property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml" /> <!-- 设置数据源 --> <property name="dataSource" ref="dataSource" /> </bean> <!-- 配置Mapper扫描 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 设置Mapper扫描包 --> <property name="basePackage" value="com.wh.mapper" /> </bean> </beans>
applicationContext-service.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:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" 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-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd"> <!-- 配置Service扫描 --> <context:component-scan base-package="com.wh.service" /> </beans>
applicationContext-trans.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:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" 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-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd"> <!-- 事务管理器 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 数据源 --> <property name="dataSource" ref="dataSource" /> </bean> <!-- 通知 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <!-- 传播行为 --> <tx:method name="*" /> <tx:method name="query*" read-only="true" /> </tx:attributes> </tx:advice> <!-- 切面 --> <aop:config> <aop:advisor advice-ref="txAdvice" pointcut="execution(* com.wh.service.*.*(..))" /> </aop:config> </beans>
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/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd 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.2.xsd"> <!-- 扫描controller包 --> <context:component-scan base-package="com.wh.controller"></context:component-scan> <!--注解驱动 --> <mvc:annotation-driven conversion-service="conversionService" /> <!-- 解决静态资源无法被springMVC处理的问题 --> <mvc:default-servlet-handler /> <!--转换器配置 --> <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="com.wh.converter.DateConverter" /> </set> </property> </bean> <!-- 配置全局异常处理器 --> <bean class="com.wh.exception.CustomHandleException"></bean> <!-- 配置文件上传解析器,id必须设置为multipartResolver --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 设置文件上传大小 --> <property name="maxUploadSize" value="5000000" /> </bean> <!-- 配置拦截器 --> <mvc:interceptors> <mvc:interceptor> <!-- 所有的请求都进入拦截器 --> <mvc:mapping path="/**"/> <!-- 配置具体的拦截器 --> <bean class="com.wh.interceptor.HandlerInterceptor1"></bean> </mvc:interceptor> </mvc:interceptors> <!--配置视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--配置逻辑视图的前缀 --> <property name="prefix" value="/WEB-INF/jsp/" /> <!--配置逻辑视图的后缀 --> <property name="suffix" value=".jsp" /> </bean> </beans>
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/book?characterEncoding=utf-8 jdbc.username=root jdbc.password=root
log4j.properties
# Global logging configuration log4j.rootLogger=DEBUG, stdout # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
web.xml
<?xml version="1.0" encoding="UTF-8"?> <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_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>book</display-name> <welcome-file-list> <welcome-file>index.html</welcome-file> <welcome-file>index.htm</welcome-file> <welcome-file>index.jsp</welcome-file> <welcome-file>default.html</welcome-file> <welcome-file>default.htm</welcome-file> <welcome-file>default.jsp</welcome-file> </welcome-file-list> <!--使用监听器加载Spring配置文件 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/applicationContext-*.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 配置过滤器,解决中文乱码问题 --> <filter> <filter-name>encoding</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>encoding</filter-name> <url-pattern>/*</url-pattern> </filter-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>/*</url-pattern> </filter-mapping> <!-- 解决restful风格提交delete和put的支持 --> <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>/*</url-pattern> </filter-mapping> <!-- 配置springmvc前端控制器 --> <servlet> <servlet-name>book</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/springmvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>book</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app>
处理器
异常处理器
exception
CustomHandleException
package com.wh.exception; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.ModelAndView; public class CustomHandleException implements HandlerExceptionResolver { public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exception) { // 定义异常信息 String msg; // 判断异常类型 if (exception instanceof MyException) { // 如果是自定义异常,读取异常信息 msg = exception.getMessage(); } else { // 如果是运行时异常,则取错误堆栈,从堆栈中获取异常信息 Writer out = new StringWriter(); PrintWriter s = new PrintWriter(out); exception.printStackTrace(s); msg = out.toString(); } // 把错误信息发给相关人员,邮件,短信等方式 // TODO // 返回错误页面,给用户友好页面显示错误信息 ModelAndView modelAndView = new ModelAndView(); modelAndView.addObject("msg", msg); modelAndView.setViewName("error"); return modelAndView; } }
MyException
package com.wh.exception; public class MyException extends Exception { // 异常信息 private String message; public MyException() { super(); } public MyException(String message) { super(); this.message = message; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }
时间转换器
converter
DateConverter
package com.wh.converter; import java.text.SimpleDateFormat; import java.util.Date; import org.springframework.core.convert.converter.Converter; /** * Converter<S, T> S:source,需要转换的源的类型 T:target,需要转换的目标类型 * * @author admin * */ public class DateConverter implements Converter<String, Date> { @Override public Date convert(String source) { try { // 把字符串转换为日期类型 SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date date = simpleDateFormat.parse(source); return date; } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } // 如果转换异常则返回空 return null; } }
登录拦截器
interceptor
HandlerInterceptor1
package com.wh.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; /** * 实现用户非法登录拦截 * * @author admin * */ public class HandlerInterceptor1 implements HandlerInterceptor { @Autowired private LoginService LoginService; /** * controller执行后且视图返回后调用此方法 这里可得到执行controller时的异常信息 这里可记录操作日志 */ public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object arg2, Exception arg3) throws Exception { } /** * controller执行后但未返回视图前调用此方法 这里可在返回用户前对模型数据进行加工处理,比如这里加入公用信息以便页面显示 */ public void postHandle(HttpServletRequest request, HttpServletResponse response, Object arg2, ModelAndView arg3) throws Exception { } /** * Controller执行前调用此方法 返回true表示继续执行,返回false中止执行 这里可以加入登录校验、权限拦截等 */ public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object obj) throws Exception { return false; } }
分页
utils
NavigationTag
package com.wh.utils; import java.io.IOException; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.tagext.TagSupport; import com.github.pagehelper.PageInfo; /** * 显示格式 上一页 1 2 3 4 5 下一页 */ public class NavigationTag extends TagSupport { static final long serialVersionUID = 2372405317744358833L; /** * request 中用于保存Page<E> 对象的变量名,默认为“page” */ private String bean = "page"; /** * 分页跳转的url地址,此属性必须 */ private String url = null; /** * 显示页码数量 */ private int number = 5; @Override public int doStartTag() throws JspException { JspWriter writer = pageContext.getOut(); HttpServletRequest request = (HttpServletRequest) pageContext.getRequest(); PageInfo<?> page = (PageInfo<?>) request.getAttribute(bean); if (page == null) return SKIP_BODY; url = resolveUrl(url, pageContext); try { // 计算总页数 Long pageCount = page.getTotal() / page.getPageSize(); if (page.getTotal() % page.getPageSize() > 0) { pageCount++; } writer.print("<nav><ul class=\"pagination\">"); // 显示“上一页”按钮 if (page.getPageNum() > 1) { String preUrl = append(url, "page", page.getPageNum() - 1); preUrl = append(preUrl, "rows", page.getPageSize()); writer.print("<li><a href=\"" + preUrl + "\">上一页</a></li>"); } else { writer.print("<li class=\"disabled\"><a href=\"#\">上一页</a></li>"); } // 显示当前页码的前2页码和后两页码 // 若1 则 1 2 3 4 5, 若2 则 1 2 3 4 5, 若3 则1 2 3 4 5, // 若4 则 2 3 4 5 6 ,若10 则 8 9 10 11 12 int indexPage = (page.getPageNum() - 2 > 0) ? page.getPageNum() - 2 : 1; for (int i = 1; i <= number && indexPage <= pageCount; indexPage++, i++) { if (indexPage == page.getPageNum()) { writer.print("<li class=\"active\"><a href=\"#\">" + indexPage + "<span class=\"sr-only\">(current)</span></a></li>"); continue; } String pageUrl = append(url, "page", indexPage); pageUrl = append(pageUrl, "rows", page.getPageSize()); writer.print("<li><a href=\"" + pageUrl + "\">" + indexPage + "</a></li>"); } // 显示“下一页”按钮 if (page.getPageNum() < pageCount) { String nextUrl = append(url, "page", page.getPageNum() + 1); nextUrl = append(nextUrl, "rows", page.getPageSize()); writer.print("<li><a href=\"" + nextUrl + "\">下一页</a></li>"); } else { writer.print("<li class=\"disabled\"><a href=\"#\">下一页</a></li>"); } writer.print("</nav>"); } catch (IOException e) { e.printStackTrace(); } return SKIP_BODY; } private String append(String url, String key, int value) { return append(url, key, String.valueOf(value)); } /** * 为url 参加参数对儿 * * @param url * @param key * @param value * @return */ private String append(String url, String key, String value) { if (url == null || url.trim().length() == 0) { return ""; } if (url.indexOf("?") == -1) { url = url + "?" + key + "=" + value; } else { if (url.endsWith("?")) { url = url + key + "=" + value; } else { url = url + "&" + key + "=" + value; } } return url; } /** * 为url 添加翻页请求参数 * * @param url * @param pageContext * @return * @throws javax.servlet.jsp.JspException */ private String resolveUrl(String url, javax.servlet.jsp.PageContext pageContext) throws JspException { // UrlSupport.resolveUrl(url, context, pageContext) Map params = pageContext.getRequest().getParameterMap(); for (Object key : params.keySet()) { if ("page".equals(key) || "rows".equals(key)) continue; Object value = params.get(key); if (value == null) continue; try { if (value.getClass().isArray()) { // 解决GET乱码问题 // value = new String(((String[]) // value)[0].getBytes("ISO-8859-1"), "UTF-8"); value = ((String[]) value)[0]; url = append(url, key.toString(), value.toString()); } else if (value instanceof String) { // 解决GET乱码问题 // value = new String(((String) // value).getBytes("ISO-8859-1"), "UTF-8"); value = (String) value; url = append(url, key.toString(), value.toString()); } } catch (Exception e) { e.printStackTrace(); } } return url; } /** * @return the bean */ public String getBean() { return bean; } /** * @param bean * the bean to set */ public void setBean(String bean) { this.bean = bean; } /** * @return the url */ public String getUrl() { return url; } /** * @param url * the url to set */ public void setUrl(String url) { this.url = url; } public void setNumber(int number) { this.number = number; } }
WEB-INF——>tld
commons.tld
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> <taglib> <tlib-version>2.0</tlib-version> <jsp-version>1.2</jsp-version> <short-name>common</short-name> <uri>http://com.wh.com/common/</uri> <display-name>Common Tag</display-name> <description>Common Tag library</description> <tag> <name>page</name> <tag-class>com.wh.utils.NavigationTag</tag-class> <body-content>JSP</body-content> <description>create navigation for paging</description> <attribute> <name>bean</name> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>number</name> <rtexprvalue>true</rtexprvalue> </attribute> <attribute> <name>url</name> <required>true</required> <rtexprvalue>true</rtexprvalue> </attribute> </tag> </taglib> 注:.jsp <%@ taglib prefix="wh" uri="http://com.wh.com/common/"%> <wh:page url="${pageContext.request.contextPath}" />
代码片段
Mapper
mapper头文本
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace=""> </mapper>
crud
<!-- 增 --> <insert id="" parameterType=""> <!-- 添加后返回正确主键id --> <selectKey keyColumn="id" keyProperty="id" order="AFTER" resultType="int"> SELECT LAST_INSERT_ID() </selectKey> insert into 表名(字段名) values(字段值) </insert> <!-- 删 --> <delete id="" parameterType=""> delete from 表名 where id = #{id} </delete> <!-- 改 --> update 表名 <set> <if test="字段名 != null and 字段名 != ''"> 字段名 = #{字段值}, </if> <if test="字段名 != null and 字段名 != ''"> 字段名 = #{字段值}, </if> where id = #{id} </set> <!-- 查 --> <select id="" parameterType="" resultType=""> select * from 表名 <where> <if test="字段名 != null and 字段名 != ''"> and 字段名 = #{字段值} </if> <if test="字段名 != null and 字段名 != ''"> and 字段名 = #{字段值} </if> </where> </select>
JSP
jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> ${pageContext.request.contextPath} </body> </html>
c
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
fmt
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%> <fmt:formatDate value="" pattern="yyyy-MM-dd"/>