dwr 自定义转换器
最近开发一个后台应用,之前一般都是使用 AJAX 来进行数据交互。但是项目中使用的是 dwr 来进行前后端交互。本文不是讲如何使用 dwr,而是想分享一下使用 dwr 遇到的问题以及解决问题的思路。 1、什么是 dwrDWR 是一个开源的类库,可以帮助开发人员开发包含AJAX技术的网站.它可以允许在浏览器里的代码(javascript)使用运行在 WEB服务器上的 JAVA 函数,就像它就在浏览器里一样. 它包含两个主要的部分:允许 JavaScript 从 WEB 服务器上一个遵循了 AJAX 原则的 Servlet (小应用程序)中获取数据.另外一方面一个 JavaScript 库可以帮助网站开发人员轻松地利用获取的数据来动态改变网页的内容. dwr 采取了一个类似 AJAX 的新方法来动态生成基于 JAVA 类的 JavaScript 代码.这样 WEB 开发人员就可以在 JavaScript 里使用Java 代码就像它们是浏览器的本地代码(客户端代码)一样;但是 Java 代码运行在 WEB 服务器端而且可以自由访问 WEB 服务器的资源.出于安全的理由,WEB 开发者必须适当地配置哪些 Java 类可以安全的被外部使用. 2、遇到的问题在使用 dwr 的时候,定义了一个接口用于前后端交互。接口的定义如下: Object method(String code,Integer id)
但是在 js 调用的时候,如果我传入空值也就是 但是我就想传到 3、分析问题因为上面有错误提示,我就猜这个异常是 dwr 框架报出的。所以我就 copy 出 这些信息都存在于 dwr jar 包里的 if (paramType == Integer.TYPE || paramType == Integer.class)
{
if (value.length() == 0)
{
return new Integer(0);
}
return new Integer(value.trim());
}
然后看了一下 然后看了一下获取转换器的逻辑: private Converter getConverter(Class paramType)
{
// Can we find a converter assignable to paramType in the HashMap?
Converter converter = getConverterAssignableFrom(paramType);
...
}
private Converter getConverterAssignableFrom(Class paramType)
{
if (paramType == null)
{
return null;
}
String lookup = paramType.getName();
// Can we find the converter for paramType in the converters HashMap?
Converter converter = (Converter) converters.get(lookup);
if (converter != null)
{
return converter;
}
}
它是根据类的类全名 (Integer 对应 然后就看到了 public void addConverter(String match,String type,Map params) {
Class clazz = (Class) converterTypes.get(type);
if (clazz == null){
return;
}
Converter converter = (Converter) clazz.newInstance();
converter.setConverterManager(this);
for (Iterator it = params.entrySet().iterator(); it.hasNext();)
{
Map.Entry entry = (Entry) it.next();
String key = (String) entry.getKey();
Object value = entry.getValue();
try
{
LocalUtil.setProperty(converter,key,value);
}
catch (NoSuchMethodException ex){
...
}
}
// add the converter for the specified match
addConverter(match,converter);
}
public void addConverter(String match,Converter converter) {
// Check that we don't have this one already
Converter other = (Converter) converters.get(match);
if (other != null)
{
log.warn("Clash of converters for " + match + ". Using " + converter.getClass().getName() + " in place of " + other.getClass().getName());
}
converters.put(match,converter);
}
首先会从 converterTypes 里面根据 type,拿到这个对应的 Class。然后以 match 为 key,转换器为 value 保存到 下面是 下面是 通过前面我们可以看到 一共会有两个地方会到 首先 在分析这个配置文件之前我们先来看一下 同样我们可以看到,它也是从 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC "-//GetAhead Limited//DTD Direct Web Remoting 1.0//EN" "http://www.getahead.ltd.uk/dwr/dwr10.dtd">
<dwr>
<init>
<creator id="jsf" class="uk.ltd.getahead.dwr.create.JsfCreator"/>
<creator id="none" class="uk.ltd.getahead.dwr.create.NullCreator"/>
<creator id="new" class="uk.ltd.getahead.dwr.create.NewCreator"/>
<creator id="pageflow" class="uk.ltd.getahead.dwr.create.PageFlowCreator"/>
<creator id="spring" class="uk.ltd.getahead.dwr.create.SpringCreator"/>
<creator id="script" class="uk.ltd.getahead.dwr.create.ScriptedCreator"/>
<creator id="struts" class="uk.ltd.getahead.dwr.create.StrutsCreator"/>
<converter id="null" class="uk.ltd.getahead.dwr.convert.NullConverter"/>
<converter id="enum" class="uk.ltd.getahead.dwr.convert.EnumConverter"/>
<converter id="primitive" class="uk.ltd.getahead.dwr.convert.PrimitiveConverter"/>
<converter id="bignumber" class="uk.ltd.getahead.dwr.convert.BigNumberConverter"/>
<converter id="string" class="uk.ltd.getahead.dwr.convert.StringConverter"/>
<converter id="array" class="uk.ltd.getahead.dwr.convert.ArrayConverter"/>
<converter id="map" class="uk.ltd.getahead.dwr.convert.MapConverter"/>
<converter id="collection" class="uk.ltd.getahead.dwr.convert.CollectionConverter"/>
<converter id="date" class="uk.ltd.getahead.dwr.convert.DateConverter"/>
<converter id="dom" class="uk.ltd.getahead.dwr.convert.DOMConverter"/>
<converter id="dom4j" class="uk.ltd.getahead.dwr.convert.DOM4JConverter"/>
<converter id="jdom" class="uk.ltd.getahead.dwr.convert.JDOMConverter"/>
<converter id="xom" class="uk.ltd.getahead.dwr.convert.XOMConverter"/>
<converter id="servlet" class="uk.ltd.getahead.dwr.convert.ServletConverter"/>
<converter id="bean" class="uk.ltd.getahead.dwr.convert.BeanConverter"/>
<converter id="object" class="uk.ltd.getahead.dwr.convert.ObjectConverter"/>
<converter id="hibernate" class="uk.ltd.getahead.dwr.convert.HibernateBeanConverter"/>
</init>
<allow>
<convert converter="null" match="void"/>
<convert converter="null" match="java.lang.Void"/>
<convert converter="primitive" match="boolean"/>
<convert converter="primitive" match="byte"/>
<convert converter="primitive" match="short"/>
<convert converter="primitive" match="int"/>
<convert converter="primitive" match="long"/>
<convert converter="primitive" match="float"/>
<convert converter="primitive" match="double"/>
<convert converter="primitive" match="char"/>
<convert converter="primitive" match="java.lang.Boolean"/>
<convert converter="primitive" match="java.lang.Byte"/>
<convert converter="primitive" match="java.lang.Short"/>
<convert converter="primitive" match="java.lang.Integer"/>
<convert converter="primitive" match="java.lang.Long"/>
<convert converter="primitive" match="java.lang.Float"/>
<convert converter="primitive" match="java.lang.Double"/>
<convert converter="primitive" match="java.lang.Character"/>
<convert converter="bignumber" match="java.math.BigInteger"/>
<convert converter="bignumber" match="java.math.BigDecimal"/>
<convert converter="string" match="java.lang.String"/>
<convert converter="date" match="java.util.Date"/>
<convert converter="array" match="[Z"/>
<convert converter="array" match="[B"/>
<convert converter="array" match="[S"/>
<convert converter="array" match="[I"/>
<convert converter="array" match="[J"/>
<convert converter="array" match="[F"/>
<convert converter="array" match="[D"/>
<convert converter="array" match="[C"/>
<convert converter="array" match="[L*"/>
<!-- The catch for the next 2 is that we really mean java.util.Collection<String> and java.util.Map<String,String> but we need to do more work before this syntax is enabled -->
<convert converter="collection" match="java.util.Collection"/>
<convert converter="map" match="java.util.Map"/>
<convert converter="dom" match="org.w3c.dom.Node"/>
<convert converter="dom" match="org.w3c.dom.Element"/>
<convert converter="dom" match="org.w3c.dom.Document"/>
<convert converter="dom4j" match="org.dom4j.Document"/>
<convert converter="dom4j" match="org.dom4j.Element"/>
<convert converter="dom4j" match="org.dom4j.Node"/>
<convert converter="jdom" match="org.jdom.Document"/>
<convert converter="jdom" match="org.jdom.Element"/>
<convert converter="xom" match="nu.xom.Document"/>
<convert converter="xom" match="nu.xom.Element"/>
<convert converter="xom" match="nu.xom.Node"/>
<convert converter="servlet" match="javax.servlet.ServletConfig"/>
<convert converter="servlet" match="javax.servlet.ServletContext"/>
<convert converter="servlet" match="javax.servlet.http.HttpServletRequest"/>
<convert converter="servlet" match="javax.servlet.http.HttpServletResponse"/>
<convert converter="servlet" match="javax.servlet.http.HttpSession"/>
</allow>
</dwr>
在 然后 4、解决问题通过上面的的分析,进行转换器添加的时候,也就是调用 所以我们只需要在自定义的配置文件中定义好 Integer 的转换逻辑,然后在覆盖 定义一个 public class MyPrimitiveConverter extends PrimitiveConverter {
@Override
public Object convertInbound(Class paramType,InboundVariable iv,InboundContext inctx) throws ConversionException {
if(paramType == Integer.class || paramType == Integer.TYPE) {
String value = iv.getValue();
if("null".equals(value) || StringUtil.isBlank(value)) {
return null;
}
}
return super.convertInbound(paramType,iv,inctx);
}
}
其实类很简单,就是把 PrimitiveConverter 的逻辑替换成上面的逻辑。 if (paramType == Integer.TYPE || paramType == Integer.class)
{
if (value.length() == 0)
{
return new Integer(0);
}
return new Integer(value.trim());
}
配置自定义解析文件
<?xml version="1.0" encoding="UTF-8"?>
<dwr>
<init>
<converter id="primitive" class="com.weihui.basis.web.config.dwr.MyPrimitiveConverter" />
</init>
</allow>
...
<convert match="java.lang.Integer" converter="primitive" />
</allow>
</dwr>
然后我们再来看一下 ok ! 大功告成。希望这篇 blog 不仅是让你学会了替换 dwr 里面的参数转换器,还能够从我的解决问题的思考方式获得收获。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |