使用struts2的json插件时,自己定义日期格式经常使用的方式是在get属性上加入@JSON注解,这个对于少量Date属性还能够,可是假设date字段多了,总不可能去给每一个date get方法加入json注解吧!

发现极大不便后查看了sturts-plugin.xml 中的json-default定义,源代码跟踪到json拦截器内部一点发现都没有,自己定义

org.apache.struts2.json.JSONPopulator中的dateFormatter属性全然不起效果。可是在同一个包下:org.apache.struts2.json 发现了类:JSONWriter 在这里才找到了一些端倪

将源代码中的

  1. /**
  2. * Add date to buffer
  3. */
  4. protected void date(Date date, Method method) {
  5. JSON json = null;
  6. if (method != null)
  7. json = method.getAnnotation(JSON.class);
  8. if (this.formatter == null)
  9. this.formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  10.  
  11. DateFormat formatter = (json != null) && (json.format().length() > 0) ? new SimpleDateFormat(json
  12. .format()) : this.formatter;
  13. this.string(formatter.format(date));
  14. }
  1. SimpleDateFormat 格式改成自己定义日期格式就可以,这样全局json 日期格式就自己定义完毕了!
  1. 注意:覆盖时仅仅须要自己定义包:org.apache.struts2.json将改动后的<span style="font-family: Arial, Helvetica, sans-serif;">JSONWriter放到包下就可以,没有必要去改动插件中的源代码信息 </span>

以下附上整个类的源代码:

  1. /*
  2. * $Id$
  3. *
  4. * Licensed to the Apache Software Foundation (ASF) under one
  5. * or more contributor license agreements. See the NOTICE file
  6. * distributed with this work for additional information
  7. * regarding copyright ownership. The ASF licenses this file
  8. * to you under the Apache License, Version 2.0 (the
  9. * "License"); you may not use this file except in compliance
  10. * with the License. You may obtain a copy of the License at
  11. *
  12. * http://www.apache.org/licenses/LICENSE-2.0
  13. *
  14. * Unless required by applicable law or agreed to in writing,
  15. * software distributed under the License is distributed on an
  16. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  17. * KIND, either express or implied. See the License for the
  18. * specific language governing permissions and limitations
  19. * under the License.
  20. */
  21. package org.apache.struts2.json;
  22.  
  23. import com.opensymphony.xwork2.util.logging.Logger;
  24. import com.opensymphony.xwork2.util.logging.LoggerFactory;
  25. import org.apache.struts2.json.annotations.JSON;
  26. import org.apache.struts2.json.annotations.JSONFieldBridge;
  27. import org.apache.struts2.json.annotations.JSONParameter;
  28. import org.apache.struts2.json.bridge.FieldBridge;
  29. import org.apache.struts2.json.bridge.ParameterizedBridge;
  30.  
  31. import java.beans.BeanInfo;
  32. import java.beans.IntrospectionException;
  33. import java.beans.Introspector;
  34. import java.beans.PropertyDescriptor;
  35. import java.lang.reflect.Array;
  36. import java.lang.reflect.Method;
  37. import java.text.CharacterIterator;
  38. import java.text.DateFormat;
  39. import java.text.SimpleDateFormat;
  40. import java.text.StringCharacterIterator;
  41. import java.util.*;
  42. import java.util.concurrent.ConcurrentHashMap;
  43. import java.util.concurrent.ConcurrentMap;
  44. import java.util.regex.Pattern;
  45.  
  46. /**
  47. * <p>
  48. * Serializes an object into JavaScript Object Notation (JSON). If cyclic
  49. * references are detected they will be nulled out.
  50. * </p>
  51. */
  52. public class JSONWriter {
  53.  
  54. private static final Logger LOG = LoggerFactory.getLogger(JSONWriter.class);
  55.  
  56. /**
  57. * By default, enums are serialised as name=value pairs
  58. */
  59. public static final boolean ENUM_AS_BEAN_DEFAULT = false;
  60.  
  61. private static char[] hex = "0123456789ABCDEF".toCharArray();
  62.  
  63. private static final ConcurrentMap<Class<?>, BeanInfo> BEAN_INFO_CACHE_IGNORE_HIERARCHY = new ConcurrentHashMap<Class<?>, BeanInfo>();
  64. private static final ConcurrentMap<Class<?>, BeanInfo> BEAN_INFO_CACHE = new ConcurrentHashMap<Class<?>, BeanInfo>();
  65.  
  66. private StringBuilder buf = new StringBuilder();
  67. private Stack<Object> stack = new Stack<Object>();
  68. private boolean ignoreHierarchy = true;
  69. private Object root;
  70. private boolean buildExpr = true;
  71. private String exprStack = "";
  72. private Collection<Pattern> excludeProperties;
  73. private Collection<Pattern> includeProperties;
  74. private DateFormat formatter;
  75. private boolean enumAsBean = ENUM_AS_BEAN_DEFAULT;
  76. private boolean excludeNullProperties;
  77.  
  78. /**
  79. * @param object Object to be serialized into JSON
  80. * @return JSON string for object
  81. * @throws JSONException
  82. */
  83. public String write(Object object) throws JSONException {
  84. return this.write(object, null, null, false);
  85. }
  86.  
  87. /**
  88. * @param object Object to be serialized into JSON
  89. * @return JSON string for object
  90. * @throws JSONException
  91. */
  92. public String write(Object object, Collection<Pattern> excludeProperties,
  93. Collection<Pattern> includeProperties, boolean excludeNullProperties) throws JSONException {
  94. this.excludeNullProperties = excludeNullProperties;
  95. this.buf.setLength(0);
  96. this.root = object;
  97. this.exprStack = "";
  98. this.buildExpr = ((excludeProperties != null) && !excludeProperties.isEmpty())
  99. || ((includeProperties != null) && !includeProperties.isEmpty());
  100. this.excludeProperties = excludeProperties;
  101. this.includeProperties = includeProperties;
  102. this.value(object, null);
  103.  
  104. return this.buf.toString();
  105. }
  106.  
  107. /**
  108. * Detect cyclic references
  109. */
  110. protected void value(Object object, Method method) throws JSONException {
  111. if (object == null) {
  112. this.add("null");
  113.  
  114. return;
  115. }
  116.  
  117. if (this.stack.contains(object)) {
  118. Class clazz = object.getClass();
  119.  
  120. // cyclic reference
  121. if (clazz.isPrimitive() || clazz.equals(String.class)) {
  122. this.process(object, method);
  123. } else {
  124. if (LOG.isDebugEnabled()) {
  125. LOG.debug("Cyclic reference detected on " + object);
  126. }
  127.  
  128. this.add("null");
  129. }
  130.  
  131. return;
  132. }
  133.  
  134. this.process(object, method);
  135. }
  136.  
  137. /**
  138. * Serialize object into json
  139. */
  140. protected void process(Object object, Method method) throws JSONException {
  141. this.stack.push(object);
  142.  
  143. if (object instanceof Class) {
  144. this.string(object);
  145. } else if (object instanceof Boolean) {
  146. this.bool((Boolean) object);
  147. } else if (object instanceof Number) {
  148. this.add(object);
  149. } else if (object instanceof String) {
  150. this.string(object);
  151. } else if (object instanceof Character) {
  152. this.string(object);
  153. } else if (object instanceof Map) {
  154. this.map((Map) object, method);
  155. } else if (object.getClass().isArray()) {
  156. this.array(object, method);
  157. } else if (object instanceof Iterable) {
  158. this.array(((Iterable) object).iterator(), method);
  159. } else if (object instanceof Date) {
  160. this.date((Date) object, method);
  161. } else if (object instanceof Calendar) {
  162. this.date(((Calendar) object).getTime(), method);
  163. } else if (object instanceof Locale) {
  164. this.string(object);
  165. } else if (object instanceof Enum) {
  166. this.enumeration((Enum) object);
  167. } else {
  168. processCustom(object, method);
  169. }
  170.  
  171. this.stack.pop();
  172. }
  173.  
  174. /**
  175. * Serialize custom object into json
  176. */
  177. protected void processCustom(Object object, Method method) throws JSONException {
  178. this.bean(object);
  179. }
  180.  
  181. /**
  182. * Instrospect bean and serialize its properties
  183. */
  184. protected void bean(Object object) throws JSONException {
  185. this.add("{");
  186.  
  187. BeanInfo info;
  188.  
  189. try {
  190. Class clazz = object.getClass();
  191.  
  192. info = ((object == this.root) && this.ignoreHierarchy)
  193. ? getBeanInfoIgnoreHierarchy(clazz)
  194. : getBeanInfo(clazz);
  195.  
  196. PropertyDescriptor[] props = info.getPropertyDescriptors();
  197.  
  198. boolean hasData = false;
  199. for (PropertyDescriptor prop : props) {
  200. String name = prop.getName();
  201. Method accessor = prop.getReadMethod();
  202. Method baseAccessor = findBaseAccessor(clazz, accessor);
  203.  
  204. if (baseAccessor != null) {
  205. if (baseAccessor.isAnnotationPresent(JSON.class)) {
  206. JSONAnnotationFinder jsonFinder = new JSONAnnotationFinder(baseAccessor).invoke();
  207.  
  208. if (!jsonFinder.shouldSerialize()) continue;
  209. if (jsonFinder.getName() != null) {
  210. name = jsonFinder.getName();
  211. }
  212. }
  213. // ignore "class" and others
  214. if (this.shouldExcludeProperty(prop)) {
  215. continue;
  216. }
  217. String expr = null;
  218. if (this.buildExpr) {
  219. expr = this.expandExpr(name);
  220. if (this.shouldExcludeProperty(expr)) {
  221. continue;
  222. }
  223. expr = this.setExprStack(expr);
  224. }
  225.  
  226. Object value = accessor.invoke(object);
  227. if (baseAccessor.isAnnotationPresent(JSONFieldBridge.class)) {
  228. value = getBridgedValue(baseAccessor, value);
  229. }
  230.  
  231. boolean propertyPrinted = this.add(name, value, accessor, hasData);
  232. hasData = hasData || propertyPrinted;
  233. if (this.buildExpr) {
  234. this.setExprStack(expr);
  235. }
  236. }
  237. }
  238.  
  239. // special-case handling for an Enumeration - include the name() as
  240. // a property */
  241. if (object instanceof Enum) {
  242. Object value = ((Enum) object).name();
  243. this.add("_name", value, object.getClass().getMethod("name"), hasData);
  244. }
  245. } catch (Exception e) {
  246. throw new JSONException(e);
  247. }
  248.  
  249. this.add("}");
  250. }
  251.  
  252. protected BeanInfo getBeanInfoIgnoreHierarchy(final Class<?> clazz) throws IntrospectionException {
  253. BeanInfo beanInfo = BEAN_INFO_CACHE_IGNORE_HIERARCHY.get(clazz);
  254. if (beanInfo != null) {
  255. return beanInfo;
  256. }
  257. beanInfo = Introspector.getBeanInfo(clazz, clazz.getSuperclass());
  258. BEAN_INFO_CACHE_IGNORE_HIERARCHY.put(clazz, beanInfo);
  259. return beanInfo;
  260. }
  261.  
  262. protected BeanInfo getBeanInfo(final Class<?> clazz) throws IntrospectionException {
  263. BeanInfo beanInfo = BEAN_INFO_CACHE.get(clazz);
  264. if (beanInfo != null) {
  265. return beanInfo;
  266. }
  267. beanInfo = Introspector.getBeanInfo(clazz);
  268. BEAN_INFO_CACHE.put(clazz, beanInfo);
  269. return beanInfo;
  270. }
  271.  
  272. protected Object getBridgedValue(Method baseAccessor, Object value) throws InstantiationException, IllegalAccessException {
  273. JSONFieldBridge fieldBridgeAnn = baseAccessor.getAnnotation(JSONFieldBridge.class);
  274. if (fieldBridgeAnn != null) {
  275. Class impl = fieldBridgeAnn.impl();
  276. FieldBridge instance = (FieldBridge) impl.newInstance();
  277.  
  278. if (fieldBridgeAnn.params().length > 0 && ParameterizedBridge.class.isAssignableFrom(impl)) {
  279. Map<String, String> params = new HashMap<String, String>(fieldBridgeAnn.params().length);
  280. for (JSONParameter param : fieldBridgeAnn.params()) {
  281. params.put(param.name(), param.value());
  282. }
  283. ((ParameterizedBridge) instance).setParameterValues(params);
  284. }
  285. value = instance.objectToString(value);
  286. }
  287. return value;
  288. }
  289.  
  290. protected Method findBaseAccessor(Class clazz, Method accessor) {
  291. Method baseAccessor = null;
  292. if (clazz.getName().contains("$$EnhancerByCGLIB$$")) {
  293. try {
  294. baseAccessor = Thread.currentThread().getContextClassLoader().loadClass(
  295. clazz.getName().substring(0, clazz.getName().indexOf("$$"))).getMethod(
  296. accessor.getName(), accessor.getParameterTypes());
  297. } catch (Exception ex) {
  298. LOG.debug(ex.getMessage(), ex);
  299. }
  300. } else if (clazz.getName().contains("$$_javassist")) {
  301. try {
  302. baseAccessor = Class.forName(
  303. clazz.getName().substring(0, clazz.getName().indexOf("_$$")))
  304. .getMethod(accessor.getName(), accessor.getParameterTypes());
  305. } catch (Exception ex) {
  306. LOG.debug(ex.getMessage(), ex);
  307. }
  308. } else {
  309. return accessor;
  310. }
  311. return baseAccessor;
  312. }
  313.  
  314. /**
  315. * Instrospect an Enum and serialize it as a name/value pair or as a bean
  316. * including all its own properties
  317. */
  318. protected void enumeration(Enum enumeration) throws JSONException {
  319. if (enumAsBean) {
  320. this.bean(enumeration);
  321. } else {
  322. this.string(enumeration.name());
  323. }
  324. }
  325.  
  326. protected boolean shouldExcludeProperty(PropertyDescriptor prop) throws SecurityException, NoSuchFieldException {
  327. String name = prop.getName();
  328. return name.equals("class")
  329. || name.equals("declaringClass")
  330. || name.equals("cachedSuperClass")
  331. || name.equals("metaClass");
  332. }
  333.  
  334. protected String expandExpr(int i) {
  335. return this.exprStack + "[" + i + "]";
  336. }
  337.  
  338. protected String expandExpr(String property) {
  339. if (this.exprStack.length() == 0) {
  340. return property;
  341. }
  342. return this.exprStack + "." + property;
  343. }
  344.  
  345. protected String setExprStack(String expr) {
  346. String s = this.exprStack;
  347. this.exprStack = expr;
  348. return s;
  349. }
  350.  
  351. protected boolean shouldExcludeProperty(String expr) {
  352. if (this.excludeProperties != null) {
  353. for (Pattern pattern : this.excludeProperties) {
  354. if (pattern.matcher(expr).matches()) {
  355. if (LOG.isDebugEnabled()) {
  356. LOG.debug("Ignoring property because of exclude rule: " + expr);
  357. }
  358. return true;
  359. }
  360. }
  361. }
  362.  
  363. if (this.includeProperties != null) {
  364. for (Pattern pattern : this.includeProperties) {
  365. if (pattern.matcher(expr).matches()) {
  366. return false;
  367. }
  368. }
  369. if (LOG.isDebugEnabled()){
  370. LOG.debug("Ignoring property because of include rule: " + expr);
  371. }
  372. return true;
  373. }
  374. return false;
  375. }
  376.  
  377. /**
  378. * Add name/value pair to buffer
  379. */
  380. protected boolean add(String name, Object value, Method method, boolean hasData) throws JSONException {
  381. if (excludeNullProperties && value == null) {
  382. return false;
  383. }
  384. if (hasData) {
  385. this.add(',');
  386. }
  387. this.add('"');
  388. this.add(name);
  389. this.add("\":");
  390. this.value(value, method);
  391. return true;
  392. }
  393.  
  394. /**
  395. * Add map to buffer
  396. */
  397. protected void map(Map map, Method method) throws JSONException {
  398. this.add("{");
  399.  
  400. Iterator it = map.entrySet().iterator();
  401.  
  402. boolean warnedNonString = false; // one report per map
  403. boolean hasData = false;
  404. while (it.hasNext()) {
  405. Map.Entry entry = (Map.Entry) it.next();
  406. if (excludeNullProperties && entry.getValue() == null) {
  407. continue;
  408. }
  409.  
  410. Object key = entry.getKey();
  411. if (key == null) {
  412. LOG.error("Cannot build expression for null key in #0", exprStack);
  413. continue;
  414. }
  415.  
  416. String expr = null;
  417. if (this.buildExpr) {
  418. expr = this.expandExpr(key.toString());
  419. if (this.shouldExcludeProperty(expr)) {
  420. continue;
  421. }
  422. expr = this.setExprStack(expr);
  423. }
  424. if (hasData) {
  425. this.add(',');
  426. }
  427. hasData = true;
  428. if (!warnedNonString && !(key instanceof String)) {
  429. if (LOG.isWarnEnabled()) {
  430. LOG.warn("JavaScript doesn't support non-String keys, using toString() on #0", key.getClass().getName());
  431. }
  432. warnedNonString = true;
  433. }
  434. this.value(key.toString(), method);
  435. this.add(":");
  436. this.value(entry.getValue(), method);
  437. if (this.buildExpr) {
  438. this.setExprStack(expr);
  439. }
  440. }
  441.  
  442. this.add("}");
  443. }
  444.  
  445. /**
  446. * Add date to buffer
  447. */
  448. protected void date(Date date, Method method) {
  449. JSON json = null;
  450. if (method != null)
  451. json = method.getAnnotation(JSON.class);
  452. if (this.formatter == null)
  453. this.formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  454.  
  455. DateFormat formatter = (json != null) && (json.format().length() > 0) ? new SimpleDateFormat(json
  456. .format()) : this.formatter;
  457. this.string(formatter.format(date));
  458. }
  459.  
  460. /**
  461. * Add array to buffer
  462. */
  463. protected void array(Iterator it, Method method) throws JSONException {
  464. this.add("[");
  465.  
  466. boolean hasData = false;
  467. for (int i = 0; it.hasNext(); i++) {
  468. String expr = null;
  469. if (this.buildExpr) {
  470. expr = this.expandExpr(i);
  471. if (this.shouldExcludeProperty(expr)) {
  472. it.next();
  473. continue;
  474. }
  475. expr = this.setExprStack(expr);
  476. }
  477. if (hasData) {
  478. this.add(',');
  479. }
  480. hasData = true;
  481. this.value(it.next(), method);
  482. if (this.buildExpr) {
  483. this.setExprStack(expr);
  484. }
  485. }
  486.  
  487. this.add("]");
  488. }
  489.  
  490. /**
  491. * Add array to buffer
  492. */
  493. protected void array(Object object, Method method) throws JSONException {
  494. this.add("[");
  495.  
  496. int length = Array.getLength(object);
  497.  
  498. boolean hasData = false;
  499. for (int i = 0; i < length; ++i) {
  500. String expr = null;
  501. if (this.buildExpr) {
  502. expr = this.expandExpr(i);
  503. if (this.shouldExcludeProperty(expr)) {
  504. continue;
  505. }
  506. expr = this.setExprStack(expr);
  507. }
  508. if (hasData) {
  509. this.add(',');
  510. }
  511. hasData = true;
  512. this.value(Array.get(object, i), method);
  513. if (this.buildExpr) {
  514. this.setExprStack(expr);
  515. }
  516. }
  517.  
  518. this.add("]");
  519. }
  520.  
  521. /**
  522. * Add boolean to buffer
  523. */
  524. protected void bool(boolean b) {
  525. this.add(b ? "true" : "false");
  526. }
  527.  
  528. /**
  529. * escape characters
  530. */
  531. protected void string(Object obj) {
  532. this.add('"');
  533.  
  534. CharacterIterator it = new StringCharacterIterator(obj.toString());
  535.  
  536. for (char c = it.first(); c != CharacterIterator.DONE; c = it.next()) {
  537. if (c == '"') {
  538. this.add("\\\"");
  539. } else if (c == '\\') {
  540. this.add("\\\\");
  541. } else if (c == '/') {
  542. this.add("\\/");
  543. } else if (c == '\b') {
  544. this.add("\\b");
  545. } else if (c == '\f') {
  546. this.add("\\f");
  547. } else if (c == '\n') {
  548. this.add("\\n");
  549. } else if (c == '\r') {
  550. this.add("\\r");
  551. } else if (c == '\t') {
  552. this.add("\\t");
  553. } else if (Character.isISOControl(c)) {
  554. this.unicode(c);
  555. } else {
  556. this.add(c);
  557. }
  558. }
  559.  
  560. this.add('"');
  561. }
  562.  
  563. /**
  564. * Add object to buffer
  565. */
  566. protected void add(Object obj) {
  567. this.buf.append(obj);
  568. }
  569.  
  570. /**
  571. * Add char to buffer
  572. */
  573. protected void add(char c) {
  574. this.buf.append(c);
  575. }
  576.  
  577. /**
  578. * Represent as unicode
  579. *
  580. * @param c character to be encoded
  581. */
  582. protected void unicode(char c) {
  583. this.add("\\u");
  584.  
  585. int n = c;
  586.  
  587. for (int i = 0; i < 4; ++i) {
  588. int digit = (n & 0xf000) >> 12;
  589.  
  590. this.add(hex[digit]);
  591. n <<= 4;
  592. }
  593. }
  594.  
  595. public void setIgnoreHierarchy(boolean ignoreHierarchy) {
  596. this.ignoreHierarchy = ignoreHierarchy;
  597. }
  598.  
  599. /**
  600. * If true, an Enum is serialized as a bean with a special property
  601. * _name=name() as all as all other properties defined within the enum.<br/>
  602. * If false, an Enum is serialized as a name=value pair (name=name())
  603. *
  604. * @param enumAsBean true to serialize an enum as a bean instead of as a name=value
  605. * pair (default=false)
  606. */
  607. public void setEnumAsBean(boolean enumAsBean) {
  608. this.enumAsBean = enumAsBean;
  609. }
  610.  
  611. protected static class JSONAnnotationFinder {
  612. private boolean serialize = true;
  613. private Method accessor;
  614. private String name;
  615.  
  616. public JSONAnnotationFinder(Method accessor) {
  617. this.accessor = accessor;
  618. }
  619.  
  620. public boolean shouldSerialize() {
  621. return serialize;
  622. }
  623.  
  624. public String getName() {
  625. return name;
  626. }
  627.  
  628. public JSONAnnotationFinder invoke() {
  629. JSON json = accessor.getAnnotation(JSON.class);
  630. serialize = json.serialize();
  631. if (serialize && json.name().length() > 0) {
  632. name = json.name();
  633. }
  634. return this;
  635. }
  636. }
  637.  
  638. }

struts2 json 定义全局Date格式的更多相关文章

  1. vue定义全局date过滤器(自定义JS文件模块和Moment.js库)

    自定义dateFormat.js文件模块 dateFormat.js /** * 时间字符串 转 时间戳 * @param {String} time_str 时间字符串(格式"2014-0 ...

  2. 字定义JSON序列化支持datetime格式序列化

    字定义JSON序列化支持datetime格式序列化 由于json.dumps无法处理datetime日期,所以可以通过自定义处理器来做扩展,如: import json from datetime i ...

  3. struts2 json 输出日期格式不正确

    struts2 输出json中 日期出现:2013-12-17T15:57:47 错误格式的数据 原因:struts2 json插件对日期的格式化有问题 解决方法:在实体类的日期的get方法上加注解: ...

  4. webapi返回json格式,并定义日期解析格式

    1.webapi返回json格式 var json = config.Formatters.JsonFormatter; json.SerializerSettings.PreserveReferen ...

  5. struts2异常处理,global-results定义全局结果处理

    <global-results>定义全局结果处理 一般发生异常之后 结果返回errHandler 因为errHandler是由<global-exception-mappings&g ...

  6. 使用 JSON.parse 反序列化 ISO 格式的日期字符串, 将返回Date格式对象

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  7. 解决nodejs中json序列化时Date类型默认为UTC格式

    在nodejs中,json序列化时Date类型时,默认转为UTC格式. 如下图 上面只是一个例子,下面我用一个更具体化的例子来展示一个这个情况,我们在开发WEB项目中,经常用到Express组件, 我 ...

  8. 解决nodejs中json序列化时Date类型为UTC格式

    在nodejs中,json序列化时Date类型时,默认转为UTC格式. 如下图 zhupengfei@DESKTOP-HJASOE3 MINGW64 /d/MyProject/exp2 $ node ...

  9. Struts2中防止表单重复提交,global-results定义全局结果处理

    1.在表单中加入<s:token/>标签 2.在动作类中加入token的拦截器 <!--如果单单写 name="token" 会丧失 defaultStack 拦 ...

随机推荐

  1. UI图标不用愁:矢量字体图标Font-Awesome

    Font-Awesome,这个项目主要是css3的一个应用,准确的说是一段css,这里的把很多图标的东西做到了font文件里面,然后通过引用外部font文件的方式,来展现图标. Font Awesom ...

  2. LightOj_1079 Just another Robbery

    题目链接 题意: 抢银行(这个背景最爱了), 有n家银行, 每家银行抢劫被抓的概率是p[i],你认为当你被抓的概率低于P的时候是安全的. 问, 你最多能抢劫到多少money. 思路: 抽象成背包问题, ...

  3. ExtJS中动态设置TextField的readOnly属性

    第一种方式: textField, 如果知道textField的id = 'textField' 话,就可以利用如下的方法: 则代码如下:Ext.getCmp("textField" ...

  4. 通过CTAPI和Citect SCADA软件进行数据通讯

    官方文档 Citect SCADA 7.20 Technical Reference 参考文献 基于Citect远程控制的变流量堆料控制系统 [王玉增,顾英妮,王维 济南大学,机械工程学院 ,Cite ...

  5. 区分html与css中的属性

    CSS中id与Class的区别 1.在CSS文件里书写时,ID加前缀"#":CLASS用"." 2.id一个页面只可以使用一次:class可以多次引用. 3.I ...

  6. hadoop的一些重要配置参数

    hadoop集群管理内存设置 Mapreduce内存使用设置 hadoop job重要性能参数

  7. Shoot the Bullet

    zoj3229:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3442 题意:一个摄影师,在n天内给m个女神拍照.每个女神至少要 ...

  8. Javascript禁止网页复制粘贴效果,或者复制时自动添加来源信息

    一.禁止复制 使用方法:在oncopy事件中return false oncopy="return false;" 1.禁止复制网页内容 <body oncopy=" ...

  9. JqueryUI 为什么TypeError: $(...).slides is not a function

    单独写一个html发现一切没有问题,但放在自己的网页中作为一部分却出现了问题,最后发现是那些js文件引入顺序出现了问题,

  10. LeetCode解题报告:LRU Cache

    LRU Cache Design and implement a data structure for Least Recently Used (LRU) cache. It should suppo ...