`
white_crucifix
  • 浏览: 95647 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Spring Web Service 简明教程 (三) —— Namespace

阅读更多
    这一章节将会非常非常的简单,因为在前文code上做的修改只有4行。虽然我知道Namespace是个专业的规范,但是我对于wsdl的namespace相关概念太不熟悉了,按照我现在的认知,在这里使用非常鸡肋。

    首先先思考一个场景:在一个Endpoint内,可以有多个方法来接受不同业务的请求。同时, 发起方只传递了一个uri和参数User,因此是如何来确定由具体哪个方法来接收呢?答案就是根节点名(localPart)…… 对于前文的例子来说,接受方法的选择,仅仅依靠的是根节点名user,更重要的是对于哪个Endpoint实现类的选择也是没有的。换句话说,不管你按照业务分了多少个endpoint,每个endpoint中分了多少个方法,这些方法就好像扔进了一个水池里,是混在一起的,而你只能通过根节点名选择执行的方法,这样,就不能有两个相同根节点名的方法并存。这样的局面我并不能接受。
  
    所以我开始研究namespace的用法,但是结果依然让我失望,namespace也无法帮助我选择endpoint的方法。以下,我们先修改代码,看看namespace最最简单的用法是什么样的吧。

    首先,修改User.java,在类名前加上namespace的注解
@XmlRootElement(name = "user",namespace = "http://mycompany.com/hr/schemas")

    然后,在每一个属性的setter前也加入注解
@XmlElement(namespace = "http://mycompany.com/hr/schemas")
public void setId(int id) { this.id = id; }

@XmlElement(namespace = "http://mycompany.com/hr/schemas")
public void setName(String name) { this.name = name; }

      说明:注解本身,顾名思义,无需解释。这里有几个注意点:

               1. 属性的注解为什么要加在setter上?只要在类名前加上@XmlAccessorType(XmlAccessType.FIELD),就可以直接在属性上加注解了。

               2. 为什么要在类名和属性上反复写相同的namespace?可以只在类名前加,但是转换成XML以后的字符串会有不同。简单的场景下,两种都兼容,但是我后面需要实现一个特性,而这个特性要求我这么做。这也是让我很不爽的地方。

               3. namespace的值有什么要求吗?还记得在user.xsd中定义的targetNamespace吗?嗯,当然不需要一致,而这里写成一致,对后面也是有帮助的,所以就这么着吧。但是一定要和@Endpoint中的namespace属性一致,这个后面会贴出来。

      UserEndpoint.java
@PayloadRoot(localPart = "user", namespace = "http://mycompany.com/hr/schemas")
    @ResponsePayload
    public User handle(@RequestPayload User user) throws Exception {

      添加了namespace属性,无需多说,没什么需要注意的。

      使用第二章的第二个测试方法testSourceSend()进行测试,在请求参数转换后,打一句输出语句,就能看到添加了namespace后的User会转换成什么样子。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<user xmlns="http://mycompany.com/hr/schemas">
<id>1</id>
<name>chenzhouce</name>
</user>

      干脆贴出不在属性上加注解后转换的效果吧:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:user xmlns:ns2="http://mycompany.com/hr/schemas">
<id>1</id>
<name>chenzhouce</name>
</ns2:user>

      这两种形式在现在的case中都是能通过的,至于含义上的区别,这里就不讲了,麻烦,也讲不太清楚。

      这就是最简单的namespace使用,如果client端和server端有一处没有配置,或者两处不一致,就不能通过,server端会出现No endpoint mapping found的警告。

      回过头,之所以说namespace鸡肋,是因为它虽然也是用来endpoint执行方法选择的,但是在与jaxb2直接转换的配合中,完全和localPart重复了,因为一个User就对应了主namespace.....

     我也找过有没有没注意的地方,但是没有找到,而且大把的时间其实是花在了一个坑上。。这个坑我一定会在后面说的。。。我觉得namespace一定有它应该存在的规范,只是我不知道。。

     代码提交到github上了,传送门:
https://github.com/chenzhouce/spring-webservice-demo/blob/Section_Namespace/src/main/java/com/zchen/User.java
注意:我放在了一个branch里Section_Namespace。前章节的内容依然在Master分支。
0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics