JAVA防止表单重复提交(SpringMVC,ICache)

一、抽取公共BaseController类

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;


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


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;


import com.cache.ICacheUtils;
import com.common.propertyeditor.DateConvertEditor;
import com.common.util.ValidateUtil;


public class BaseController {

/** 默认编码方式 */
protected final String defaultEncoding = "UTF-8";

/**
* 获取请求中的数据信息
* @return
*/
@SuppressWarnings("unchecked")
protected Map<String, String> getParameters(HttpServletRequest request) {
Map<String, String> map = new HashMap<String, String>();
Enumeration<String> enus = request.getParameterNames();
while (enus.hasMoreElements()) {
String key = enus.nextElement();
String value = request.getParameter(key);
map.put(key, value);
}
return map;
}

/**
* 获取get请求中的数据信息
* @return
*/
@SuppressWarnings("unchecked")
protected Map<String, String> getParametersByGet(HttpServletRequest request) {
Map<String, String> map = new HashMap<String, String>();
Enumeration<String> enus = request.getParameterNames();
while (enus.hasMoreElements()) {
String key = enus.nextElement();
String value = request.getParameter(key);
try {
if(ValidateUtil.isNotEmpty(value)) {
value = java.net.URLDecoder.decode(value,"UTF-8");
}
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
map.put(key, value);
}
return map;
}


@InitBinder  
protected void initBinder(HttpServletRequest request,  
                              ServletRequestDataBinder binder) throws Exception {  
    //对于需要转换为Date类型的属性,使用DateEditor进行处理  
    binder.registerCustomEditor(Date.class, new DateConvertEditor());  


/**
* 获取项目基础路径.
* @param req
* @return
*/
protected String getBasePath(HttpServletRequest req){
StringBuffer baseUrl = new StringBuffer();
String scheme = req.getScheme();
int port = req.getServerPort();


baseUrl.append(scheme); // http, https
baseUrl.append("://");
baseUrl.append(req.getServerName());
if ((scheme.equals("http") && port != 80) || (scheme.equals("https") && port != 443))
{
baseUrl.append(':');
baseUrl.append(req.getServerPort());
}
return baseUrl.toString();
}

/**
     * 向前台输出json字符串
     * @param jsonStr 要输出的json字符串
     * @throws IOException
     *
     * @author zzx
     */
    protected void printOutJson(HttpServletResponse response,String jsonStr) throws IOException{
    response.setCharacterEncoding(defaultEncoding);
    response.setContentType("text/json; charset=UTF-8");
    response.getWriter().print(jsonStr);

}


/**此处用于处理表单重复提交**/

    @Autowired
private ICacheUtils iCacheUtils;
    protected void createToken(){
    String token=UUID.randomUUID().toString();
    getRequest().getSession(false).setAttribute("token",token);//客户端token
    iCacheUtils.setToken(token);//服务端token
    }
    protected void removeToken(){
    String clinetToken = getRequest().getParameter("token");
    iCacheUtils.removeToken(clinetToken);
    }
    protected boolean isRepeatSubmit() {
    List<String> serverToken = iCacheUtils.getToken();
        if (ValidateUtil.isEmpty(serverToken)) {
            return true ;
        }
        String clinetToken = getRequest().getParameter("token");
        if (clinetToken == null ) {
            return true ;
        }
        if (!serverToken.contains(clinetToken)) {
            return true ;
        }
        return false ;
    }
    
   
    
/**
* 获取用户IP.
* @param req
* @return
*/
protected static String getIp(HttpServletRequest req){
String ip = req.getHeader("x-forwarded-for");
    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
        ip = req.getHeader("Proxy-Client-IP");
    }
    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
        ip = req.getHeader("WL-Proxy-Client-IP");
    }
    if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)){
        ip = req.getRemoteAddr();
    }
    ip = ip.equals("0:0:0:0:0:0:0:1")?"127.0.0.1":ip;
    return ip;
}

/**
* 取得HttpRequest的简化函数.
*/
protected HttpServletRequest getRequest(){
return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
}
protected HttpSession getSession(){
return getRequest().getSession();
}


protected HttpSession getSession(boolean isNew){
return getRequest().getSession(isNew);

}


    protected String getParameter(String name){
return getRequest().getParameter(name);
}
protected ResultDO<String> toErrorResult(BindingResult br){
return new ResultDO<String>(ResCode.COM_PARAMERROR.getResCode(),br.getAllErrors().get(0).getDefaultMessage().toString());
}
protected ResultDO<String> toErrorResult(String code,String dedsc){
return new ResultDO<String>(code,dedsc);
}
protected String toErrorResultString(BindingResult br){
ResultDO<String> dojo= toErrorResult(br);
return JsonUtil.toJson(dojo);
}
protected String toErrorResultString(ResultDO<?> dojo){
return JsonUtil.toJson(dojo);
}
protected String toErrorResultString(String code,String dedsc){
ResultDO<String> dojo= toErrorResult(code,dedsc);
return JsonUtil.toJson(dojo);
}
protected ResultDO<String> toErrorResult(ResCode coded){
return new ResultDO<String>(coded.getResCode(),coded.getResDescription());
}
protected <T>ResultDO<T> toSuccessResult(T br){
return new ResultDO<T>(br);
}
protected <T>ResultDO<T> toSuccessResult(){
return new ResultDO<T>(true);
}
protected <T>ResultDO<T> toErrorResult(ResultDO<T> _sRd){
return new ResultDO<T>(_sRd.getErrorCode(),_sRd.getErrorMsg(),_sRd.getObj());
}

}


二、创建ICacheUtils 接口

import java.util.List;




public interface ICacheUtils {


public List<String> getToken();
public List<String> setToken(String token);
public List<String> removeToken(String token);

}


三、实现ICacheUtils 接口



/**
 * 基于ehcache的缓存工具类
 * @author admin
 *
 */
@SuppressWarnings({"rawtypes","unchecked"})
public class EhCacheUtils implements ICacheUtils{




public List<String> getToken(){
String key=SYS_CACHE+"_getToken";
List<String>  tokenList = (List) get(SYS_CACHE,key);
return tokenList;
}
public List<String> setToken(String token){
String key=SYS_CACHE+"_getToken";
List<String>  tokenList = (List) get(SYS_CACHE,key);
if (tokenList == null){
tokenList =  new ArrayList<String>();
}
tokenList.add(token);
put(SYS_CACHE,key, tokenList);
return tokenList;
}
public List<String> removeToken(String token){
String key=SYS_CACHE+"_getToken";
List<String>  tokenList = (List) get(SYS_CACHE,key);
if (tokenList == null){
tokenList =  new ArrayList<String>();
}
tokenList.remove(token);
put(SYS_CACHE,key, tokenList);
return tokenList;
}

}

四、控制器继承基础BaseController

@Controller
@RequestMapping("/test")

public class TestController extends BaseController {

    @RequestMapping(value = "/toFormPage")
public String toFormPage(ModelMap map) {
createToken();
。。。。此处写你自己的代码
return "/FormPage";
}

@RequestMapping(value = "/doSaveTest",method = RequestMethod.POST)

public @ResponseBody ResultDO<?> doSaveTest(HttpServletRequest request){

               /**判断是否重复提交**/

if(isRepeatSubmit()){
return toErrorResult(new ResultDO<Boolean>(ResCode.COM_EXCEPTION.getResCode(), "表单已提交成功"));

}

try{

/**此处写调用service层代码**/

                /**如果成功则:**/

                removeToken();

}catch(Exception e){


}

}


五、jsp页面Form表单

<form action="${pageContext.request.contextPath}/test/doSaveTest" method="post" id="myForm">

            <input type="hidden" value="${token}" name="token" />

                 .......其他表单数据

            <input type="submit"/>

</form>



六、一些工具类

1、JsonUtil 

import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;


import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;


/**
 * this is a common Class work with Json
 * 
 * @author ylzhang20
 */
public abstract class JsonUtil {


/**
* Encapsulate <code>Object</code> to a JSON String

* @param o
*            Oject
* @return JSON JSON String
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static String toJson(final Object o) {
if (o == null) {
return "null";
}
if (o instanceof String) // String
{
return string2Json((String) o);
}
if (o instanceof Boolean) // Boolean
{
return boolean2Json((Boolean) o);
}
if (o instanceof Number) // Number
{
return number2Json((Number) o);
}
if (o instanceof Map) // Map
{
return map2Json((Map<String, Object>) o);
}
if (o instanceof Collection) // List Set
{
return collection2Json((Collection) o);
}
if (o instanceof Object[]) // List of object
{
return array2Json((Object[]) o);
}


if (o instanceof int[])// int type
{
return intArray2Json((int[]) o);
}
if (o instanceof boolean[])// boolean type
{
return booleanArray2Json((boolean[]) o);
}
if (o instanceof long[]) {
return longArray2Json((long[]) o);
}
if (o instanceof float[]) {
return floatArray2Json((float[]) o);
}
if (o instanceof double[]) {
return doubleArray2Json((double[]) o);
}
if (o instanceof short[]) {
return shortArray2Json((short[]) o);
}
if (o instanceof byte[]) {
return byteArray2Json((byte[]) o);
}
if (o instanceof Object) {
return object2Json(o);
}


throw new RuntimeException("No support type Object:"
+ o.getClass().getName());
}


/**
* Change a String to an JSON String

* @param s
*            a String
* @return a JSON String
*/
public static String string2Json(final String s) {
final StringBuilder sb = new StringBuilder(s.length() + 20);
sb.append('\"');
for (int i = 0; i < s.length(); i++) {
final char c = s.charAt(i);
switch (c) {
case '\"':
sb.append("\\\"");
break;
case '\\':
sb.append("\\\\");
break;
case '/':
sb.append("\\/");
break;
case '\b':
sb.append("\\b");
break;
case '\f':
sb.append("\\f");
break;
case '\n':
sb.append("\\n");
break;
case '\r':
sb.append("\\r");
break;
case '\t':
sb.append("\\t");
break;
default:
sb.append(c);
}
}
sb.append('\"');
return sb.toString();
}


/**
* Change a Number to JSON

* @param number
*            Number
* @return a JSON String
*/
public static String number2Json(final Number number) {
return number.toString();
}


/**
* Change Boolean to JSON

* @param bool
*            Boolean
* @return a JSON String
*/
public static String boolean2Json(final Boolean bool) {
return bool.toString();
}


/**
* Change Collection to JSON (List,Set)

* @param c
*            a Collection Object
* @return a JSON String
*/
public static String collection2Json(final Collection<Object> c) {
final Object[] arrObj = c.toArray();
return toJson(arrObj);
}

/**
* 把list数据转换的json字符串

* @param labels list数据
* @return 返回转换后的json字符串
* @author xfzhou
*/
public static String collection2Json(final Object obj) {
if(obj == null) return null;
Gson gson = new Gson();

return gson.toJson(obj);
    }

/**
* 把json数据字符串,转换成list对象

* @param str json数据字符串
* @return 返回list对象,元素是map对象
* @author xfzhou
*/
public static List<String> json2List(String str) {
        if(ValidateUtil.isEmpty( str )) return null;
        
        Gson jsonObj = new Gson();
        Type listType = new TypeToken<List<String>>() {}.getType();
        
        return jsonObj.fromJson( str, listType );
    }


/**
* Change Map<String, Object> to JSON

* @param map
*            a Map
* @return a JSON String
*/
public static String map2Json(final Map<String, Object> map) {
if (map.isEmpty()) {
return "{}";
}
final StringBuilder sb = new StringBuilder(map.size() << 4);
sb.append('{');
final Set<String> keys = map.keySet();
for (final String key : keys) {
final Object value = map.get(key);
sb.append('\"');
sb.append(key); // Can not be special character
sb.append('\"');
sb.append(':');
sb.append(toJson(value));
sb.append(',');
}
// add last "}"
sb.setCharAt(sb.length() - 1, '}');
return sb.toString();
}


/**
* Change array to JSON

* @param array
*            an Object array
* @return a JSON String
*/
public static String array2Json(final Object[] array) {
if (array.length == 0) {
return "[]";
}
final StringBuilder sb = new StringBuilder(array.length << 4); // the
// power
// of
// four
sb.append('[');
for (final Object o : array) {
sb.append(toJson(o));
sb.append(',');
}
// change last "," to "]"
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}


/**
* Change int array to JSON

* @param array
*            a int array
* @return a JSON String
*/
public static String intArray2Json(final int[] array) {
if (array.length == 0) {
return "[]";
}
final StringBuilder sb = new StringBuilder(array.length << 4);
sb.append('[');
for (final int o : array) {
sb.append(Integer.toString(o));
sb.append(',');
}
// set last ',' to ']':
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}


/**
* Change long array to JSON

* @param array
*            a long array
* @return a JSON String
*/
public static String longArray2Json(final long[] array) {
if (array.length == 0) {
return "[]";
}
final StringBuilder sb = new StringBuilder(array.length << 4);
sb.append('[');
for (final long o : array) {
sb.append(Long.toString(o));
sb.append(',');
}
// set last ',' to ']':
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}


/**
* Change boolean array to JSON

* @param array
*            an boolean array
* @return a JSON String
*/
public static String booleanArray2Json(final boolean[] array) {
if (array.length == 0) {
return "[]";
}
final StringBuilder sb = new StringBuilder(array.length << 4);
sb.append('[');
for (final boolean o : array) {
sb.append(Boolean.toString(o));
sb.append(',');
}
// set last ',' to ']':
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}


/**
* Change float array to JSON

* @param array
*            a float array
* @return a JSON String
*/
public static String floatArray2Json(final float[] array) {
if (array.length == 0) {
return "[]";
}
final StringBuilder sb = new StringBuilder(array.length << 4);
sb.append('[');
for (final float o : array) {
sb.append(Float.toString(o));
sb.append(',');
}
// set last ',' to ']':
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}


/**
* Change double array to JSON

* @param array
*            an double array
* @return a JSON String
*/
public static String doubleArray2Json(final double[] array) {
if (array.length == 0) {
return "[]";
}
final StringBuilder sb = new StringBuilder(array.length << 4);
sb.append('[');
for (final double o : array) {
sb.append(Double.toString(o));
sb.append(',');
}
// set last ',' to ']':
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}


public static String shortArray2Json(final short[] array) {
if (array.length == 0) {
return "[]";
}
final StringBuilder sb = new StringBuilder(array.length << 4);
sb.append('[');
for (final short o : array) {
sb.append(Short.toString(o));
sb.append(',');
}
// set last ',' to ']':
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}


/**
* Change byte array to JSON

* @param array
*            an byte array
* @return a JSON String
*/
public static String byteArray2Json(final byte[] array) {
if (array.length == 0) {
return "[]";
}
final StringBuilder sb = new StringBuilder(array.length << 4);
sb.append('[');
for (final byte o : array) {
sb.append(Byte.toString(o));
sb.append(',');
}
// set last ',' to ']':
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}


/**
* Change an Object to JSON

* @param bean
*            Object to json
* @return a JSON String
*/
public static String object2Json(final Object bean) {
// check null
if (bean == null) {
return "{}";
}
final Method[] methods = bean.getClass().getMethods();
final StringBuilder sb = new StringBuilder(methods.length << 4);
// the power of four
sb.append('{');


for (final Method method : methods) {
try {
final String name = method.getName();
String key = "";
if (name.startsWith("get")) {
key = name.substring(3);


final String[] arrs = { "Class" };// prevention of endless
// loop
boolean bl = false;
for (final String s : arrs) {
if (s.equals(key)) {
bl = true;
continue;
}
}
if (bl) {
continue; // prevention of endless loop
}
} else if (name.startsWith("is")) {
key = name.substring(2);
}
if (key.length() > 0 && Character.isUpperCase(key.charAt(0))
&& method.getParameterTypes().length == 0) {
if (key.length() == 1) {
key = key.toLowerCase();
} else if (!Character.isUpperCase(key.charAt(1))) {
key = key.substring(0, 1).toLowerCase()
+ key.substring(1);
}
final Object elementObj = method.invoke(bean);


// System.out.println("###" + key + ":" +
// elementObj.toString());


sb.append('\"');
sb.append(key); // can't content special character
sb.append('\"');
sb.append(':');
sb.append(toJson(elementObj));
sb.append(',');
}
} catch (final Exception e) {
// e.getMessage();
throw new RuntimeException("Packing Object Exception��"
+ e.getMessage(), e);
}
}
if (sb.length() == 1) {
return bean.toString();
} else {
sb.setCharAt(sb.length() - 1, '}');
return sb.toString();
}
}


/**
* Change an Object to JSON,the jsonString has object name.

* @param array
*            an int array
* @return a JSON String
*/
public static String object2JsonWithName(final Object bean) {
StringBuffer objectContent = new StringBuffer(object2Json(bean));
return objectContent.append(bean.getClass().getSimpleName()).toString();
}

/**
* 把json数据字符串,转换成map对象

* @param jsonData son数据字符串
* @return 返回map对象
* @author xfzhou
*/
public static Map<String,String> json2Map(String jsonData) {
        if(ValidateUtil.isEmpty( jsonData )) return null;
        
        Gson jsonObj = new Gson();
        Type mapType = new TypeToken<Map<String, String>>() {}.getType();
        
        return jsonObj.fromJson( jsonData, mapType );        
    }


/**
* 把json数据字符串,转换成list对象

* @param fileInfoList json数据字符串
* @return 返回list对象,元素是map对象
* @author xfzhou
*/
public static List<Map<String,String>> json2MapList(String fileInfoList) {
        if(ValidateUtil.isEmpty( fileInfoList )) return null;
        
        Gson jsonObj = new Gson();
        Type listType = new TypeToken<List<Map<String, String>>>() {}.getType();
        
        return jsonObj.fromJson( fileInfoList, listType );
    }

}


2、返回体



import java.io.Serializable;


/**
 * 业务操作响应Bean.
 * @param <T>
 */
public class ResultDO<T> extends BaseVo implements Serializable {
private static final long serialVersionUID = -2042618546543630713L;
// 业务操作是否成功
private boolean isOK = true;
// 返回值,可以是任何类型
private T obj;
// 响应错误码
private String errorMsg;
// 响应码
private String errorCode;


public ResultDO() {
}
public ResultDO(boolean _isOK) {
this.isOK = _isOK;
}
public ResultDO(T result) {
this.isOK = true;
this.obj = result;
}


public ResultDO(String errorCode, String errorMsg) {
this.isOK = false;
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}


public ResultDO(String errorCode, String errorMsg, T result) {
this.isOK = false;
this.errorCode = errorCode;
this.errorMsg = errorMsg;
this.obj = result;
}


public String getErrorCode() {
return errorCode;
}


public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}


public boolean isOK() {
return isOK;
}


public ResultDO<T> setOK(boolean isOK) {
this.isOK = isOK;
return this;
}


public T getObj() {
return obj;
}


public ResultDO<T> setObj(T obj) {
this.obj = obj;
return this;
}


public String getErrorMsg() {
return errorMsg;
}


public ResultDO<T> setErrorMsg(String errorMsg) {
this.isOK = false;
this.errorMsg = errorMsg;
return this;
}

}


3、基础实体类

public abstract class BaseVo implements Serializable{

/**

*/
private static final long serialVersionUID = 1169083819505759557L;


@Override
public String toString(){
return JsonUtil.toJson(this);
}


}

猜你喜欢

转载自blog.csdn.net/qq_29777207/article/details/79450839