`
cheneyph
  • 浏览: 292649 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论
收藏列表
标题 标签 来源
【FreeMarker】spring mvc + freemarker(多个viewResolver) freemarker, spring mvc
/**
		<dependency>
			<groupId>org.freemarker</groupId>
			<artifactId>freemarker</artifactId>
			<version>2.3.20</version>
		</dependency>


applicationContext-mvc.xml
http://blog.csdn.net/shandian534/article/details/5545219 
①order中的值越小,优先级越高。
②而id为viewResolver的viewResolver的优先级是最低的。
	<bean id="viewResolver_jsp"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />
		<property name="viewClass" value="com.cignacmb.liscont.web.controller.JSPJstlView" />
        <property name="order" value="0" />
	</bean> 
    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
        <property name="cache" value="true" />
        <property name="prefix" value="" />
        <property name="suffix" value=".ftl" />
        <property name="contentType" value="text/html;charset=UTF-8"></property>
        <property name="requestContextAttribute" value="request" />
        <property name="exposeSpringMacroHelpers" value="true" />
        <property name="exposeRequestAttributes" value="true" />
        <property name="exposeSessionAttributes" value="true" />
        <property name="order" value="1" />
    </bean>


applicationContext.xml
	<!-- freemarker的配置 -->
	<bean id="freemarkerConfig"
		class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
		<property name="templateLoaderPath" value="classpath:ftl" />
		<property name="defaultEncoding" value="utf-8" />
		<property name="freemarkerSettings">
			<props>
				<prop key="template_update_delay">10</prop>
				<prop key="locale">zh_CN</prop>
				<prop key="datetime_format">yyyy-MM-dd</prop>
				<prop key="date_format">yyyy-MM-dd</prop>
				<prop key="number_format">#.##</prop>
			</props>
		</property>
	</bean>
*/


@Controller
@RequestMapping(value="/ftl")
public class FreeMarkerController {
	
	@RequestMapping(value="/welcome.xhtml")
	public ModelAndView getFirstPage(HttpServletRequest request) {
		// welcom就是视图的名称(welcom.ftl)
		ModelAndView mv = new ModelAndView("welcome");
		mv.addObject("name", "My First Spring Mvc");
		return mv;
	}
}

/**
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>Hello ${name}
</body>
</html>
*/

public class JSPJstlView extends JstlView {
	
	/**
	 * http://www.iteye.com/problems/76107
	 * spring实现该方法时返回true,这样相当于view总是存在,
	 * 从而导致其余视图解析器无法得到解析机会。
	 */
	public boolean checkResource(Locale locale) throws Exception {
		File file = new File(this.getServletContext().getRealPath("/")
				+ getUrl());
		return file.exists();// 判断该jsp页面是否存在
	}
}
【spring mvc】复杂Form提交 spring mvc Spring3 mvc 复杂的Form提交

public class FormBean {
	private String riskname;
	private String riskshortname;

	private List<Insured> list;
}


<tr>
	<td class="title"><label>险种中文名称</label></td>
	<td class="input"><input name="riskname" value="险种中文名称" class="easyui-textbox input-common"></td>
	<td class="title"><label>险种中文简称</label></td>
	<td class="input"><input name="riskshortname" value="险种中文简称" class="easyui-textbox input-common"></td>
</tr>
<tr>
	<td class="title"><label>被保险人一</label></td>
	<td class="input"><input name="list[0].insuredname" value="被保险人一" > </td>
	<td class="input"><input name="list[0].insuredidno" value="123123123" > </td>
</tr>
<tr>
	<td class="title"><label>被保险人二</label></td>
	<td class="input"><input name="list[1].insuredname" value="被保险人二" > </td>
	<td class="input"><input name="list[1].insuredidno" value="22312fds3" > </td>
</tr>
<script type="text/javascript">
$(document).ready(function(){
	$("#multiParaTypeTestBtn").click(function(){
		$("#multiParaTypeTest").form('submit', {
			url: '../tags/test.json',
			onSubmit: function(param){
				return $(this).form('validate');
			},
			success: function(result){
				var json = $.parseJSON(result);
				if(json.code == '0'){
					$riskRelaTable.datagrid('reload');
					$.messager.alert('提示','操作成功!','info');
				} else {
					$.messager.alert('警告',json.message,'error');
				}
			}
		})
	});
})
</script>
【spring mvc】静态资源处理 spring mvc Spring MVC静态资源处理
Spring MVC静态资源处理——<mvc:resources /> ||<mvc:default-servlet-handler />

调整web.xml中的DispatcherServlet的配置,使其可以捕获所有的请求:
    <servlet>
        <servlet-name>springMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>


采用<mvc:default-servlet-handler />
...................


采用<mvc:resources />
<mvc:default-servlet-handler />将静态资源的处理经由Spring MVC框架交回Web应用服务器处理。而<mvc:resources />更进一步,由Spring MVC框架自己处理静态资源,并添加一些有用的附加值功能。

首先,<mvc:resources />允许静态资源放在任何地方,如WEB-INF目录下、类路径下等,你甚至可以将JavaScript等静态文件打到JAR包中。通过location属性指定静态资源的位置,由于location属性是Resources类型,因此可以使用诸如"classpath:"等的资源前缀指定资源位置。传统Web容器的静态资源只能放在Web容器的根路径下,<mvc:resources />完全打破了这个限制。

其次,<mvc:resources />依据当前著名的Page Speed、YSlow等浏览器优化原则对静态资源提供优化。你可以通过cacheSeconds属性指定静态资源在浏览器端的缓存时间,一般可将该时间设置为一年,以充分利用浏览器端的缓存。在输出静态资源时,会根据配置设置好响应报文头的Expires 和 Cache-Control值。

在接收到静态资源的获取请求时,会检查请求头的Last-Modified值,如果静态资源没有发生变化,则直接返回303相应状态码,提示客户端使用浏览器缓存的数据,而非将静态资源的内容输出到客户端,以充分节省带宽,提高程序性能。

在springMVC-servlet中添加如下配置:

<mvc:resources location="/,classpath:/META-INF/publicResources/" mapping="/resources/**"/>
【spring mvc】@InitBinder 表单数据绑定 spring mvc
/*
 * Spring表单的initBinder:绑定表单复杂属性:
 * http://blog.sina.com.cn/s/blog_65dcacbb0100hwa8.html
 *
 * spring mvc使用@InitBinder 标签对表单数据绑定:
 * http://blog.csdn.net/axin66ok/article/details/17938095
 */

/**
 * @author c1panx
 * @ 2015年5月26日  上午11:34:50
 */
public class BaseController {
	
	/**
	 * 自定义springMVC的属性编辑器主要有两种方式:<br>
	 * 一种是使用@InitBinder标签在运行期注册一个属性编辑器,这种编辑器只在当前Controller里面有效;<br>
	 * 还有一种是实现自己的 WebBindingInitializer,然后定义一个 AnnotationMethodHandlerAdapter的bean,在此bean里面进行注册 ,这种属性编辑器是全局的。
	 * <br>
	 * 本类采用方式一 <br>
	 * 默认返回日期格式:yyyy-MM-dd,其他特殊情况时可继承重写
	 * <hr>
	 * <a href="http://haohaoxuexi.iteye.com/blog/1190065">springMVC自定义属性编辑器</a> <br>
	 * <a href="http://blog.csdn.net/whumr1/article/details/8056285">spring mvc绑定对象String转Date</a>
	 * <br>
	 * @param request
	 * @param binder
	 * @throws Exception
	 */
	@InitBinder
	protected void initBinder(HttpServletRequest request,
			ServletRequestDataBinder binder) throws Exception {
		// 对于需要转换为Date类型的属性,使用DateEditor进行处理
		binder.registerCustomEditor(java.util.Date.class, new DateUtilEditor());
		binder.registerCustomEditor(java.sql.Date.class, new DateSQLEditor());
	}
}


/**************************************************************************************/


/**
 * 
 */
package com.cignacmb.productdef.mvc.editor;

import java.beans.PropertyEditorSupport;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;

import com.cignacmb.productdef.common.Constants;

/**
 * springMVC的属性编辑器 —— 日期编辑器 java.util.Date类型
 * @author c1panx
 * @ 2015年5月26日  上午11:11:15
 */
public class DateUtilEditor extends PropertyEditorSupport {

	private static final DateFormat DATEFORMAT = new SimpleDateFormat("yyyy-MM-dd");
//	private static final DateFormat TIMEFORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	private boolean allowEmpty = true;
	private DateFormat dateFormat;

	public DateUtilEditor() {
		this.dateFormat = DATEFORMAT;
	}
	
	public DateUtilEditor(boolean allowEmpty) {
		this.allowEmpty = allowEmpty;
	}
	
	public DateUtilEditor(DateFormat dateFormat) {
		this.dateFormat = dateFormat;
	}
	
	public DateUtilEditor(DateFormat dateFormat, boolean allowEmpty) {
		this.dateFormat = dateFormat;
		this.allowEmpty = allowEmpty;
	}

	@Override
	public String getAsText() {
		if (dateFormat == null) {
			dateFormat = DATEFORMAT;
		}
		Date date = (Date) getValue();
		return null == date ? null : dateFormat.format(date);
	}

	@Override
	public void setAsText(String text) throws IllegalArgumentException {
		if (this.allowEmpty && StringUtils.isBlank(text)) {
			// Treat empty String as null value.
			setValue(null);
		} else {
			try {
				// 常用日期格式字符串转换成日期对象
				Date date = DateUtils.parseDate(text, Constants.DatePattern);
				setValue(date);
			} catch (ParseException e) {
				throw new IllegalArgumentException("Could not parse date: "
						+ e.getMessage(), e);
			}
		}
	}

}


/**************************************************************************************/


/**
 * 
 */
package com.cignacmb.productdef.mvc.editor;

import java.beans.PropertyEditorSupport;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;

import com.cignacmb.productdef.common.Constants;
import com.cignacmb.productdef.util.Tools;

/**
 * springMVC的属性编辑器 —— 日期编辑器 java.sql.Date类型
 * @author c1panx
 * @ 2015年5月26日  上午11:11:15
 */
public class DateSQLEditor extends PropertyEditorSupport {

	private static final DateFormat DATEFORMAT = new SimpleDateFormat("yyyy-MM-dd");

	private boolean allowEmpty = true;

	public DateSQLEditor() {
	}
	
	public DateSQLEditor(boolean allowEmpty) {
		this.allowEmpty = allowEmpty;
	}
	
	@Override
	public String getAsText() {
		java.sql.Date sqlDate = (java.sql.Date) getValue();
		java.util.Date utilDate = Tools.sqlDateToUtilDate(sqlDate);
		return null == utilDate ? "" : DATEFORMAT.format(utilDate);
	}

	@Override
	public void setAsText(String text) throws IllegalArgumentException {
		if (this.allowEmpty && StringUtils.isBlank(text)) {
			// Treat empty String as null value.
			setValue(null);
		} else {
			try {
				// 常用日期格式字符串转换成日期对象
				Date date = DateUtils.parseDate(text, Constants.DatePattern);
				setValue(Tools.utilDateToSqlDate(date));
			} catch (ParseException e) {
				throw new IllegalArgumentException("Could not parse date: "
						+ e.getMessage(), e);
			}
		}
	}

}


【spring mvc】mybatis-generator之JavaTypeResolverDefaultImpl.java spring mvc
/*
 *  Copyright 2005 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.mybatis.generator.internal.types;

import java.math.BigDecimal;
import java.sql.Types;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.JavaTypeResolver;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.config.Context;
import org.mybatis.generator.config.PropertyRegistry;
import org.mybatis.generator.internal.util.StringUtility;

/**
 * 新核心系统中数据库中的Date只包含年月日信息,时间保存至对应的time字段<br>
 * mybatis generator默认映射至java.util.Date<br>
 * 针对新核心,需重新映射至java.sql.Date<br>
 * 在xml中设置配置开关:<br>
 * property name="sqldate" value="true" <br>
 * true: 表示使用java.sql.date,
 * 其他情况使用java.util.Date
 * @author Jeff Butler
 */
public class JavaTypeResolverDefaultImpl implements JavaTypeResolver {

    protected List<String> warnings;

    protected Properties properties;

    protected Context context;

    protected boolean forceBigDecimals;

    protected Map<Integer, JdbcTypeInformation> typeMap;
    
    public JavaTypeResolverDefaultImpl() {
        super();
        properties = new Properties();
        typeMap = new HashMap<Integer, JdbcTypeInformation>();

        typeMap.put(Types.ARRAY, new JdbcTypeInformation("ARRAY", //$NON-NLS-1$
                new FullyQualifiedJavaType(Object.class.getName())));
        typeMap.put(Types.BIGINT, new JdbcTypeInformation("BIGINT", //$NON-NLS-1$
                new FullyQualifiedJavaType(Long.class.getName())));
        typeMap.put(Types.BINARY, new JdbcTypeInformation("BINARY", //$NON-NLS-1$
                new FullyQualifiedJavaType("byte[]"))); //$NON-NLS-1$
        typeMap.put(Types.BIT, new JdbcTypeInformation("BIT", //$NON-NLS-1$
                new FullyQualifiedJavaType(Boolean.class.getName())));
        typeMap.put(Types.BLOB, new JdbcTypeInformation("BLOB", //$NON-NLS-1$
                new FullyQualifiedJavaType("byte[]"))); //$NON-NLS-1$
        typeMap.put(Types.BOOLEAN, new JdbcTypeInformation("BOOLEAN", //$NON-NLS-1$
                new FullyQualifiedJavaType(Boolean.class.getName())));
        typeMap.put(Types.CHAR, new JdbcTypeInformation("CHAR", //$NON-NLS-1$
                new FullyQualifiedJavaType(String.class.getName())));
        typeMap.put(Types.CLOB, new JdbcTypeInformation("CLOB", //$NON-NLS-1$
                new FullyQualifiedJavaType(String.class.getName())));
        typeMap.put(Types.DATALINK, new JdbcTypeInformation("DATALINK", //$NON-NLS-1$
                new FullyQualifiedJavaType(Object.class.getName())));
        typeMap.put(Types.DATE, new JdbcTypeInformation("DATE", //$NON-NLS-1$
                new FullyQualifiedJavaType(Date.class.getName())));
        typeMap.put(Types.DISTINCT, new JdbcTypeInformation("DISTINCT", //$NON-NLS-1$
                new FullyQualifiedJavaType(Object.class.getName())));
        typeMap.put(Types.DOUBLE, new JdbcTypeInformation("DOUBLE", //$NON-NLS-1$
                new FullyQualifiedJavaType(Double.class.getName())));
        typeMap.put(Types.FLOAT, new JdbcTypeInformation("FLOAT", //$NON-NLS-1$
                new FullyQualifiedJavaType(Double.class.getName())));
        typeMap.put(Types.INTEGER, new JdbcTypeInformation("INTEGER", //$NON-NLS-1$
                new FullyQualifiedJavaType(Integer.class.getName())));
        typeMap.put(Types.JAVA_OBJECT, new JdbcTypeInformation("JAVA_OBJECT", //$NON-NLS-1$
                new FullyQualifiedJavaType(Object.class.getName())));
        typeMap.put(Jdbc4Types.LONGNVARCHAR, new JdbcTypeInformation("LONGNVARCHAR", //$NON-NLS-1$
                new FullyQualifiedJavaType(String.class.getName())));
        typeMap.put(Types.LONGVARBINARY, new JdbcTypeInformation(
                "LONGVARBINARY", //$NON-NLS-1$
                new FullyQualifiedJavaType("byte[]"))); //$NON-NLS-1$
        typeMap.put(Types.LONGVARCHAR, new JdbcTypeInformation("LONGVARCHAR", //$NON-NLS-1$
                new FullyQualifiedJavaType(String.class.getName())));
        typeMap.put(Jdbc4Types.NCHAR, new JdbcTypeInformation("NCHAR", //$NON-NLS-1$
                new FullyQualifiedJavaType(String.class.getName())));
        typeMap.put(Jdbc4Types.NCLOB, new JdbcTypeInformation("NCLOB", //$NON-NLS-1$
                new FullyQualifiedJavaType(String.class.getName())));
        typeMap.put(Jdbc4Types.NVARCHAR, new JdbcTypeInformation("NVARCHAR", //$NON-NLS-1$
                new FullyQualifiedJavaType(String.class.getName())));
        typeMap.put(Types.NULL, new JdbcTypeInformation("NULL", //$NON-NLS-1$
                new FullyQualifiedJavaType(Object.class.getName())));
        typeMap.put(Types.OTHER, new JdbcTypeInformation("OTHER", //$NON-NLS-1$
                new FullyQualifiedJavaType(Object.class.getName())));
        typeMap.put(Types.REAL, new JdbcTypeInformation("REAL", //$NON-NLS-1$
                new FullyQualifiedJavaType(Float.class.getName())));
        typeMap.put(Types.REF, new JdbcTypeInformation("REF", //$NON-NLS-1$
                new FullyQualifiedJavaType(Object.class.getName())));
        typeMap.put(Types.SMALLINT, new JdbcTypeInformation("SMALLINT", //$NON-NLS-1$
                new FullyQualifiedJavaType(Short.class.getName())));
        typeMap.put(Types.STRUCT, new JdbcTypeInformation("STRUCT", //$NON-NLS-1$
                new FullyQualifiedJavaType(Object.class.getName())));
        typeMap.put(Types.TIME, new JdbcTypeInformation("TIME", //$NON-NLS-1$
                new FullyQualifiedJavaType(Date.class.getName())));
        typeMap.put(Types.TIMESTAMP, new JdbcTypeInformation("TIMESTAMP", //$NON-NLS-1$
                new FullyQualifiedJavaType(Date.class.getName())));
        typeMap.put(Types.TINYINT, new JdbcTypeInformation("TINYINT", //$NON-NLS-1$
                new FullyQualifiedJavaType(Byte.class.getName())));
        typeMap.put(Types.VARBINARY, new JdbcTypeInformation("VARBINARY", //$NON-NLS-1$
                new FullyQualifiedJavaType("byte[]"))); //$NON-NLS-1$
        typeMap.put(Types.VARCHAR, new JdbcTypeInformation("VARCHAR", //$NON-NLS-1$
                new FullyQualifiedJavaType(String.class.getName())));
        
    }

    public void addConfigurationProperties(Properties properties) {
        this.properties.putAll(properties);
        forceBigDecimals = StringUtility
                .isTrue(properties
                        .getProperty(PropertyRegistry.TYPE_RESOLVER_FORCE_BIG_DECIMALS));
    }

    public FullyQualifiedJavaType calculateJavaType(
            IntrospectedColumn introspectedColumn) {
        FullyQualifiedJavaType answer;
        JdbcTypeInformation jdbcTypeInformation = typeMap
                .get(introspectedColumn.getJdbcType());

        if (jdbcTypeInformation == null) {
            switch (introspectedColumn.getJdbcType()) {
            case Types.DECIMAL:
            case Types.NUMERIC:
                if (introspectedColumn.getScale() > 0
                        || introspectedColumn.getLength() > 18
                        || forceBigDecimals) {
                    answer = new FullyQualifiedJavaType(BigDecimal.class
                            .getName());
                } else if (introspectedColumn.getLength() > 9) {
                    answer = new FullyQualifiedJavaType(Long.class.getName());
                } else if (introspectedColumn.getLength() > 4) {
                    answer = new FullyQualifiedJavaType(Integer.class.getName());
                } else {
                    answer = new FullyQualifiedJavaType(Short.class.getName());
                }
                break;

            default:
                answer = null;
                break;
            }
        } else {
            answer = jdbcTypeInformation.getFullyQualifiedJavaType();
        }

        return answer;
    }

    public String calculateJdbcTypeName(IntrospectedColumn introspectedColumn) {
        String answer;
        JdbcTypeInformation jdbcTypeInformation = typeMap
                .get(introspectedColumn.getJdbcType());

        if (jdbcTypeInformation == null) {
            switch (introspectedColumn.getJdbcType()) {
            case Types.DECIMAL:
                answer = "DECIMAL"; //$NON-NLS-1$
                break;
            case Types.NUMERIC:
                answer = "NUMERIC"; //$NON-NLS-1$
                break;
            default:
                answer = null;
                break;
            }
        } else {
            answer = jdbcTypeInformation.getJdbcTypeName();
        }

        return answer;
    }

    public void setWarnings(List<String> warnings) {
        this.warnings = warnings;
    }

    public void setContext(Context context) {
        this.context = context;
        // TODO add
        String sqldate = context.getProperty("sqldate");
        System.out.println("sqldate = " + sqldate);
		if ("true".equalsIgnoreCase(sqldate)) {
			typeMap.put(Types.DATE, new JdbcTypeInformation("DATE",
					new FullyQualifiedJavaType(java.sql.Date.class.getName())));
			typeMap.put(Types.TIME, new JdbcTypeInformation("TIME",
					new FullyQualifiedJavaType(java.sql.Date.class.getName())));
			typeMap.put(Types.TIMESTAMP, new JdbcTypeInformation("TIMESTAMP",
					new FullyQualifiedJavaType(java.sql.Date.class.getName())));
		}
    }

    public static class JdbcTypeInformation {
        private String jdbcTypeName;

        private FullyQualifiedJavaType fullyQualifiedJavaType;

        public JdbcTypeInformation(String jdbcTypeName,
                FullyQualifiedJavaType fullyQualifiedJavaType) {
            this.jdbcTypeName = jdbcTypeName;
            this.fullyQualifiedJavaType = fullyQualifiedJavaType;
        }

        public String getJdbcTypeName() {
            return jdbcTypeName;
        }

        public FullyQualifiedJavaType getFullyQualifiedJavaType() {
            return fullyQualifiedJavaType;
        }
    }
}
【spring mvc】mybatis-generator之DatabaseIntrospector.java spring mvc
/*
 *  Copyright 2005 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.mybatis.generator.internal.db;

import static org.mybatis.generator.internal.util.JavaBeansUtil.getCamelCaseString;
import static org.mybatis.generator.internal.util.JavaBeansUtil.getValidPropertyName;
import static org.mybatis.generator.internal.util.StringUtility.composeFullyQualifiedTableName;
import static org.mybatis.generator.internal.util.StringUtility.isTrue;
import static org.mybatis.generator.internal.util.StringUtility.stringContainsSQLWildcard;
import static org.mybatis.generator.internal.util.StringUtility.stringContainsSpace;
import static org.mybatis.generator.internal.util.StringUtility.stringHasValue;
import static org.mybatis.generator.internal.util.messages.Messages.getString;

import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.StringUtils;
import org.mybatis.generator.api.FullyQualifiedTable;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.JavaTypeResolver;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.config.ColumnOverride;
import org.mybatis.generator.config.Context;
import org.mybatis.generator.config.GeneratedKey;
import org.mybatis.generator.config.PropertyRegistry;
import org.mybatis.generator.config.TableConfiguration;
import org.mybatis.generator.internal.ObjectFactory;
import org.mybatis.generator.logging.Log;
import org.mybatis.generator.logging.LogFactory;

/**
 * <a href="http://blog.csdn.net/isea533/article/details/42102297">MyBatis Generator 详解</a><br>
 * table 元素:schema:数据库的schema,可以使用SQL通配符匹配。如果设置了该值,生成SQL的表名会变成如schema.tableName的形式。
 * <br>
 * 因此重写本类,在table 元素中不配置schema时,采用content中的property配置。
 * context节点中配置示例:
 * <property name="schema" value="lis_dev"/>
 * @author Jeff Butler
 */
public class DatabaseIntrospector {

    private DatabaseMetaData databaseMetaData;
    private JavaTypeResolver javaTypeResolver;
    private List<String> warnings;
    private Context context;
    private Log logger;

    public DatabaseIntrospector(Context context,
            DatabaseMetaData databaseMetaData,
            JavaTypeResolver javaTypeResolver, List<String> warnings) {
        super();
        this.context = context;
        this.databaseMetaData = databaseMetaData;
        this.javaTypeResolver = javaTypeResolver;
        this.warnings = warnings;
        logger = LogFactory.getLog(getClass());
    }

    private void calculatePrimaryKey(FullyQualifiedTable table,
            IntrospectedTable introspectedTable) {
        ResultSet rs = null;

        try {
            rs = databaseMetaData.getPrimaryKeys(
                    table.getIntrospectedCatalog(), table
                            .getIntrospectedSchema(), table
                            .getIntrospectedTableName());
        } catch (SQLException e) {
            closeResultSet(rs);
            warnings.add(getString("Warning.15")); //$NON-NLS-1$
            return;
        }

        try {
            // keep primary columns in key sequence order
            Map<Short, String> keyColumns = new TreeMap<Short, String>();
            while (rs.next()) {
                String columnName = rs.getString("COLUMN_NAME"); //$NON-NLS-1$
                short keySeq = rs.getShort("KEY_SEQ"); //$NON-NLS-1$
                keyColumns.put(keySeq, columnName);
            }
            
            for (String columnName : keyColumns.values()) {
                introspectedTable.addPrimaryKeyColumn(columnName);
            }
        } catch (SQLException e) {
            // ignore the primary key if there's any error
        } finally {
            closeResultSet(rs);
        }
    }

    private void closeResultSet(ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                // ignore
                ;
            }
        }
    }

    private void reportIntrospectionWarnings(
            IntrospectedTable introspectedTable,
            TableConfiguration tableConfiguration, FullyQualifiedTable table) {
        // make sure that every column listed in column overrides
        // actually exists in the table
        for (ColumnOverride columnOverride : tableConfiguration
                .getColumnOverrides()) {
            if (introspectedTable.getColumn(columnOverride.getColumnName()) == null) {
                warnings.add(getString("Warning.3", //$NON-NLS-1$
                        columnOverride.getColumnName(), table.toString()));
            }
        }

        // make sure that every column listed in ignored columns
        // actually exists in the table
        for (String string : tableConfiguration.getIgnoredColumnsInError()) {
            warnings.add(getString("Warning.4", //$NON-NLS-1$
                    string, table.toString()));
        }

        GeneratedKey generatedKey = tableConfiguration.getGeneratedKey();
        if (generatedKey != null
                && introspectedTable.getColumn(generatedKey.getColumn()) == null) {
            if (generatedKey.isIdentity()) {
                warnings.add(getString("Warning.5", //$NON-NLS-1$
                        generatedKey.getColumn(), table.toString()));
            } else {
                warnings.add(getString("Warning.6", //$NON-NLS-1$
                        generatedKey.getColumn(), table.toString()));
            }
        }
    }

    /**
     * Returns a List<IntrospectedTable> that matches the specified table
     * configuration.
     * 
     * @param tc
     * @return a list of introspected tables
     * @throws SQLException
     */
    public List<IntrospectedTable> introspectTables(TableConfiguration tc)
            throws SQLException {

        // get the raw columns from the DB
        Map<ActualTableName, List<IntrospectedColumn>> columns = getColumns(tc);

        if (columns.isEmpty()) {
            warnings.add(getString("Warning.19", tc.getCatalog(), //$NON-NLS-1$
                    tc.getSchema(), tc.getTableName()));
            return null;
        }

        removeIgnoredColumns(tc, columns);
        calculateExtraColumnInformation(tc, columns);
        applyColumnOverrides(tc, columns);
        calculateIdentityColumns(tc, columns);

        List<IntrospectedTable> introspectedTables = calculateIntrospectedTables(
                tc, columns);

        // now introspectedTables has all the columns from all the
        // tables in the configuration. Do some validation...

        Iterator<IntrospectedTable> iter = introspectedTables.iterator();
        while (iter.hasNext()) {
            IntrospectedTable introspectedTable = iter.next();

            if (!introspectedTable.hasAnyColumns()) {
                // add warning that the table has no columns, remove from the
                // list
                String warning = getString(
                                "Warning.1", introspectedTable.getFullyQualifiedTable().toString()); //$NON-NLS-1$
                warnings.add(warning);
                iter.remove();
            } else if (!introspectedTable.hasPrimaryKeyColumns()
                    && !introspectedTable.hasBaseColumns()) {
                // add warning that the table has only BLOB columns, remove from
                // the list
                String warning = getString(
                                "Warning.18", introspectedTable.getFullyQualifiedTable().toString()); //$NON-NLS-1$ 
                warnings.add(warning);
                iter.remove();
            } else {
                // now make sure that all columns called out in the
                // configuration
                // actually exist
                reportIntrospectionWarnings(introspectedTable, tc,
                        introspectedTable.getFullyQualifiedTable());
            }
        }

        return introspectedTables;
    }

    /**
     * @param tc
     * @param columns
     */
    private void removeIgnoredColumns(TableConfiguration tc,
            Map<ActualTableName, List<IntrospectedColumn>> columns) {
        for (Map.Entry<ActualTableName, List<IntrospectedColumn>> entry : columns
                .entrySet()) {
            Iterator<IntrospectedColumn> tableColumns = (entry.getValue())
                    .iterator();
            while (tableColumns.hasNext()) {
                IntrospectedColumn introspectedColumn = tableColumns.next();
                if (tc
                        .isColumnIgnored(introspectedColumn
                                .getActualColumnName())) {
                    tableColumns.remove();
                    if (logger.isDebugEnabled()) {
                        logger.debug(getString("Tracing.3", //$NON-NLS-1$
                                introspectedColumn.getActualColumnName(), entry
                                        .getKey().toString()));
                    }
                }
            }
        }
    }

    private void calculateExtraColumnInformation(TableConfiguration tc,
            Map<ActualTableName, List<IntrospectedColumn>> columns) {
        StringBuilder sb = new StringBuilder();
        Pattern pattern = null;
        String replaceString = null;
        if (tc.getColumnRenamingRule() != null) {
            pattern = Pattern.compile(tc.getColumnRenamingRule()
                    .getSearchString());
            replaceString = tc.getColumnRenamingRule().getReplaceString();
            replaceString = replaceString == null ? "" : replaceString; //$NON-NLS-1$
        }

        for (Map.Entry<ActualTableName, List<IntrospectedColumn>> entry : columns
                .entrySet()) {
            for (IntrospectedColumn introspectedColumn : entry.getValue()) {
                String calculatedColumnName;
                if (pattern == null) {
                    calculatedColumnName = introspectedColumn
                            .getActualColumnName();
                } else {
                    Matcher matcher = pattern.matcher(introspectedColumn
                            .getActualColumnName());
                    calculatedColumnName = matcher.replaceAll(replaceString);
                }

                if (isTrue(tc
                        .getProperty(PropertyRegistry.TABLE_USE_ACTUAL_COLUMN_NAMES))) {
                    introspectedColumn.setJavaProperty(
                            getValidPropertyName(calculatedColumnName));
                } else if (isTrue(tc
                                .getProperty(PropertyRegistry.TABLE_USE_COMPOUND_PROPERTY_NAMES))) {
                    sb.setLength(0);
                    sb.append(calculatedColumnName);
                    sb.append('_');
                    sb.append(getCamelCaseString(
                            introspectedColumn.getRemarks(), true));
                    introspectedColumn.setJavaProperty(
                            getValidPropertyName(sb.toString()));
                } else {
                    introspectedColumn.setJavaProperty(
                            getCamelCaseString(calculatedColumnName, false));
                }

                FullyQualifiedJavaType fullyQualifiedJavaType = javaTypeResolver
                        .calculateJavaType(introspectedColumn);

                if (fullyQualifiedJavaType != null) {
                    introspectedColumn
                            .setFullyQualifiedJavaType(fullyQualifiedJavaType);
                    introspectedColumn.setJdbcTypeName(javaTypeResolver
                            .calculateJdbcTypeName(introspectedColumn));
                } else {
                    // type cannot be resolved. Check for ignored or overridden
                    boolean warn = true;
                    if (tc.isColumnIgnored(introspectedColumn
                            .getActualColumnName())) {
                        warn = false;
                    }

                    ColumnOverride co = tc.getColumnOverride(introspectedColumn
                            .getActualColumnName());
                    if (co != null) {
                        if (stringHasValue(co.getJavaType())
                                && stringHasValue(co.getJavaType())) {
                            warn = false;
                        }
                    }

                    // if the type is not supported, then we'll report a warning
                    if (warn) {
                        introspectedColumn
                                .setFullyQualifiedJavaType(FullyQualifiedJavaType
                                        .getObjectInstance());
                        introspectedColumn.setJdbcTypeName("OTHER"); //$NON-NLS-1$

                        String warning = getString("Warning.14", //$NON-NLS-1$
                                Integer.toString(introspectedColumn.getJdbcType()),
                                entry.getKey().toString(),
                                introspectedColumn.getActualColumnName());

                        warnings.add(warning);
                    }
                }

                if (context.autoDelimitKeywords()) {
                    if (SqlReservedWords.containsWord(introspectedColumn
                            .getActualColumnName())) {
                        introspectedColumn.setColumnNameDelimited(true);
                    }
                }

                if (tc.isAllColumnDelimitingEnabled()) {
                    introspectedColumn.setColumnNameDelimited(true);
                }
            }
        }
    }

    private void calculateIdentityColumns(TableConfiguration tc,
            Map<ActualTableName, List<IntrospectedColumn>> columns) {
        GeneratedKey gk = tc.getGeneratedKey();
        if (gk == null) {
            // no generated key, then no identity or sequence columns
            return;
        }
        
        for (Map.Entry<ActualTableName, List<IntrospectedColumn>> entry : columns
                .entrySet()) {
            for (IntrospectedColumn introspectedColumn : entry.getValue()) {
                if (isMatchedColumn(introspectedColumn, gk)) {
                    if (gk.isIdentity() || gk.isJdbcStandard()) {
                        introspectedColumn.setIdentity(true);
                        introspectedColumn.setSequenceColumn(false);
                    } else {
                        introspectedColumn.setIdentity(false);
                        introspectedColumn.setSequenceColumn(true);
                    }
                }
            }
        }
    }
    
    private boolean isMatchedColumn(IntrospectedColumn introspectedColumn, GeneratedKey gk) {
        if (introspectedColumn.isColumnNameDelimited()) {
            return introspectedColumn.getActualColumnName().equals(gk.getColumn());
        } else {
            return introspectedColumn.getActualColumnName().equalsIgnoreCase(gk.getColumn());
        }
    }

    private void applyColumnOverrides(TableConfiguration tc,
            Map<ActualTableName, List<IntrospectedColumn>> columns) {
        for (Map.Entry<ActualTableName, List<IntrospectedColumn>> entry : columns
                .entrySet()) {
            for (IntrospectedColumn introspectedColumn : entry.getValue()) {
                ColumnOverride columnOverride = tc
                        .getColumnOverride(introspectedColumn
                                .getActualColumnName());

                if (columnOverride != null) {
                    if (logger.isDebugEnabled()) {
                        logger.debug(getString("Tracing.4", //$NON-NLS-1$
                                introspectedColumn.getActualColumnName(), entry
                                        .getKey().toString()));
                    }

                    if (stringHasValue(columnOverride
                            .getJavaProperty())) {
                        introspectedColumn.setJavaProperty(columnOverride
                                .getJavaProperty());
                    }

                    if (stringHasValue(columnOverride
                            .getJavaType())) {
                        introspectedColumn
                                .setFullyQualifiedJavaType(new FullyQualifiedJavaType(
                                        columnOverride.getJavaType()));
                    }

                    if (stringHasValue(columnOverride
                            .getJdbcType())) {
                        introspectedColumn.setJdbcTypeName(columnOverride
                                .getJdbcType());
                    }

                    if (stringHasValue(columnOverride
                            .getTypeHandler())) {
                        introspectedColumn.setTypeHandler(columnOverride
                                .getTypeHandler());
                    }

                    if (columnOverride.isColumnNameDelimited()) {
                        introspectedColumn.setColumnNameDelimited(true);
                    }

                    introspectedColumn.setProperties(columnOverride
                            .getProperties());
                }
            }
        }
    }

    /**
     * This method returns a Map<ActualTableName, List<ColumnDefinitions>> of
     * columns returned from the database introspection.
     * 
     * @param tc
     * @return introspected columns
     * @throws SQLException
     */
    private Map<ActualTableName, List<IntrospectedColumn>> getColumns(
            TableConfiguration tc) throws SQLException {
        String localCatalog;
        String localSchema;
        String localTableName;
        
        // TODO
		String schema = context.getProperty("schema");
		if (StringUtils.isBlank(schema)) {
			schema = null;
		}

        boolean delimitIdentifiers = tc.isDelimitIdentifiers()
                || stringContainsSpace(tc.getCatalog())
                || stringContainsSpace(tc.getSchema())
                || stringContainsSpace(tc.getTableName());

        if (delimitIdentifiers) {
            localCatalog = tc.getCatalog();
            localSchema = tc.getSchema();
            localTableName = tc.getTableName();
        } else if (databaseMetaData.storesLowerCaseIdentifiers()) {
            localCatalog = tc.getCatalog() == null ? null : tc.getCatalog()
                    .toLowerCase();
            localSchema = tc.getSchema() == null ? null : tc.getSchema()
                    .toLowerCase();
            localTableName = tc.getTableName() == null ? null : tc
                    .getTableName().toLowerCase();
            // TODO add
			schema = null == schema ? null : schema.toLowerCase();
        } else if (databaseMetaData.storesUpperCaseIdentifiers()) {
            localCatalog = tc.getCatalog() == null ? null : tc.getCatalog()
                    .toUpperCase();
            localSchema = tc.getSchema() == null ? null : tc.getSchema()
                    .toUpperCase();
            localTableName = tc.getTableName() == null ? null : tc
                    .getTableName().toUpperCase();
            // TODO add
			schema = null == schema ? null : schema.toUpperCase();
        } else {
            localCatalog = tc.getCatalog();
            localSchema = tc.getSchema();
            localTableName = tc.getTableName();
        }

        if (tc.isWildcardEscapingEnabled()) {
            String escapeString = databaseMetaData.getSearchStringEscape();

            StringBuilder sb = new StringBuilder();
            StringTokenizer st;
            if (localSchema != null) {
                st = new StringTokenizer(localSchema, "_%", true); //$NON-NLS-1$
                while (st.hasMoreTokens()) {
                    String token = st.nextToken();
                    if (token.equals("_") //$NON-NLS-1$
                            || token.equals("%")) { //$NON-NLS-1$
                        sb.append(escapeString);
                    }
                    sb.append(token);
                }
                localSchema = sb.toString();
            }

            sb.setLength(0);
            st = new StringTokenizer(localTableName, "_%", true); //$NON-NLS-1$
            while (st.hasMoreTokens()) {
                String token = st.nextToken();
                if (token.equals("_") //$NON-NLS-1$
                        || token.equals("%")) { //$NON-NLS-1$
                    sb.append(escapeString);
                }
                sb.append(token);
            }
            localTableName = sb.toString();
        }

        Map<ActualTableName, List<IntrospectedColumn>> answer = new HashMap<ActualTableName, List<IntrospectedColumn>>();

        if (logger.isDebugEnabled()) {
            String fullTableName = composeFullyQualifiedTableName(localCatalog, localSchema,
                            localTableName, '.');
            logger.debug(getString("Tracing.1", fullTableName)); //$NON-NLS-1$
        }

//        ResultSet rs = databaseMetaData.getColumns(localCatalog, localSchema,
//                localTableName, null);
        // TODO edit
		String tSchema = StringUtils.isNotBlank(localSchema) ? localSchema : schema;
        ResultSet rs = databaseMetaData.getColumns(localCatalog, tSchema, localTableName, null);

        while (rs.next()) {
            IntrospectedColumn introspectedColumn = ObjectFactory
                    .createIntrospectedColumn(context);

            introspectedColumn.setTableAlias(tc.getAlias());
            introspectedColumn.setJdbcType(rs.getInt("DATA_TYPE")); //$NON-NLS-1$
            introspectedColumn.setLength(rs.getInt("COLUMN_SIZE")); //$NON-NLS-1$
            introspectedColumn.setActualColumnName(rs.getString("COLUMN_NAME")); //$NON-NLS-1$
            introspectedColumn
                    .setNullable(rs.getInt("NULLABLE") == DatabaseMetaData.columnNullable); //$NON-NLS-1$
            introspectedColumn.setScale(rs.getInt("DECIMAL_DIGITS")); //$NON-NLS-1$
            introspectedColumn.setRemarks(rs.getString("REMARKS")); //$NON-NLS-1$
            introspectedColumn.setDefaultValue(rs.getString("COLUMN_DEF")); //$NON-NLS-1$

            ActualTableName atn = new ActualTableName(
                    rs.getString("TABLE_CAT"), //$NON-NLS-1$
                    rs.getString("TABLE_SCHEM"), //$NON-NLS-1$
                    rs.getString("TABLE_NAME")); //$NON-NLS-1$

            List<IntrospectedColumn> columns = answer.get(atn);
            if (columns == null) {
                columns = new ArrayList<IntrospectedColumn>();
                answer.put(atn, columns);
            }

            columns.add(introspectedColumn);

            if (logger.isDebugEnabled()) {
                logger.debug(getString(
                        "Tracing.2", //$NON-NLS-1$
                        introspectedColumn.getActualColumnName(), Integer
                                .toString(introspectedColumn.getJdbcType()),
                        atn.toString()));
            }
        }

        closeResultSet(rs);

        if (answer.size() > 1
                && !stringContainsSQLWildcard(localSchema)
                && !stringContainsSQLWildcard(localTableName)) {
            // issue a warning if there is more than one table and
            // no wildcards were used
            ActualTableName inputAtn = new ActualTableName(tc.getCatalog(), tc
                    .getSchema(), tc.getTableName());

            StringBuilder sb = new StringBuilder();
            boolean comma = false;
            for (ActualTableName atn : answer.keySet()) {
                if (comma) {
                    sb.append(',');
                } else {
                    comma = true;
                }
                sb.append(atn.toString());
            }

            warnings.add(getString("Warning.25", //$NON-NLS-1$
                    inputAtn.toString(), sb.toString()));
        }

        return answer;
    }

    private List<IntrospectedTable> calculateIntrospectedTables(
            TableConfiguration tc,
            Map<ActualTableName, List<IntrospectedColumn>> columns) {
        boolean delimitIdentifiers = tc.isDelimitIdentifiers()
                || stringContainsSpace(tc.getCatalog())
                || stringContainsSpace(tc.getSchema())
                || stringContainsSpace(tc.getTableName());

        List<IntrospectedTable> answer = new ArrayList<IntrospectedTable>();

        for (Map.Entry<ActualTableName, List<IntrospectedColumn>> entry : columns
                .entrySet()) {
            ActualTableName atn = entry.getKey();

            // we only use the returned catalog and schema if something was
            // actually
            // specified on the table configuration. If something was returned
            // from the DB for these fields, but nothing was specified on the
            // table
            // configuration, then some sort of DB default is being returned
            // and we don't want that in our SQL
            FullyQualifiedTable table = new FullyQualifiedTable(
                    stringHasValue(tc.getCatalog()) ? atn
                            .getCatalog() : null,
                    stringHasValue(tc.getSchema()) ? atn
                            .getSchema() : null,
                    atn.getTableName(),
                    tc.getDomainObjectName(),
                    tc.getAlias(),
                    isTrue(tc.getProperty(PropertyRegistry.TABLE_IGNORE_QUALIFIERS_AT_RUNTIME)),
                    tc.getProperty(PropertyRegistry.TABLE_RUNTIME_CATALOG),
                    tc.getProperty(PropertyRegistry.TABLE_RUNTIME_SCHEMA),
                    tc.getProperty(PropertyRegistry.TABLE_RUNTIME_TABLE_NAME),
                    delimitIdentifiers, context);

            IntrospectedTable introspectedTable = ObjectFactory
                    .createIntrospectedTable(tc, table, context);

            for (IntrospectedColumn introspectedColumn : entry.getValue()) {
                introspectedTable.addColumn(introspectedColumn);
            }

            calculatePrimaryKey(table, introspectedTable);

            answer.add(introspectedTable);
        }

        return answer;
    }
}
【spring mvc】mybatis-generator之IntrospectedTableMyBatis3Impl.java spring mvc
/*
 *  Copyright 2009 The Apache Software Foundation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.mybatis.generator.codegen.mybatis3;

import java.util.ArrayList;
import java.util.List;

import org.mybatis.generator.api.GeneratedJavaFile;
import org.mybatis.generator.api.GeneratedXmlFile;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.ProgressCallback;
import org.mybatis.generator.api.dom.java.CompilationUnit;
import org.mybatis.generator.api.dom.xml.Document;
import org.mybatis.generator.codegen.AbstractGenerator;
import org.mybatis.generator.codegen.AbstractJavaClientGenerator;
import org.mybatis.generator.codegen.AbstractJavaGenerator;
import org.mybatis.generator.codegen.AbstractXmlGenerator;
import org.mybatis.generator.codegen.mybatis3.javamapper.AnnotatedClientGenerator;
import org.mybatis.generator.codegen.mybatis3.javamapper.JavaMapperGenerator;
import org.mybatis.generator.codegen.mybatis3.javamapper.MixedClientGenerator;
import org.mybatis.generator.codegen.mybatis3.model.BaseRecordGenerator;
import org.mybatis.generator.codegen.mybatis3.model.ExampleGenerator;
import org.mybatis.generator.codegen.mybatis3.model.PrimaryKeyGenerator;
import org.mybatis.generator.codegen.mybatis3.model.RecordWithBLOBsGenerator;
import org.mybatis.generator.codegen.mybatis3.xmlmapper.XMLMapperGenerator;
import org.mybatis.generator.config.PropertyRegistry;
import org.mybatis.generator.internal.ObjectFactory;

/**
 * 重写,以支持mergeable属性<br>
 * 可不用重新打包jar,直接在工程中按此包结构重写即可
 * @author Jeff Butler
 * 
 */
public class IntrospectedTableMyBatis3Impl extends IntrospectedTable {
    protected List<AbstractJavaGenerator> javaModelGenerators;
    protected List<AbstractJavaGenerator> clientGenerators;
    protected AbstractXmlGenerator xmlMapperGenerator;

    public IntrospectedTableMyBatis3Impl() {
        super(TargetRuntime.MYBATIS3);
        javaModelGenerators = new ArrayList<AbstractJavaGenerator>();
        clientGenerators = new ArrayList<AbstractJavaGenerator>();
    }

    @Override
    public void calculateGenerators(List<String> warnings,
            ProgressCallback progressCallback) {
        calculateJavaModelGenerators(warnings, progressCallback);
        
        AbstractJavaClientGenerator javaClientGenerator =
            calculateClientGenerators(warnings, progressCallback);
            
        calculateXmlMapperGenerator(javaClientGenerator, warnings, progressCallback);
    }

    protected void calculateXmlMapperGenerator(AbstractJavaClientGenerator javaClientGenerator, 
            List<String> warnings,
            ProgressCallback progressCallback) {
        if (javaClientGenerator == null) {
            if (context.getSqlMapGeneratorConfiguration() != null) {
                xmlMapperGenerator = new XMLMapperGenerator();
            }
        } else {
            xmlMapperGenerator = javaClientGenerator.getMatchedXMLGenerator();
        }
        
        initializeAbstractGenerator(xmlMapperGenerator, warnings,
                progressCallback);
    }

    /**
     * 
     * @param warnings
     * @param progressCallback
     * @return true if an XML generator is required
     */
    protected AbstractJavaClientGenerator calculateClientGenerators(List<String> warnings,
            ProgressCallback progressCallback) {
        if (!rules.generateJavaClient()) {
            return null;
        }
        
        AbstractJavaClientGenerator javaGenerator = createJavaClientGenerator();
        if (javaGenerator == null) {
            return null;
        }

        initializeAbstractGenerator(javaGenerator, warnings, progressCallback);
        clientGenerators.add(javaGenerator);
        
        return javaGenerator;
    }
    
    protected AbstractJavaClientGenerator createJavaClientGenerator() {
        if (context.getJavaClientGeneratorConfiguration() == null) {
            return null;
        }
        
        String type = context.getJavaClientGeneratorConfiguration()
                .getConfigurationType();

        AbstractJavaClientGenerator javaGenerator;
        if ("XMLMAPPER".equalsIgnoreCase(type)) { //$NON-NLS-1$
            javaGenerator = new JavaMapperGenerator();
        } else if ("MIXEDMAPPER".equalsIgnoreCase(type)) { //$NON-NLS-1$
            javaGenerator = new MixedClientGenerator();
        } else if ("ANNOTATEDMAPPER".equalsIgnoreCase(type)) { //$NON-NLS-1$
            javaGenerator = new AnnotatedClientGenerator();
        } else if ("MAPPER".equalsIgnoreCase(type)) { //$NON-NLS-1$
            javaGenerator = new JavaMapperGenerator();
        } else {
            javaGenerator = (AbstractJavaClientGenerator) ObjectFactory
                    .createInternalObject(type);
        }
        
        return javaGenerator;
    }

    protected void calculateJavaModelGenerators(List<String> warnings,
            ProgressCallback progressCallback) {
        if (getRules().generateExampleClass()) {
            AbstractJavaGenerator javaGenerator = new ExampleGenerator();
            initializeAbstractGenerator(javaGenerator, warnings,
                    progressCallback);
            javaModelGenerators.add(javaGenerator);
        }

        if (getRules().generatePrimaryKeyClass()) {
            AbstractJavaGenerator javaGenerator = new PrimaryKeyGenerator();
            initializeAbstractGenerator(javaGenerator, warnings,
                    progressCallback);
            javaModelGenerators.add(javaGenerator);
        }

        if (getRules().generateBaseRecordClass()) {
            AbstractJavaGenerator javaGenerator = new BaseRecordGenerator();
            initializeAbstractGenerator(javaGenerator, warnings,
                    progressCallback);
            javaModelGenerators.add(javaGenerator);
        }

        if (getRules().generateRecordWithBLOBsClass()) {
            AbstractJavaGenerator javaGenerator = new RecordWithBLOBsGenerator();
            initializeAbstractGenerator(javaGenerator, warnings,
                    progressCallback);
            javaModelGenerators.add(javaGenerator);
        }
    }

    protected void initializeAbstractGenerator(
            AbstractGenerator abstractGenerator, List<String> warnings,
            ProgressCallback progressCallback) {
        if (abstractGenerator == null) {
            return;
        }
        
        abstractGenerator.setContext(context);
        abstractGenerator.setIntrospectedTable(this);
        abstractGenerator.setProgressCallback(progressCallback);
        abstractGenerator.setWarnings(warnings);
    }

    @Override
    public List<GeneratedJavaFile> getGeneratedJavaFiles() {
        List<GeneratedJavaFile> answer = new ArrayList<GeneratedJavaFile>();

        for (AbstractJavaGenerator javaGenerator : javaModelGenerators) {
            List<CompilationUnit> compilationUnits = javaGenerator
                    .getCompilationUnits();
            for (CompilationUnit compilationUnit : compilationUnits) {
                GeneratedJavaFile gjf = new GeneratedJavaFile(compilationUnit,
                        context.getJavaModelGeneratorConfiguration()
                                .getTargetProject(),
                                context.getProperty(PropertyRegistry.CONTEXT_JAVA_FILE_ENCODING),
                                context.getJavaFormatter());
                answer.add(gjf);
            }
        }

        for (AbstractJavaGenerator javaGenerator : clientGenerators) {
            List<CompilationUnit> compilationUnits = javaGenerator
                    .getCompilationUnits();
            for (CompilationUnit compilationUnit : compilationUnits) {
                GeneratedJavaFile gjf = new GeneratedJavaFile(compilationUnit,
                        context.getJavaClientGeneratorConfiguration()
                                .getTargetProject(),
                                context.getProperty(PropertyRegistry.CONTEXT_JAVA_FILE_ENCODING),
                                context.getJavaFormatter());
                answer.add(gjf);
            }
        }

        return answer;
    }

    @Override
    public List<GeneratedXmlFile> getGeneratedXmlFiles() {
        List<GeneratedXmlFile> answer = new ArrayList<GeneratedXmlFile>();

        if (xmlMapperGenerator != null) {
            Document document = xmlMapperGenerator.getDocument();
			/**
			 * 原来中的 GeneratedXmlFile 保留;将其中构造函数中的true 修改为 : false; 设置
			 * isMergeable = false; 在生成 xml文件的时候,将不是合并,而是直接覆盖;
			 */
            
//            GeneratedXmlFile gxf = new GeneratedXmlFile(document,
//                getMyBatis3XmlMapperFileName(), getMyBatis3XmlMapperPackage(),
//                context.getSqlMapGeneratorConfiguration().getTargetProject(),
//                true, context.getXmlFormatter());
			String tmp = context.getProperty("mergeable");
			boolean mergeable = false;
			if ("true".equalsIgnoreCase(tmp)) {
				mergeable = true;
			}
			GeneratedXmlFile gxf = new GeneratedXmlFile(document,
					getMyBatis3XmlMapperFileName(),
					getMyBatis3XmlMapperPackage(), context
							.getSqlMapGeneratorConfiguration()
							.getTargetProject(), mergeable,
					context.getXmlFormatter());
            if (context.getPlugins().sqlMapGenerated(gxf, this)) {
                answer.add(gxf);
            }
        }

        return answer;
    }

    @Override
    public int getGenerationSteps() {
        return javaModelGenerators.size() + clientGenerators.size() +
            (xmlMapperGenerator == null ? 0 : 1);
    }

    @Override
    public boolean isJava5Targeted() {
        return true;
    }

    @Override
    public boolean requiresXMLGenerator() {
        AbstractJavaClientGenerator javaClientGenerator =
            createJavaClientGenerator();
        
        if (javaClientGenerator == null) {
            return false;
        } else {
            return javaClientGenerator.requiresXMLGenerator();
        }
    }
}
【spring mvc】mybatis-generator spring mvc
<!--
MyBatis Generator中文文档:http://blog.csdn.net/isea533/article/details/42102297
使用Mybatis的Generator可能导致的一个错误: http://www.tuicool.com/articles/MN7bAbF
mybatis-generator重新生成代码时的SQL映射文件覆盖: http://my.oschina.net/u/140938/blog/220006
-->

<!--
maven 依赖
<dependency>
	<groupId>org.mybatis.generator</groupId>
	<artifactId>mybatis-generator-core</artifactId>
	<version>1.3.2</version>
	<scope>test</scope>
</dependency>
-->

<!-- XML示例 -->
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration> 
	<properties resource="system-config/dev.properties"/>
<!-- 配置mysql 驱动jar包路径.用了绝对路径 -->
<!-- 	<classPathEntry -->
<!-- 	<classPathEntry  location="D:\Maven2\repository\net\sourceforge\jtds\jtds\1.3.0\jtds-1.3.0.jar"/> -->
<!-- 	<classPathEntry  location="D:\maven\repository\com\microsoft\sqlserver\sqljdbc4\4.2.0\sqljdbc4-4.2.0.jar"/>  -->
	<!-- 为了防止生成的代码中有很多注释,比较难看,加入下面的配置控制 -->
	<context id="lis_tables" targetRuntime="MyBatis3" defaultModelType="flat">
		<property name="mergeable" value="false"/> 
		<property name="schema" value="lis_dev"/>
		<property name="sqldate" value="true"/>
		<commentGenerator>
			<!-- 去除自动生成的注释 -->
			<property name="suppressAllComments" value="true" />
			<!-- 阻止生成的注释包含时间戳 -->
			<property name="suppressDate" value="true" />
		</commentGenerator> 
		<!-- 注释控制完毕 --> 
		<!-- 数据库连接 -->
		<jdbcConnection driverClass="${lis.jdbc.driverClassName}"
			connectionURL="${lis.jdbc.url}"
			userId="${lis.jdbc.username}" password="${lis.jdbc.password}">
		</jdbcConnection>
<!-- 		<jdbcConnection driverClass="com.mysql.jdbc.Driver" -->
<!-- 			connectionURL="jdbc:mysql://localhost:3306/cignacmb" -->
<!-- 			userId="root" password="root"> -->
<!-- 		</jdbcConnection> -->
		<!-- com.microsoft.sqlserver.jdbc.SQLServerDriver -->
<!-- 		<jdbcConnection driverClass="net.sourceforge.jtds.jdbc.Driver" -->
<!-- 			connectionURL="jdbc:jtds:sqlserver://SD-20120429CJGQ;DatabaseName=cignacmb" -->
<!-- 			userId="lg_dev" password="lg_dev"> -->
<!-- 		</jdbcConnection> -->
<!-- 		<jdbcConnection driverClass="oracle.jdbc.driver.OracleDriver" -->
<!-- 			connectionURL="jdbc:oracle:thin:@10.141.141.131:1521:gis" -->
<!-- 			userId="lis_dev" password="lis_dev"> -->
<!-- 		</jdbcConnection> -->
		<javaTypeResolver>
			<property name="forceBigDecimals" value="false" />
		</javaTypeResolver> 
		
		<!-- 数据表对应的model 层 -->
		<javaModelGenerator targetPackage="com.cignacmb.productdef.lis.model.pub"
			targetProject="src/main/java">
<!-- 			<property name="constructorBased" value="true" /> -->
			<property name="enableSubPackages" value="false" />
			<property name="trimStrings" value="true" />
		</javaModelGenerator> 
		
		<!-- sql mapper 映射配置文件 -->
		<sqlMapGenerator targetPackage="com.cignacmb.productdef.lis.mapper.pub"
			targetProject="src/main/resources">
			<property name="enableSubPackages" value="false" />
		</sqlMapGenerator> 
		
		<!-- 在ibatis2 中是dao层,但在mybatis3中,其实就是mapper接口 -->
		<javaClientGenerator type="XMLMAPPER"
			targetPackage="com.cignacmb.productdef.lis.mapper.pub" 
			targetProject="src/main/java">
		</javaClientGenerator> 
		
		<!-- 要对那些数据表进行生成操作,必须要有一个. -->
		<table tableName="pd_lmrisk" domainObjectName="PDLMRiskModel" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>
		<table tableName="pd_lmriskapp" domainObjectName="PDLMRiskAppModel" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>
		<table tableName="pd_lmriskpay" domainObjectName="PDLMRiskPayModel" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>
		<table tableName="pd_lmriskrela" domainObjectName="PDLMRiskRelaModel" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>

		<table tableName="pd_lmriskduty" domainObjectName="PDLMRiskDutyModel" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>
		<table tableName="pd_lmduty" domainObjectName="PDLMDutyModel" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>
		<table tableName="pd_lmdutypay" domainObjectName="PDLMDutyPayModel" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>
		<table tableName="pd_lmdutyget" domainObjectName="PDLMDutyGetModel" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>

		<table tableName="ldmaxno" domainObjectName="LDMaxNoModel" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>
		<table tableName="pd_basefield" domainObjectName="PDBaseFieldModel" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"/>

	</context>
</generatorConfiguration>

<!-- java调用 -->
	public static void main(String[] args) {
		Logger logger = Logger.getLogger(GenMain.class);
		long startTime = System.currentTimeMillis();
		
		logger.info("start ...");
		List<String> warnings = new ArrayList<String>();
		boolean overwrite = true;
		String genCfg = "/mbgConfiguration.xml";
		File configFile = new File(GenMain.class.getResource(genCfg).getFile());
		ConfigurationParser cp = new ConfigurationParser(warnings);
		DefaultShellCallback callback = new DefaultShellCallback(overwrite);
		try {
			Configuration config = cp.parseConfiguration(configFile);
			MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
					callback, warnings);
			myBatisGenerator.generate(null);
		} catch (InvalidConfigurationException e) {
			logger.error(e.getMessage(), e);
		} catch (SQLException e) {
			logger.error(e.getMessage(), e);
		} catch (IOException e) {
			logger.error(e.getMessage(), e);
		} catch (InterruptedException e) {
			logger.error(e.getMessage(), e);
		} catch (XMLParserException e) {
			logger.error(e.getMessage(), e);
		}
		logger.info("end ... >> " + (System.currentTimeMillis() - startTime));
	}
【spring mvc】乱码问题 spring mvc
<!-- web.xml 可解决post乱码问题 -->
	<!-- 编码格式 -->
	<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>
         <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>

<!-- jsp-config 用来说明包含的页面默认按照什么编码格式包含。web-app 标签的version必须是2.4的 -->
	<jsp-config>
		<jsp-property-group>
			<url-pattern>*.jsp</url-pattern>
			<el-ignored>true</el-ignored>
			<page-encoding>UTF-8</page-encoding>
			<scripting-invalid>false</scripting-invalid>
			<include-prelude></include-prelude>
			<include-coda></include-coda>
		</jsp-property-group>
	</jsp-config>

<!-- 如果get方式乱码,一般是将tomcat中conf目录下server.xml文件中加入: -->
<Connector port="8080" maxHttpHeaderSize="8192"
	maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
	enableLookups="false" redirectPort="8443" acceptCount="100"
	connectionTimeout="20000" disableUploadTimeout="true" URIEncoding="UTF-8" />
【spring mvc】多数据源配置2 spring mvc
<!-- self-dataSource.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:p="http://www.springframework.org/schema/p"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:util="http://www.springframework.org/schema/util"
	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/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd 
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd 
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd"
	default-autowire="byName">
	
	<!-- 配置数据源 -->
	<bean id="self_dataSource" class="org.apache.commons.dbcp.BasicDataSource"  
        destroy-method="close">  
        <property name="driverClassName" value="${self.jdbc.driverClassName}" />  
        <property name="url" value="${self.jdbc.url}" />  
        <property name="username" value="${self.jdbc.username}" />  
        <property name="password" value="${self.jdbc.password}" />  
        <property name="maxActive" value="100" />  
        <property name="maxWait" value="1000" />  
        <property name="poolPreparedStatements" value="false" />  
        <property name="defaultAutoCommit" value="false" />  
    </bean>  

	<!--把mybatis SqlSessionFactory的创建交由spring管理 -->
	<bean id="self_sqlSessionFactoryBeanName" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="self_dataSource" />
<!-- 		<property name="typeAliasesPackage" value="com.cignacmb.selfhelp.dao.self" /> -->
		<property name="configLocation" value="classpath:mybatis-config.xml" />
		<property name="mapperLocations">
			<list>
				<value>classpath:com/cignacmb/selfhelp/self/mapper/*.xml</value>
			</list>
		</property>
	</bean>

	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="sqlSessionFactoryBeanName" value="self_sqlSessionFactoryBeanName"/>
		<property name="basePackage" value="com.cignacmb.selfhelp.self.mapper" />
	</bean>

	<!-- Local Transaction Management (txManager) -->
	<bean id="selfTransactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="self_dataSource" />
		<qualifier value="selfTransaction" />
	</bean>

	<!--启动spring注解功能 -->
	<tx:annotation-driven transaction-manager="selfTransactionManager" />
</beans>

<!------------------------------------------------------------------------------------->

<!-- lis-dataSource.xml -->
	<!-- 配置数据源 -->
	<bean id="lis_dataSource" class="org.apache.commons.dbcp.BasicDataSource"  
        destroy-method="close">  
        <property name="driverClassName" value="${lis.jdbc.driverClassName}" />  
        <property name="url" value="${lis.jdbc.url}" />  
        <property name="username" value="${lis.jdbc.username}" />  
        <property name="password" value="${lis.jdbc.password}" />  
        <property name="maxActive" value="100" />  
        <property name="maxWait" value="1000" />  
        <property name="poolPreparedStatements" value="false" />  
        <property name="defaultAutoCommit" value="false" />  
    </bean>  
	<bean id="lis_sqlSessionFactoryBeanName" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="lis_dataSource" />
		<property name="configLocation" value="classpath:mybatis-config.xml" />
		<property name="mapperLocations">
			<list>
				<value>classpath:com/cignacmb/selfhelp/lis/mapper/*.xml</value>
			</list>
		</property>
	</bean>
	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="sqlSessionFactoryBeanName" value="lis_sqlSessionFactoryBeanName"/>
		<property name="basePackage" value="com.cignacmb.selfhelp.lis.mapper" />
	</bean>
	<bean id="lisTransactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="lis_dataSource" />
		<qualifier value="lisTransaction" />
	</bean>
	<tx:annotation-driven transaction-manager="lisTransactionManager" />

<!------------------------------------------------------------------------------------->

<!-- applicationContext.xml -->
	<context:property-placeholder location="classpath:system-config/dev.properties" ignore-unresolvable="true" />

	<!-- 自动扫描Bean -->
	<context:component-scan base-package="com.cignacmb.selfhelp" >
		<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
	</context:component-scan>
	
	<!-- enable autowire -->  
<!--     <context:annotation-config /> -->
    
	<!-- 强制使用CGLIB代理 -->
	<aop:aspectj-autoproxy proxy-target-class="true" />

	<import resource="datasource/self-dataSource.xml"/>
	<import resource="datasource/lis-dataSource.xml"/>
【spring mvc】ObjectMapper之类型转换 spring mvc SpringMVC+MyBatis - 12 spring mvc4返回的json日期为Long的解决方案
import java.io.IOException;
import java.util.Date;

import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializerProvider;
import org.codehaus.jackson.map.ser.CustomSerializerFactory;
import org.springframework.stereotype.Service;

@Service
public class CustomObjectMapper extends ObjectMapper {
	public CustomObjectMapper() {
		CustomSerializerFactory factory = new CustomSerializerFactory();
		factory.addGenericMapping(Date.class, new JsonSerializer<Date>() {
			@Override
			public void serialize(Date value, JsonGenerator jsonGenerator,
					SerializerProvider provider) throws IOException,
					JsonProcessingException {
//				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//				jsonGenerator.writeString(sdf.format(value));
				
				if(null != value){
					jsonGenerator.writeString(String.valueOf(value.getTime()));
				}
			}
		});
		this.setSerializerFactory(factory);
	}
}


xml 配置
    <bean id="mappingJacksonHttpMessageConverter"  
        class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">  
        <property name="objectMapper" ref="customObjectMapper"/>  
        <property name="supportedMediaTypes">  
            <list>  
                <value>text/html;charset=UTF-8</value>  
            </list>  
        </property>  
    </bean>
【spring mvc】多数据源配置 spring mvc Spring+Mybatis 多数据源配置
【注意项】
1. spring-test 3 是根据autowired自动注入;与junit 4.8.1结合使用;
2. @Resource、@Autowired、@Qualifier的注解注入及区别
   @Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入;
   @Autowired默认是按照类型装配注入的,如果想按照名称来转配注入,则需要结合@Qualifier一起使用;
   @Resource注解是又J2EE提供,而@Autowired是由Spring提供,故减少系统对spring的依赖建议使用@Resource的方式;
   @Resource和@Autowired都可以书写标注在字段或者该字段的setter方法之上
3. spring-test 2.5.6 是通过set方法注入,而不是注解,可解决多数据库的问题;
   spring-test 2.5.6 与 junit 3.8.1结合使用;即:
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>2.5.6</version>
		</dependency>



---------------------------------------------------------------------------------------

1、注解式事务声明
@Transactional(value = "insurance", rollbackFor = Exception.class)
@Transactional(value = "isap", rollbackFor = Exception.class)

<bean id="transactionManager2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
    <property name="dataSource" ref="dataSource2" />  
    <qualifier value="insurance" />  
</bean> 
【spring mvc】CrossDomainView spring mvc
/**
 * 
 */

import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.servlet.view.AbstractView;

import com.google.gson.Gson;

/**
 * 跨域请求视图
 * @author c1panx
 * 2015-01-11  下午2:16:40
 */
public class CrossDomainView extends AbstractView {
	
	public static final String DEFAULT_CONTENT_TYPE = "text/plain;charset=UTF-8";
	public static final String DEFAULT_CHAR_ENCODING = "UTF-8";
	
	private String encodeing = DEFAULT_CHAR_ENCODING;

	private Object jsonData = null;
	private Map<String, Object> _jsonDataMap = new HashMap<String, Object>();

	private Set<String> renderedAttributes;

	public CrossDomainView() {
		setContentType(DEFAULT_CONTENT_TYPE);
	}

	public CrossDomainView(Object data) {
		setContentType(DEFAULT_CONTENT_TYPE);
		this.jsonData = data;
	}

	public void setEncodeing(String encodeing) {
		this.encodeing = encodeing;
	}

	@Override
	protected void renderMergedOutputModel(Map<String, Object> model,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		// 回调函数名
		String jsoncallback = request.getParameter("jsoncallback");
		
		String result = "";
		if (jsonData != null) {
			result = new Gson().toJson(jsonData);
		} else if (!_jsonDataMap.isEmpty()) {
			result = new Gson().toJson(_jsonDataMap);
		} else {
			model = filterModel(model);
			result = new Gson().toJson(model);
		}
		
		// 若未传递jsoncallback参数,则返回普通的JSON串
		if (StringUtils.isBlank(jsoncallback) == false) {
			result = jsoncallback + "(" + result + ")";
		}
		logger.info("CrossDomainView jsoncallback:" + jsoncallback);
		logger.info("CrossDomainView result:" + result);

		response.setCharacterEncoding(encodeing);
		response.setContentType(getContentType());
		PrintWriter out = null;
		try {
			out = response.getWriter();
			out.print(result);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		} finally {
			if (null != out) {
				out.flush();
				out.close();
			}
		}
	}

	/**
	 * Filters out undesired attributes from the given model.
	 * <p>
	 * Default implementation removes {@link BindingResult} instances and
	 * entries not included in the {@link #setRenderedAttributes(Set)
	 * renderedAttributes} property.
	 */
	protected Map<String, Object> filterModel(Map<String, Object> model) {
		Map<String, Object> result = new HashMap<String, Object>(model.size());
		Set<String> renderedAttributes = !CollectionUtils.isEmpty(this.renderedAttributes) ? this.renderedAttributes
				: model.keySet();
		for (Map.Entry<String, Object> entry : model.entrySet()) {
			if (!(entry.getValue() instanceof BindingResult)
					&& renderedAttributes.contains(entry.getKey())) {
				result.put(entry.getKey(), entry.getValue());
			}
		}

		return result;

	}

	public void setJsonData(Object jsonData) {
		this.jsonData = jsonData;
	}

	public static CrossDomainView returnJson(Object jsonData) {
		CrossDomainView jsonView = new CrossDomainView();
		jsonView.setJsonData(jsonData);
		return jsonView;
	}

	public CrossDomainView put(String key, Object value) {
		_jsonDataMap.put(key, value);
		return this;
	}
}




//跨域请求示例
$.ajax({
	url:t_json.url + "?jsoncallback=?",
	data: {mobile:t_json.$mobile.val(), type:t_json.type},
	dataType: "jsonp",
//	type: "POST",
	crossDomain: true,
	beforeSend: function(XMLHttpRequest){},
	success: function(data, textStatus){
		
	},
	error: function(XMLHttpRequest, textStatus, errorThrown){
		
	}
});
【spring mvc】kaptcha.ValidateCodeController spring mvc
/**
 * 
 */
package com.cignacmb.member.center.controller;

import java.awt.image.BufferedImage;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.google.code.kaptcha.Producer;

/**
 * 图片动态码
 * @author c1panx
 *  2015年2月5日 下午4:57:01
 */
@Controller
public class ValidateCodeController {
	
	private final Logger logger = Logger.getLogger(this.getClass());

	@Autowired
	private Producer captchaProducer = null;
	
	@RequestMapping("/validate-code.xhtml")
	public ModelAndView handleRequest(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		response.setDateHeader("Expires", 0);
		// Set standard HTTP/1.1 no-cache headers.
		response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
		// Set IE extended HTTP/1.1 no-cache headers (use addHeader).
		response.addHeader("Cache-Control", "post-check=0, pre-check=0");
		// Set standard HTTP/1.0 no-cache header.
		response.setHeader("Pragma", "no-cache");
		// return a jpeg
		response.setContentType("image/jpeg");
		// create the text for the image
		String capText = captchaProducer.createText();
		// store the text in the session
		request.getSession().setAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY,
				capText);
		// create the image with the text
		BufferedImage bi = captchaProducer.createImage(capText);
		
		ServletOutputStream out = null;
		try {
			out = response.getOutputStream();
			// write the data out
			ImageIO.write(bi, "jpg", out);
			out.flush();
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
		} finally {
			if (null != out) {
				out.close();
			}
		}
		return null;
	}
}
【spring mvc】kaptcha.MemberWordRenderer spring mvc
/**
 * 
 */
package com.cignacmb.member.center.validatecode;

import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.font.GlyphVector;
import java.awt.image.BufferedImage;
import java.util.Random;

import com.google.code.kaptcha.text.WordRenderer;
import com.google.code.kaptcha.util.Configurable;

/**
 * <a href='http://fancyboy2050.iteye.com/blog/1146763'>Kaptcha使用</a>
 * @author c1panx
 *  2015年2月6日 上午9:45:25
 */
public class MemberWordRenderer extends Configurable implements WordRenderer {

	public MemberWordRenderer() {
	}  
	
	@Override
	public BufferedImage renderWord(String word, int width, int height) {
		int fontSize = getConfig().getTextProducerFontSize();
		// 这个地方我们自定义了验证码文本字符样式,虽然是可以配置的,但是字体展示都粗体,我们希望不是粗体就只有自定义这个渲染类了
		String paramName = "kaptcha.textproducer.font.names";
		String paramValue = (String) getConfig().getProperties().get(paramName);
		String fontNames[] = paramValue.split(",");
		Font fonts[] = new Font[fontNames.length];
		for (int i = 0; i < fontNames.length; i++) {
//			fonts[i] = new Font(fontNames[i], Font.ITALIC, fontSize);
			fonts[i] = new Font(fontNames[i], Font.BOLD + Font.ITALIC, fontSize);
		}

		java.awt.Color color = getConfig().getTextProducerFontColor();
		int charSpace = getConfig().getTextProducerCharSpace();
		BufferedImage image = new BufferedImage(width, height, 2);
		Graphics2D g2D = image.createGraphics();

		g2D.setColor(color);
		RenderingHints hints = new RenderingHints(
				RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);
		hints.add(new RenderingHints(RenderingHints.KEY_RENDERING,
				RenderingHints.VALUE_RENDER_QUALITY));

		g2D.setRenderingHints(hints);
		java.awt.font.FontRenderContext frc = g2D.getFontRenderContext();
		Random random = new Random();
		int startPosY = (height - fontSize) / 5 + fontSize;
		char wordChars[] = word.toCharArray();
		Font chosenFonts[] = new Font[wordChars.length];
		int charWidths[] = new int[wordChars.length];
		int widthNeeded = 0;
		for (int i = 0; i < wordChars.length; i++) {
			chosenFonts[i] = fonts[random.nextInt(fonts.length)];
			char charToDraw[] = { wordChars[i] };
			GlyphVector gv = chosenFonts[i].createGlyphVector(frc, charToDraw);
			charWidths[i] = (int) gv.getVisualBounds().getWidth();
			if (i > 0)
				widthNeeded += 2;
			widthNeeded += charWidths[i];
		}

		int startPosX = (width - widthNeeded) / 2;
		for (int i = 0; i < wordChars.length; i++) {
			g2D.setFont(chosenFonts[i]);
			char charToDraw[] = { wordChars[i] };
			g2D.drawChars(charToDraw, 0, charToDraw.length, startPosX,
					startPosY);
			startPosX = startPosX + charWidths[i] + charSpace;
		}

		return image;
	}

}
【spring mvc】kaptcha.MemberWaterRipple spring mvc
/**
 * 
 */
package com.cignacmb.member.center.validatecode;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

import com.google.code.kaptcha.NoiseProducer;
import com.google.code.kaptcha.impl.WaterRipple;
import com.jhlabs.image.RippleFilter;
import com.jhlabs.image.TransformFilter;
import com.jhlabs.image.WaterFilter;

/**
 * @author c1panx
 *  2015年2月9日 下午3:11:07
 */
public class MemberWaterRipple extends WaterRipple {

	public BufferedImage getDistortedImage(BufferedImage baseImage) {
		// baseImage,无噪点文字图片
		
		NoiseProducer noiseProducer = getConfig().getNoiseImpl();
		BufferedImage distortedImage = new BufferedImage(baseImage.getWidth(),
				baseImage.getHeight(), BufferedImage.TYPE_INT_ARGB);

		Graphics2D graphics = (Graphics2D) distortedImage.getGraphics();

		// http://javadox.com/com.jhlabs/filters/2.0.235-1/com/jhlabs/image/RippleFilter.html
		RippleFilter rippleFilter = new RippleFilter();
		// RippleFilter.SINE 正弦波的涟漪
		rippleFilter.setWaveType(RippleFilter.SINE);
		// 在 X 方向设置的波动幅度。
		rippleFilter.setXAmplitude(2.6f);
		rippleFilter.setYAmplitude(1.7f);
		// 在 X 方向设置波长的波纹。
		rippleFilter.setXWavelength(15);
		rippleFilter.setYWavelength(5);
		rippleFilter.setEdgeAction(TransformFilter.NEAREST_NEIGHBOUR);

		// http://www.2cto.com/kf/201302/188441.html
		WaterFilter waterFilter = new WaterFilter();
		waterFilter.setAmplitude(0.5f);	// 振幅
		waterFilter.setPhase(10);	// 相位
		waterFilter.setWavelength(2);	// 波长

		// baseImage,无噪点文字图片
		BufferedImage effectImage = baseImage;
		// waterFilter.filter 文字上添加噪点
//		BufferedImage effectImage = waterFilter.filter(baseImage, null);
		effectImage = rippleFilter.filter(effectImage, null);

		graphics.drawImage(effectImage, 0, 0, null, null);

		graphics.dispose();

		// 干扰线
		noiseProducer.makeNoise(distortedImage, .1f, .1f, .25f, .25f);
		noiseProducer.makeNoise(distortedImage, .1f, .25f, .5f, .9f);
		return distortedImage;
	}
}
【spring mvc】kaptcha.MemberNoise spring mvc
/**
 * 
 */
package com.cignacmb.member.center.validatecode;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.CubicCurve2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.util.Random;

import com.google.code.kaptcha.impl.DefaultNoise;


/**
 * @author c1panx
 *  2015年2月5日 下午5:26:55
 */
public class MemberNoise extends DefaultNoise {

	public void makeNoise(BufferedImage image, float factorOne,
			float factorTwo, float factorThree, float factorFour) {
		Color color = getConfig().getNoiseColor();

		// image size
		int width = image.getWidth();
		int height = image.getHeight();

		// the points where the line changes the stroke and direction
		Point2D[] pts = null;
		Random rand = new Random();

		// the curve from where the points are taken
		CubicCurve2D cc = new CubicCurve2D.Float(width * factorOne, height
				* rand.nextFloat(), width * factorTwo, height
				* rand.nextFloat(), width * factorThree, height
				* rand.nextFloat(), width * factorFour, height
				* rand.nextFloat());

		// creates an iterator to define the boundary of the flattened curve
		PathIterator pi = cc.getPathIterator(null, 2);
		Point2D tmp[] = new Point2D[200];
		int i = 0;

		// while pi is iterating the curve, adds points to tmp array
		while (!pi.isDone()) {
			float[] coords = new float[6];
			switch (pi.currentSegment(coords)) {
			case PathIterator.SEG_MOVETO:
			case PathIterator.SEG_LINETO:
				tmp[i] = new Point2D.Float(coords[0], coords[1]);
			}
			i++;
			pi.next();
		}

		pts = new Point2D[i];
		System.arraycopy(tmp, 0, pts, 0, i);

		Graphics2D graph = (Graphics2D) image.getGraphics();
		graph.setRenderingHints(new RenderingHints(
				RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON));

		graph.setColor(color);

		// for the maximum 3 point change the stroke and direction
		for (i = 0; i < pts.length - 1; i++) {
			if (i < 3)
				graph.setStroke(new BasicStroke(0.9f * (4 - i)));
			graph.drawLine((int) pts[i].getX(), (int) pts[i].getY(),
					(int) pts[i + 1].getX(), (int) pts[i + 1].getY());
		}

		graph.dispose();
	}
	
}
【spring mvc】LoginInterceptor spring mvc
/**
 * 登录态校验的拦截器
 * @author c1panx
 * @date 2014-10-22 下午4:42:56
 */
@Component
public class LoginInterceptor extends HandlerInterceptorAdapter {

	private static final Logger logger = Logger.getLogger(LoginInterceptor.class);

	@Value("${member.center.base.url}")
	private String baseURL;
	
	private String loginURL;
	
	@Autowired
	private InterceptService interceptService;
	@Autowired
	private CookieService cookieService;
	
	private String[] filterURLArray = null;
	
	@PostConstruct
	public void init(){
		loginURL = baseURL + "login.xhtml";
		// 配置的页面,不需进行拦截
		filterURLArray = new String[]{
				"/login.xhtml",	// 登录页及登录接口
				"/login/flow.xhtml",	// 弹出层登录
				"/checkUser.xhtml",	// 判断用户名是否被注册过
				"/sendsms.xhtml",	// 短信发送
				
				"/register.xhtml",	// 注册页及注册接口
				"/register/flow.xhtml",	// 弹出层注册
				"/register.json",	// ajax退出
				"/register/toactivate.xhtml", // 邮箱注册成功后的提示页,可重发激活邮件
				"/register/resend.xhtml",	// 重新发送邮件
				"/register/activate.xhtml",	// 邮件激活地址
				
				"/authenticate.xhtml",	// 认证接口
				
				"/retrieve/pwd.xhtml",	// 密码找回
				"/retrieve/bymobile.xhtml",	
				"/retrieve/byemail.xhtml",	
				"/retrieve/byemailpwd.xhtml",//密码邮件找回发送邮件
				"/retrieve/toactivate.xhtml",//密码找回邮件激活地址,发送后跳转的提示页
				"/retrieve/password.xhtml",	// 邮件中密码重置连接
				
				//"/validateCode.xhtml",	// 图片验证码
				"/validate-code.xhtml",	// 图片验证码
				"/live800/trust.xhtml",	// live800用户基本信息
				"/login.json",	// ajax退出
				"/logout.json",	// ajax退出
		};
	}
	
	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		
		this.displayClientInfo(request);
		
		interceptService.intercept(request);
		
		String path = request.getServletPath();
		if (this.filterPages(path)) {
			logger.info("不需被拦截:" + path);
			return true;
		}

		HttpSession session = request.getSession();
		Long sessionUserID = Tools.getUserId(session);
		Long cookieUserID = this.getUserIDInCookie(request);
		
		if(null == sessionUserID){
			// session中无用户信息,则校验cookie内容
			if (cookieService.checkToken(request)) {
				session.setAttribute(Constants.Session_User_ID, cookieUserID);
				return true;
			}
			response.sendRedirect(loginURL);
		} else {
			// session中有用户信息,cookie中无用户信息
			if(null == cookieUserID){
				response.sendRedirect(loginURL);
			}
			// 判断用户ID是否一致,一致不做处理
			if (sessionUserID.longValue() == cookieUserID.longValue()) {
				return true;
			}else{
				// 不一致时,判断cookie有效性
				if (cookieService.checkToken(request) == false) {
					// cookie有效,但用户ID不一致,跳转至登录页
					response.sendRedirect(loginURL);
				}
				// cookie有效,重新覆盖session中userID
				session.setAttribute(Constants.Session_User_ID, cookieUserID);
			}
		}
		return true;
	}
	
	/**
	 * 显示客户端请求信息,必要时可入库分析<br>
	 * @param request
	 */
	private void displayClientInfo(HttpServletRequest request){
		logger.info("----------------------------------------------------");
		logger.info("display request info: ");
		
		// 获得用户请求的URI
		logger.info("RequestURI: " + request.getRequestURI());
		logger.info("RequestURL: " + request.getRequestURL());
		logger.info("ContextPath: " + request.getContextPath());
		logger.info("ServletPath: " + request.getServletPath());
		logger.info("AuthType: " + request.getAuthType());
		logger.info("LocalAddr: " + request.getLocalAddr());
		logger.info("LocalName: " + request.getLocalName());
		logger.info("Method: " + request.getMethod());
		logger.info("PathInfo: " + request.getPathInfo());
		logger.info("PathTranslated: " + request.getPathTranslated());

		logger.info("basepath: " + Tools.getContextPath(request));
		
		// TODO
		String ip = IPUtil.getRequestIP(request);
		logger.info("clinet IP: " + ip);
		logger.info("----------------------------------------------------");
	}
	
	/**
	 * 过滤不需拦截的页面<br>
	 * 静态资源不存在拦截问题
	 * @param currentURL
	 * @return
	 * true: 页面被过滤掉 <br>
	 * false: 页面需验证有效性
	 */
	private boolean filterPages(String currentURL) {
		logger.info("被截取的地址:" + currentURL);
		if (StringUtils.isBlank(currentURL)) {
			return true;
		}
		if (null == filterURLArray) {
			return true;
		}
		for (String url : filterURLArray) {
			if (currentURL.equals(url)) {
				return true;
			}
		}
		return false;
	}
	
	/**
	 * cookie中的用户ID
	 * @param request
	 * @return
	 */
	private Long getUserIDInCookie(HttpServletRequest request) {
		Map<String, Cookie> cookieMap = cookieService.getCookieMap(request);
		String uid = cookieService.getCookieValue(Constants.COOKIE_UID, cookieMap);
		
		if (StringUtils.isBlank(uid)) {
			return null;
		}
		try {
			return Long.valueOf(uid);
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			return null;
		}
	}
	
}
【spring mvc】log4j.xml spring mvc
<?xml version="1.0" encoding="UTF-8"?>  <!-- Log4J Configuration for online -->
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
	<!-- Appenders -->
	<appender name="console" class="org.apache.log4j.ConsoleAppender">
		<param name="Target" value="System.out" />
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="[%X{LocalHost}][%p] %-d{yyyy-MM-dd HH\:mm\:ss.sss} [%t] [%c.%M\:%L]  %m%n " />
		</layout>
	</appender>
	<!-- Appenders -->
	<appender name="appAppender" class="org.apache.log4j.DailyRollingFileAppender">
		<param name="File" value="/mnt/ntfs/member/center.log" />
		<param name="Encoding" value="UTF-8" />
		<param name="Append" value="true" />
		<param name="DatePattern" value="'.'yyyy-MM-dd" />
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="[%X{LocalHost}][%p] %-d{yyyy-MM-dd HH\:mm\:ss.sss} [%t] [%c.%M\:%L]  %m%n " />
		</layout>
	</appender>

	<appender name="errorAppender" class="org.apache.log4j.DailyRollingFileAppender">
		<param name="File" value="/mnt/ntfs/member/center.error.log" />
		<param name="Encoding" value="UTF-8" />
		<param name="Append" value="true" />
		<param name="DatePattern" value="'.'yyyy-MM-dd" />
		<layout class="org.apache.log4j.PatternLayout">
			<param name="ConversionPattern" value="[%X{LocalHost}][%p] %-d{yyyy-MM-dd HH\:mm\:ss.sss} [%t] [%c.%M\:%L]  %m%n " />
		</layout>
		<filter class="org.apache.log4j.varia.LevelRangeFilter">
			<param name="LevelMax" value="ERROR" />
			<param name="LevelMin" value="ERROR" />
		</filter>
	</appender>

	<!-- Spring Loggers -->
	<logger name="org.springframework">
		<level value="WARN" />
	</logger>

	<logger name="org.springframework.web">
		<level value="WARN" />
	</logger>

	<!-- Root Logger -->
	<root>
		<priority value="INFO" />
<!-- 		<priority value="DEBUG" /> -->
		<appender-ref ref="console" />
		<appender-ref ref="appAppender" />
		<appender-ref ref="errorAppender" />
	</root>

</log4j:configuration>
【spring mvc】tld spring mvc
JSP页头:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ page isELIgnored="false" %>
【spring mvc】web.xml spring mvc
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	version="2.4"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

 	<context-param>
		<param-name>webAppRootKey</param-name>
		<param-value>member.center.root </param-value>
	</context-param>
	
	<context-param>
      <param-name>log4jConfigLocation</param-name>
      <param-value>classpath:log4j.xml</param-value>
    </context-param>
    
	<!-- Spring的配置文件 -->
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath:applicationContext.xml</param-value>
	</context-param>
	
	<!-- 日志配置文件 -->
    <listener>
      <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>
	<!-- 容器监听器 -->
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	
	<!-- Spring默认的Servlet -->
	<servlet>  
    	<servlet-name>dispatcherservlet</servlet-name>  
    	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    	<init-param>  
        	<param-name>contextConfigLocation</param-name>  
        	<param-value>classpath:applicationContext-mvc.xml</param-value>  
    	</init-param> 
    	<load-on-startup>1</load-on-startup>  
	</servlet>  
	
	<!-- Servlet映射 -->
	<servlet-mapping>  
    	<servlet-name>dispatcherservlet</servlet-name>  
    	<url-pattern>*.xhtml</url-pattern>  
	</servlet-mapping>
	<servlet-mapping>  
    	<servlet-name>dispatcherservlet</servlet-name>  
    	<url-pattern>*.json</url-pattern>  
	</servlet-mapping>  

	<!-- 编码格式 -->
	<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>
         <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>

<!--     <session-config> -->
<!--     	<session-timeout>30</session-timeout> -->
<!--     </session-config> -->
    
    <!-- 欢迎页 -->
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
		<welcome-file>login.xhtml</welcome-file>
		<welcome-file>index.xhtml</welcome-file>
	</welcome-file-list>

<!-- jsp-config 用来说明包含的页面默认按照什么编码格式包含。web-app 标签的version必须是2.4的 -->
	<jsp-config>
		<jsp-property-group>
			<description>Special property group for JSP Configuration JSP example.</description>
			<display-name>JSPConfiguration</display-name>
			<url-pattern>*.jsp</url-pattern>
			<el-ignored>true</el-ignored>
			<page-encoding>UTF-8</page-encoding>
			<scripting-invalid>false</scripting-invalid>
			<include-prelude></include-prelude>
			<include-coda></include-coda>

			<description>Special property group for JSP Configuration JSP example.</description>
			<display-name>JSPConfiguration</display-name>
			<url-pattern>*.html</url-pattern>
			<el-ignored>true</el-ignored>
			<page-encoding>UTF-8</page-encoding>
			<scripting-invalid>false</scripting-invalid>
			<include-prelude></include-prelude>
			<include-coda></include-coda>
		</jsp-property-group>
	</jsp-config>
</web-app>


或在引用的JSP文件头加入:
<%@ page language="java" contentType="text/html; charset=UTF-8"  pageEncoding="UTF-8"%>
【spring mvc】pom.xml spring mvc
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.cignacmb.member</groupId>
  <artifactId>center</artifactId>
  <packaging>war</packaging>
  <version>1.0.0</version>
  <name>service Maven Webapp</name>
  <url>http://maven.apache.org</url>
  
  <properties>
  	<spring.version>3.1.0.RELEASE</spring.version>
  </properties>
  
  <dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.8.1</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.14</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aspects</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>1.4</version>
		</dependency>
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.7.0</version>
		</dependency>
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis-spring</artifactId>
			<version>1.2.0</version>
		</dependency>
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.2.2</version>
		</dependency>

		<dependency>
		  <groupId>com.thoughtworks.xstream</groupId>
		  <artifactId>xstream</artifactId>
		  <version>1.4.3</version>
		</dependency>

		<!-- offer by mike -->
		<dependency>
			<groupId>commons-beanutils</groupId>
			<artifactId>commons-beanutils</artifactId>
			<version>1.7.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.commons</groupId>
			<artifactId>commons-lang3</artifactId>
			<version>3.3.2</version>
		</dependency>
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>2.4</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.4</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>1.6.8</version>
		</dependency>
		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib-nodep</artifactId>
			<version>2.1_3</version>
		</dependency>
		<dependency>
			<groupId>commons-pool</groupId>
			<artifactId>commons-pool</artifactId>
			<version>1.5.6</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
		<dependency>
			<groupId>taglibs</groupId>
			<artifactId>standard</artifactId>
			<version>1.1.2</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-simple</artifactId>
			<version>1.6.2</version>
		</dependency>
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>jackson-core-lgpl</artifactId>
			<version>1.8.1</version>
		</dependency>
		<dependency>
			<groupId>org.codehaus.jackson</groupId>
			<artifactId>jackson-mapper-lgpl</artifactId>
			<version>1.8.1</version>
		</dependency>
		<dependency>
			<groupId>javax.annotation</groupId>
			<artifactId>jsr250-api</artifactId>
			<version>1.0</version>
		</dependency>
		<dependency>
			<groupId>net.sf.json-lib</groupId>
			<artifactId>json-lib</artifactId>
			<version>2.4</version>
			<classifier>jdk15</classifier>
		</dependency>
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
			<version>1.1.1</version>
		</dependency>

		<dependency>
			<groupId>com.fasterxml.jackson.core</groupId>
			<artifactId>jackson-databind</artifactId>
			<version>2.4.0</version>
		</dependency>
		<dependency>
			<groupId>com.microsoft.sqlserver</groupId>
			<artifactId>sqljdbc4</artifactId>
			<version>4.2.0</version>
		</dependency>

		<dependency>
			<groupId>com.oracle</groupId>
			<artifactId>ojdbc6</artifactId>
			<version>11.2.0.3.0</version>
		</dependency>
		<!-- memcached client -->
		<dependency>
			<groupId>com.danga</groupId>
			<artifactId>java-memcached</artifactId>
			<version>2.6.6</version>
			<type>jar</type>
		</dependency>
		
		<dependency>
			<groupId>com.google.code.gson</groupId>
			<artifactId>gson</artifactId>
			<version>2.2.4</version>
		</dependency>
		<dependency>
			<groupId>org.apache.httpcomponents</groupId>
			<artifactId>httpclient</artifactId>
			<version>4.1.2</version>
		</dependency>
		
		<!-- 理赔  client-->
		<dependency>
		  <groupId>org.apache.axis</groupId>
		  <artifactId>axis</artifactId>
		  <version>1.4</version>
		</dependency>
		
		<dependency>
		  <groupId>wsdl4j</groupId>
		  <artifactId>wsdl4j</artifactId>
		  <version>1.6.3</version>
		</dependency>
		<dependency>
		    <groupId>javax.mail</groupId>
		    <artifactId>mail</artifactId>
		    <version>1.4</version>
		</dependency>
		<dependency>
		    <groupId>javax.xml</groupId>
		    <artifactId>jaxrpc</artifactId>
		    <version>1.0</version>
		</dependency>
		<dependency>
           <groupId>com.cignacmb</groupId>
           <artifactId>cigna-cmb-esb-client</artifactId>
           <version>1.0.3</version>
       </dependency>
		
		<dependency>
			<groupId>javax.mail</groupId>
			<artifactId>mail</artifactId>
			<version>1.4.1</version>
		</dependency>
		 <dependency>
			<groupId>org.freemarker</groupId>
			<artifactId>freemarker</artifactId>
			<version>2.3.16</version>
		 </dependency>

		 <dependency>
		 	<groupId>commons-codec</groupId>
		 	<artifactId>commons-codec</artifactId>
		 	<version>1.10</version>
		 </dependency>
		 <dependency>
		 	<groupId>com.google.code</groupId>
		 	<artifactId>kaptcha</artifactId>
		 	<version>2.3.2</version>
		 </dependency>
  </dependencies>
  
  <build>
    <finalName>member</finalName>
	<plugins>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-compiler-plugin</artifactId>
			<version>2.1</version>
			<configuration>
				<source>1.6</source>
				<target>1.6</target>
				<encoding>UTF-8</encoding>
			</configuration>
		</plugin>
		<plugin>
			<artifactId>maven-resources-plugin</artifactId>
			<version>2.4.1</version>
			<configuration>
				<encoding>UTF-8</encoding>
			</configuration>
		</plugin>
	</plugins>
  </build>
</project>
【spring mvc】applicationContext-test.xml spring mvc
// JUnitTest
/**
 * @author c1panx
 */
@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
@ContextConfiguration({"classpath:applicationContext-test.xml"})
public class AbstractJUnitTest extends AbstractTransactionalJUnit4SpringContextTests  {

}

// db-config.properties
// SQLServer
jdbc.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.url=jdbc:sqlserver://VMDBSQ01-TST\\PHDBSQLG01;DatabaseName=quote_cn
jdbc.username=LG
jdbc.password=abcde123.

// Oracle
jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@168.140.161.54:1522:ecoms
jdbc.username=test
jdbc.password=test

// sqlit
jdbc.driverClassName=org.sqlite.JDBC
jdbc.url=jdbc:sqlite:test.db3
jdbc.username=
jdbc.password=

// applicationContext-test.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:p="http://www.springframework.org/schema/p"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:util="http://www.springframework.org/schema/util"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd"
	default-autowire="byName">
	
	<context:property-placeholder location="classpath:system-config/dev.properties, classpath:db-config.properties" ignore-unresolvable="true" />

	<!-- <context:annotation-config /> -->
	<!-- 自动扫描Bean -->
	<context:component-scan base-package="com.cignacmb.member.service" >
		<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
	</context:component-scan>

	<!--启动spring注解功能 -->
	<tx:annotation-driven transaction-manager="transactionManager" />

	<bean id="member_dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="${jdbc.driverClassName}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		<property name="maxActive" value="100" />
		<property name="maxWait" value="1000" />
		<property name="poolPreparedStatements" value="false" />
		<property name="defaultAutoCommit" value="false" />
	</bean>

	<!--把mybatis SqlSessionFactory的创建交由spring管理 -->
	<bean id="sqlSessionFactoryBeanName" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="member_dataSource" />
		<property name="configLocation" value="classpath:mybatis-config.xml" />
	</bean>

	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage"
			value="com.cignacmb.member.service.dao" />
	</bean>

	<!-- Local Transaction Management (txManager) -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="member_dataSource" />
	</bean>
	
	<bean id="freeMarker" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">  
    	<property name="templateLoaderPath" value="classpath:template"/><!--指定模板文件目录-->   
	    <property name="freemarkerSettings"><!-- 设置FreeMarker环境属性-->   
	      <props>  
<!-- 	          <prop key="template_update_delay">1800</prop> -->
	          <prop key="default_encoding">UTF-8</prop>
	          <prop key="locale">zh_CN</prop>
	      </props>  
	    </property>  
   </bean>
</beans>
【spring mvc】mybatis-config.xml spring mvc
<?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>
		<!-- changes from the defaults -->
		<setting name="lazyLoadingEnabled" value="false" />
		<!-- JdbcType enumeration. Most common are: NULL, VARCHAR and OTHER -->
		<setting name="jdbcTypeForNull" value="NULL" />
		<setting name="logImpl" value="LOG4j" />
	</settings>
</configuration>
【spring mvc】applicationContext.xml spring mvc
<?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:p="http://www.springframework.org/schema/p"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:util="http://www.springframework.org/schema/util"
	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/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd 
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd 
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd"
	default-autowire="byName">
	
	<context:property-placeholder location="classpath:system-config/${config_env}.properties" ignore-unresolvable="true" />

	<!-- 自动扫描Bean -->
	<context:component-scan base-package="com.cignacmb.member.center" >
		<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
	</context:component-scan>

	<!--启动spring注解功能 -->
	<tx:annotation-driven transaction-manager="transactionManager" />
	
	<!-- 强制使用CGLIB代理 -->
	<aop:aspectj-autoproxy proxy-target-class="true" />

	<!-- 配置数据源 -->
	<bean id="member_dataSource"
		class="org.springframework.jndi.JndiObjectFactoryBean">
		<property name="jndiName">
            <value>java:comp/env/jdbc/member_jndi</value>
        </property>
	</bean>

	<!--把mybatis SqlSessionFactory的创建交由spring管理 -->
	<bean id="sqlSessionFactoryBeanName" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="member_dataSource" />
		<property name="configLocation" value="classpath:mybatis-config.xml" />
	</bean>

	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
		<property name="basePackage" value="com.cignacmb.member.center.dao" />
	</bean>

	<!-- Local Transaction Management (txManager) -->
	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="member_dataSource" />
	</bean>
	
	<bean id="freeMarker" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">  
    	<property name="templateLoaderPath" value="classpath:template"/><!--指定模板文件目录-->
	    <property name="freemarkerSettings"><!-- 设置FreeMarker环境属性-->
	      <props>  
<!-- 	          <prop key="template_update_delay">1800</prop> -->
	          <prop key="default_encoding">UTF-8</prop>
	          <prop key="locale">zh_CN</prop>
	      </props>  
	    </property>  
   </bean>

	<bean id="captchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha">
		<property name="config">
			<bean class="com.google.code.kaptcha.util.Config">
				<constructor-arg>
					<props>
						<prop key="kaptcha.border">no</prop>
						<prop key="kaptcha.image.width">80</prop>
						<prop key="kaptcha.image.height">36</prop>
						<prop key="kaptcha.textproducer.char.length">4</prop>
						<prop key="kaptcha.textproducer.font.size">20</prop>
						<prop key="kaptcha.textproducer.font.names">宋体,楷体,微软雅黑</prop>
						<prop key="kaptcha.textproducer.font.color">23,133,12</prop>
						<prop key="kaptcha.background.clear.from">255,255,255</prop>
						<prop key="kaptcha.background.clear.to">255,255,255</prop>
						<prop key="kaptcha.textproducer.char.string">1234567890</prop>
						<prop key="kaptcha.obscurificator.impl">com.cignacmb.member.center.validatecode.MemberWaterRipple</prop>
						<prop key="kaptcha.noise.color">23,133,12</prop>
						<prop key="kaptcha.noise.impl">com.cignacmb.member.center.validatecode.MemberNoise</prop>
						<prop key="kaptcha.word.impl">com.cignacmb.member.center.validatecode.MemberWordRenderer</prop>
					</props>
				</constructor-arg>
			</bean>
		</property>
	</bean>
</beans>
【spring mvc】applicationContext-mvc.xml spring mvc
<?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:p="http://www.springframework.org/schema/p"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:util="http://www.springframework.org/schema/util"
	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/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd 
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd 
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd"
	default-autowire="byName">
	
	<!-- 启用spring mvc 注解 -->
    <context:annotation-config />
    
	<!-- 解析配置文件 -->
	<context:property-placeholder location="classpath:system-config/${config_env}.properties" ignore-unresolvable="true" />
    
	<!-- 自动扫描Bean -->
	<context:component-scan base-package="com.cignacmb.member.center">
		<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" /> 
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service" />
	</context:component-scan>
	
     <!-- 处理在类级别上的@RequestMapping注解,增加了拦截器-->  
    <bean  
        class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" >  
        <property name="interceptors">  
           <!-- 多个拦截器,顺序执行 -->  
           <list>  
              <ref bean="loginInterceptor"/>  
           </list>  
        </property>  
    </bean>
    
    <!-- 处理方法级别上的@RequestMapping注解-->  
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" >  
        <property name="messageConverters">    
            <util:list id="beanList">
            	<!-- 将返回对象转换为json -->
                <ref bean="mappingJacksonHttpMessageConverter"/>    
            </util:list>    
        </property>   
    </bean>
	
	<!-- mvc的视图扭转 -->
	<bean id="viewResolver"	class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/jsp/" p:suffix=".jsp" />
	
	<!-- 为了处理返回的JSON数据的编码,默认是ISO-88859-1的,这里把它设置为UTF-8,解决有乱码的情况 -->
  	<bean id="mappingJacksonHttpMessageConverter"  class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
 		<property name="supportedMediaTypes">    
            <list>
               <value>text/html;charset=UTF-8</value>
               <value>application/json</value>
               <value>text/plain;charset=UTF-8</value>
<!--                <value>application/x-javascript</value> -->
            </list>
        </property>
    </bean>

</beans>
Global site tag (gtag.js) - Google Analytics