#
actionMessage怎么能保存到session中哪!!太占用服务器资源了。防止刷新比较好的办法是利用token来解决就可以了阿:
就你的情况来看我给你举个例子
在Action中的add方法中,我们需要将Token值明确的要求保存在页面中,只需增加一条语句:saveToken(request);,如下所示:
public ActionForward add(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
//前面的处理省略
saveToken(request);
//转发到需要录入信息的页面
return mapping.findForward("add");
}
在Action的insert方法中,我们根据表单中的Token值与服务器端的Token值比较,如下所示:
//处理信息录入的action
public ActionForward insert(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
if (isTokenValid(request, true)) {
// 表单不是重复提交正常执行
} else {
//表单重复提交
saveToken(request);
//给客户端提示错误,当然这里也就是你把ActionMessages保存到request范围内,然后forward到错误页面
}
}
执行的流程:add(Action)->信息录入页面(jsp)->insert(Action)
综上,其实你选择重定向到页面无非就是为了让request失效保证不能重复提交,而恰恰你的错误信息又是保存到了request范围内了,所以呵呵出现问题了,利用token来解决这个问题吧
了,至于token我再lz解释一下:
Struts的Token机制能够很好的解决表单重复提交的问题,基本原理是:服务器端在处理到达的请求之前,会将请求中包含的令牌值与保存在当前用户会话中的令牌值进行比较,看是否匹配。在处理完该请求后,且在答复发送给客户端之前,将会产生一个新的令牌,该令牌除传给客户端以外,也会将用户会话中保存的旧的令牌进行替换。这样如果用户回退到刚才的提交页面并再次提交的话,客户端传过来的令牌就和服务器端的令牌不一致,从而有效地防止了重复提交的发生。
这时其实也就是两点,第一:你需要在请求中有这个令牌值,请求中的令牌值如何保存,其实就和我们平时在页面中保存一些信息是一样的,通过隐藏字段来保存,保存的形式如: 〈input type="hidden" name="org.apache.struts.taglib.html.TOKEN" value="6aa35341f25184fd996c4c918255c3ae"〉,这个value是TokenProcessor类中的generateToken()获得的,是根据当前用户的session id和当前时间的long值来计算的。第二:在客户端提交后,我们要根据判断在请求中包含的值是否和服务器的令牌一致,因为服务器每次提交都会生成新的Token,所以,如果是重复提交,客户端的Token值和服务器端的Token值就会不一致。
http://www.oracle.com/technology/sample_code/tech/java/codesnippet/webservices/attachment/index.html
http://www.ibm.com/developerworks/xml/library/x-tippass.html
From:http://www.ibm.com/developerworks/webservices/library/ws-whichwsdl/
A Web Services Description Language (WSDL) binding style can be RPC or document. The use can be encoded or literal. How do you determine which combination of style and use to use? The author describes the WSDL and SOAP messages for each combination to help you decide.
Introduction
A WSDL document describes a Web service. A WSDL binding describes how the service is bound to a messaging protocol, particularly the SOAP messaging protocol. A WSDL SOAP binding can be either a Remote Procedure Call (RPC) style binding or a document style binding. A SOAP binding can also have an encoded use or a literal use. This gives you four style/use models:
- RPC/encoded
- RPC/literal
- Document/encoded
- Document/literal
Add to this collection a pattern which is commonly called the document/literal wrapped pattern and you have five binding styles to choose from when creating a WSDL file. Which one should you choose?
Before I go any further, let me clear up some confusion that many of us have stumbled over. The terminology here is very unfortunate: RPC versus document. These terms imply that the RPC style should be used for RPC programming models and that the document style should be used for document or messaging programming models. That is not the case at all. The style has nothing to do with a programming model. It merely dictates how to translate a WSDL binding to a SOAP message. Nothing more. You can use either style with any programming model.
Likewise, the terms encoded and literal are only meaningful for the WSDL-to-SOAP mapping, though, at least here, the traditional meanings of the words make a bit more sense.
For this discussion, let's start with the Java method in Listing 1 and apply the JAX-RPC Java-to-WSDL rules to it (see Resources for the JAX-RPC 1.1 specification).
Listing 1. Java method
public void myMethod(int x, float y);
|
RPC/encoded
Take the method in Listing 1 and run it through your favorite Java-to-WSDL tool, specifying that you want it to generate RPC/encoded WSDL. You should end up with something like the WSDL snippet in Listing 2.
Listing 2. RPC/encoded WSDL for myMethod
<message name="myMethodRequest">
<part name="x" type="xsd:int"/>
<part name="y" type="xsd:float"/>
</message>
<message name="empty"/>
<portType name="PT">
<operation name="myMethod">
<input message="myMethodRequest"/>
<output message="empty"/>
</operation>
</portType>
<binding .../>
<!-- I won't bother with the details, just assume it's RPC/encoded. -->
|
Now invoke this method with "5" as the value for parameter x
and "5.0" for parameter y
. That sends a SOAP message which looks something like Listing 3.
Listing 3. RPC/encoded SOAP message for myMethod
<soap:envelope>
<soap:body>
<myMethod>
<x xsi:type="xsd:int">5</x>
<y xsi:type="xsd:float">5.0</y>
</myMethod>
</soap:body>
</soap:envelope>
|
|
A note about prefixes and namespaces
For the most part, for brevity, I ignore namespaces and prefixes in the listings in this article. I do use a few prefixes that you can assume are defined with the following namespaces:
- xmlns:xsd="http://www.w3.org/2001/XMLSchema"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
For a discussion about namespaces and the WSDL-to-SOAP mapping, see paper "Handle namespaces in SOAP messages you create by hand" (see Resources).
|
|
There are a number of things to notice about the WSDL and SOAP message for this RPC/encoded example:
Strengths
- The WSDL is about as straightforward as it's possible for WSDL to be.
- The operation name appears in the message, so the receiver has an easy time dispatching this message to the implementation of the operation.
Weaknesses
|
WS-I compliance
The various Web services specifications are sometimes inconsistent and unclear. The WS-I organization was formed to clear up the issues with the specs. It has defined a number of profiles which dictate how you should write your Web services to be interoperable. For more information on WS-I, see the WS-I links in Resources.
|
|
- The type encoding info (such as
xsi:type="xsd:int"
) is usually just overhead which degrades throughput performance.
- You cannot easily validate this message since only the
<x ...>5</x>
and <y ...>5.0</y>
lines contain things defined in a schema; the rest of the soap:body
contents comes from WSDL definitions.
- Although it is legal WSDL, RPC/encoded is not WS-I compliant.
Is there a way to keep the strengths and remove the weaknesses? Possibly. Let's look at the RPC/literal style.
RPC/literal
The RPC/literal WSDL for this method looks almost the same as the RPC/encoded WSDL (see Listing 4). The use in the binding is changed from encoded to literal. That's it.
Listing 4. RPC/literal WSDL for myMethod
<message name="myMethodRequest">
<part name="x" type="xsd:int"/>
<part name="y" type="xsd:float"/%gt;
</message>
<message name="empty"/>
<portType name="PT">
<operation name="myMethod">
<input message="myMethodRequest"/>
<output message="empty"/>
</operation>
</portType>
<binding .../>
<!-- I won't bother with the details, just assume it's RPC/literal. -->
|
What about the SOAP message for RPC/literal (see Listing 5)? Here there is a bit more of a change. The type encodings have been removed.
Listing 5. RPC/literal SOAP message for myMethod
<soap:envelope>
<soap:body>
<myMethod>
<x>5</x>
<y>5.0</y>
</myMethod>
</soap:body>
</soap:envelope>
|
|
A note about xsi:type and literal use
Although in normal circumstances xsi:type does not appear in a literal WSDL's SOAP message, there are still cases when type information is necessary and it will appear -- in polymorphism, for instance. If the API expects a base type and an extension instance is sent, the type of that instance must be provided for proper deserialization of the object.
|
|
Here are the strengths and weaknesses of this approach:
Strengths
- The WSDL is still about as straightforward as it is possible for WSDL to be.
- The operation name still appears in the message.
- The type encoding info is eliminated.
- RPC/literal is WS-I compliant.
Weaknesses
- You still cannot easily validate this message since only the
<x ...>5</x>
and <y ...>5.0</y>
lines contain things defined in a schema; the rest of the soap:body
contents comes from WSDL definitions.
What about the document styles? Do they help overcome this weakness?
Document/encoded
Nobody follows this style. It is not WS-I compliant. So let's move on.
Document/literal
The WSDL for document/literal changes somewhat from the WSDL for RPC/literal. The differences are highlighted in bold in Listing 6.
Listing 6. Document/literal WSDL for myMethod
<types>
<schema>
<element name="xElement" type="xsd:int"/>
<element name="yElement" type="xsd:float"/>
</schema>
</types>
<message name="myMethodRequest">
<part name="x" element="xElement"/>
<part name="y" element="yElement"/>
</message>
<message name="empty"/>
<portType name="PT">
<operation name="myMethod">
<input message="myMethodRequest"/>
<output message="empty"/>
</operation>
</portType>
<binding .../>
<!-- I won't bother with the details, just assume it's document/literal. -->
|
The SOAP message for this WSDL is in Listing 7:
Listing 7. Document/literal SOAP message for myMethod
<soap:envelope>
<soap:body>
<xElement>5</xElement>
<yElement>5.0</yElement>
</soap:body>
</soap:envelope>
|
|
A note about the message part
I could have changed only the binding, as I did from RPC/encoded to RPC/literal. It would have been legal WSDL. However, the WS-I Basic Profile dictates that document/literal message parts refer to elements rather than types, so I'm complying with WS-I. (And using an element part here leads well into the discussion about the document/literal wrapped pattern.)
|
|
Here are the strengths and weaknesses of this approach:
Strengths
- There is no type encoding info.
- You can finally validate this message with any XML validator. Everything within the
soap:body
is defined in a schema.
- Document/literal is WS-I compliant, but with restrictions (see weaknesses).
Weaknesses
- The WSDL is getting a bit more complicated. This is a very minor weakness, however, since WSDL is not meant to be read by humans.
- The operation name in the SOAP message is lost. Without the name, dispatching can be difficult, and sometimes impossible.
- WS-I only allows one child of the
soap:body
in a SOAP message. As you can see in Listing 7, this example's soap:body
has two children.
The document/literal style seems to have merely rearranged the strengths and weaknesses from the RPC/literal model. You can validate the message, but you lose the operation name. Is there anything you can do to improve upon this? Yes. It's called the document/literal wrapped pattern.
Document/literal wrapped
Before I describe the rules for the document/literal wrapped pattern, let me show you the WSDL and the SOAP message in Listing 8 and Listing 9.
Listing 8. Document/literal wrapped WSDL for myMethod
<types>
<schema>
<element name="myMethod">
<complexType>
<sequence>
<element name="x" type="xsd:int"/>
<element name="y" type="xsd:float"/>
</sequence>
</complexType>
</element>
<element name="myMethodResponse">
<complexType/>
</element>
</schema>
</types>
<message name="myMethodRequest">
<part name="parameters" element="myMethod"/>
</message>
<message name="empty">
<part name="parameters" element="myMethodResponse"/>
</message>
<portType name="PT">
<operation name="myMethod">
<input message="myMethodRequest"/>
<output message="empty"/>
</operation>
</portType>
<binding .../>
<!-- I won't bother with the details, just assume it's document/literal. -->
|
The WSDL schema now has a wrapper around the parameters (see Listing 9).
Listing 9. Document/literal wrapped SOAP message for myMethod
<soap:envelope>
<soap:body>
<myMethod>
<x>5</x>
<y>5.0</y>
</myMethod>
</soap:body>
</soap:envelope>
|
Notice that this SOAP message looks remarkably like the RPC/literal SOAP message in Listing 5. You might say it looks exactly like the RPC/literal SOAP message, but there's a subtle difference. In the RPC/literal SOAP message, the <myMethod>
child of <soap:body>
was the name of the operation. In the document/literal wrapped SOAP message, the <myMethod>
clause is the name of the wrapper element which the single input message's part refers to. It just so happens that one of the characteristics of the wrapped pattern is that the name of the input element is the same as the name of the operation. This pattern is a sly way of putting the operation name back into the SOAP message.
These are the basic characteristics of the document/literal wrapped pattern:
- The input message has a single part.
- The part is an element.
- The element has the same name as the operation.
- The element's complex type has no attributes.
Here are the strengths and weaknesses of this approach:
Strengths
- There is no type encoding info.
- Everything that appears in the
soap:body
is defined by the schema, so you can easily validate this message.
- Once again, you have the method name in the SOAP message.
- Document/literal is WS-I compliant, and the wrapped pattern meets the WS-I restriction that the SOAP message's
soap:body
has only one child.
Weaknesses
- The WSDL is even more complicated.
As you can see, there is still a weakness with the document/literal wrapped pattern, but it's minor and far outweighed by the strengths.
|
RPC/literal wrapped?
From a WSDL point of view, there's no reason the wrapped pattern is tied only to document/literal bindings. It could just as easily be applied to an RPC/literal binding. But this would be rather silly. The SOAP message would contain a myMethod element for the operation and a child myMethod element for the element name. Also, even though it's legal WSDL, an RPC/literal part should be a type; an element part is not WS-I compliant.
|
|
Where is doc/lit wrapped defined?
This wrapped style originates from Microsoft®. There is no specification that defines this style; so while this style is a good thing, unfortunately, the only choice right now, in order to interoperate with Microsoft's and other's implementations, is to make educated guesses as to how it works based on the output of the Microsoft WSDL generator. This pattern has been around for awhile, and the industry has done a good job of understanding it, but while the pattern is fairly obvious in this example, there are corner cases in which the proper thing to do is not particularly clear. Our best hope is that an independent group like the WS-I organization will help stabilize and standardize this in the future.
Why not use document/literal wrapped all the time?
So far, this article has given the impression that the document/literal wrapped style is the best approach. Very often that's true. But there are still cases where you'd be better off using another style.
Reasons to use document/literal non-wrapped
If you have overloaded operations, you cannot use the document/literal wrapped style.
Imagine that, along with the method you've been using all along, you have the additional method in Listing 10.
Listing 10. Problem methods for document/literal wrapped
public void myMethod(int x, float y);
public void myMethod(int x);
|
|
A note about overloaded operations
WSDL 2.0 will not allow overloaded operations. This is unfortunate for languages like the Java language which do allow them. Specs like JAX-RPC will have to define a name mangling scheme to map overloaded methods to WSDL. WSDL 2.0 merely moves the problem from the WSDL-to-SOAP mapping to the WSDL-to-language mapping.
|
|
WSDL allows overloaded operations. But when you add the wrapped pattern to WSDL, you require an element to have the same name as the operation, and you cannot have two elements with the same name in XML. So you must use the document/literal, non-wrapped style or one of the RPC styles.
Reasons to use RPC/literal
Since the document/literal, non-wrapped style doesn't provide the operation name, there are cases where you'll need to use one of the RPC styles. For instance, say you have the set of methods in Listing 11.
Listing 11. Problem methods for document/literal non-wrapped
public void myMethod(int x, float y);
public void myMethod(int x);
public void someOtherMethod(int x, float y);
|
Now assume that your server receives the document/literal SOAP message that you saw back in Listing 7. Which method should the server dispatch to? All you know for sure is that it's not myMethod(int x)
because the message has two parameters and this method requires one. It could be either of the other two methods. With the document/literal style, you have no way to know which one.
Instead of the document/literal message, assume that the server receives an RPC/literal message such as the one in Listing 5. With this message it's fairly easy for a server to decide which method to dispatch to. You know the operation name is myMethod, and you know you have two parameters, so it must be myMethod(int x, float y)
.
Reasons to use RPC/encoded
The primary reason to prefer the RPC/encoded style is for data graphs. Imagine that you have a binary tree whose nodes are defined in Listing 12.
Listing 12. Binary tree node schema
<complexType name="Node">
<sequence>
<element name="name" type="xsd:string"/>
<element name="left" type="Node" xsd:nillable="true"/>
<element name="right" type="Node" xsd:nillable="true"/>
</sequence>
</complexType>
|
With this node definition, you could construct a tree whose root node -- A -- points to node B through both its left and right links (see Figure 1).
Figure 1. Encoded tree.
The standard way to send data graphs is to use the href tag, which is part of the RPC/encoded style (Listing 13).
Listing 13. The RPC/encoded binary tree
<A>
<name>A</name>
<left href="12345"/>
<right href="12345"/>
</A>
<B id="12345">
<name>B</name>
<left xsi:nil="true"/>
<right xsi:nil="true"/>
</B>
|
Under any literal style, the href attribute is not available, so the graph linkage is lost (see Listing 14 and Figure 2). You still have a root node, A, which points to a node B to the left and another node B to the right. These B nodes are equal, but they are not the same node. Data have been duplicated instead of being referenced twice.
Listing 14. The literal binary tree
<A>
<name>A</name>
<left>
<name>B</name>
<left xsi:nil="true"/>
<right xsi:nil="true"/>
</left>
<right>
<name>B</name>
<left xsi:nil="true"/>
<right xsi:nil="true"/>
</right>
</A>
|
Figure 2. Literal tree
There are various ways you can do graphs in literal styles, but there are no standard ways; so anything you might do would probably not interoperate with the service on the other end of the wire.
SOAP response messages
So far I have been discussing request messages. But what about response messages? What do they look like? By now it should be clear to you what the response message looks like for a document/literal message. The contents of the soap:body
are fully defined by a schema, so all you have to do is look at the schema to know what the response message looks like. For instance, see Listing 15 for the response for the WSDL in Listing 8.
Listing 15. document/literal wrapped response SOAP message for myMethod
<soap:envelope>
<soap:body>
<myMethodResponse/>
</soap:body>
</soap:envelope>
|
But what is the child of the soap:body
for the RPC style responses? The WSDL 1.1 specification is not clear. But WS-I comes to the rescue. WS-I's Basic Profile dictates that in the RPC/literal response message, the name of the child of soap:body
is "... the corresponding wsdl:operation
name suffixed with the string 'Response'." Surprise! That's exactly what the conventional wrapped pattern's response element is called. So Listing 15 applies to the RPC/literal message as well as the document/literal wrapped message. (Since RPC/encoded is not WS-I compliant, the WS-I Basic Profile doesn't mention what an RPC/encoded response looks like, but you can assume the same convention applies here that applies everywhere else.) So the contents of response messages are not so mysterious after all.
Summary
There are four binding styles (there are really five, but document/encoded is meaningless). While each style has its place, under most situations the best style is document/literal wrapped.
Resources
About the author
|
|
|
Russell Butek is an SOA and Web services consultant for IBM. He has been one of the developers of IBM WebSphere Web services engine. He has also been a member the JAX-RPC Java Specification Request (JSR) expert group. He was involved in the implementation of Apache's AXIS SOAP engine, driving AXIS 1.0 to comply with JAX-RPC 1.0.
|
Axis 中使用WSDL文件的详细介绍
<deployment>:告诉Axis Engine这是一个部署描述文件。一个部署描述文件可以表示一个完整的engine配置或者将要部署到一个活动active的一部分组件。
<GlobalConfiguration>:用于控制engine范围的配置。可以包含以下子元素:
· <parameter> : 用来设置Axis的各种属性,参考Global Axis Configuration,可以配置任意数量的参数元素.
· <role> : 设置一个SOAP actor/role URI,engine可以对它进行识别。这允许指向这个role的SOAP headers成功的被engine处理。任意数量.
· <requestFlow> : 全局的请求Handlers。在调用实际的服务之前调用.
· <responseFlow> : 全局响应Handlers,在调用完实际的服务后,还没有返回到客户端之前调用.
<requestFlow [name="name"] [type="type"] >可以放置任意多个<handler> or <chain>在<requestFlow>中,但是可能只有一个<requestFlow>.
<responseFlow [name="name"] [type="type"] >可以放置任意多个<handler> or <chain>在< responseFlow >中,但是可能只有一个< responseFlow >.
<undeployment>部署文档的根元素,用于指示Axis这是个卸载描述文件.
<handler [name="name"] type="type">位于顶层元素<deployment> or <undeployment>, or inside a <chain>, <requestFlow>, or <responseFlow>. 用于定义Handler,并定义handler的类型。"Type" 可以是已经定义的Handler或者是"java:class.name"形式的QName。可选的"name"属性允许将这个Handler的定义在其他部署描述部分中引用。可以包含任意数量的<parameter name="name" value="value">元素.
<service name="name" provider="provider" >部署/卸载一个Axis服务。这是最复杂的一个WSDD标签。Options可能通过以下元素来指定: <parameter name="name" value="value"/>, 一些常用的包括:· className : 后台实现的类 allowedMethods : 每个provider可以决定那些方法允许web services访问
Axis支持的providers有如下几种:
Java RPC Provider (provider="java:RPC") 默认情况下所有的public方法都可以web service方式提供Java MsgProvder (provider="java:MSG") 为了更进一步的限制上面的方法,allowedMethods选项用于指定一个以空格分隔的方法名,只有这些方法可以通过web service访问。也可以将这个值指定为”*”表示所有的方法都可以访问。同时operation元素用来更进一步的定义被提供的方法,但是它不能决定方法的可见性. 注意,发布任何web service都有安全含义.
· allowedRoles : 都好分离的允许访问服务的角色列表。注意,这些是安全角色,和SOAP角色相反。安全角色控制访问,SOAP角色控制哪些SOAPheaders会被处理。
· extraClasses : 指定一个空格或者都好分离的类名称列表,这些类的名字应该被包含在WSDL文档的类型定义部分。当服务接口引用一个基类的时候,或者希望WSDL文件包含其他类的XML Schema类型定义的时候,这个参数很有用。
如果希望为服务定义handler,可以在<service>元素中添加<requestFlow>和<responseFlow>子元素。他们的语义和<chain>元素中的定义时一样的。也就是说,它们可以包含<handler> and <chain> 元素,根据指定的顺序被调用.
通过服务的Handlers来控制角色,可以在服务声明中指定任意数量的<role>元素。
例如:
<service name="test">
<parameter name="className" value="test.Implementation"/>
<parameter name="allowedMethods" value="*"/>
<namespace>http://testservice/</namespace>
<role>http://testservice/MyRole</role>
<requestFlow> <!-- Run these before processing the request -->
<handler type="java:MyHandlerClass"/>"
<handler type="somethingIDefinedPreviously"/>
</requestFlow>
</service>
|
可以通过使用<operation>标签指定关于服务的特殊操作的元数据。这可以将方法的java参数名和特定的XML名进行映射,为参数指定特定的模式,并将特定的XML名字映射到特定的操作。例如
<operation name="method"> </operation>
<chain name="name"><subelement/>...</chain>
定义一个链。当chain被调用的时候,按顺序调用其中的handler。这样就可以构建一个常用功能的模块,chain元素的子元素可以是handler或者chain。handler的定义形式可以是如下两种方式:
<chain name="myChain">
<handler type="java:org.apache.axis.handlers.LogHandler"/>
</chain>
或者
<handler name="logger" type="java:org.apache.axis.handlers.LogHandler"/>
<chain name="myChain"/>
<handler type="logger"/>
</chain>
<transport name="name">
|
定义了一个服务器端的传输。当一个输入请求到达的时候,服务器传输被调用。服务器传输可能定义<requestFlow> and/or <responseFlow> 元素来指定handlers/chains,在请求和响应被处理的时候被调用,这个功能和service元素中的功能一样。典型的传输请求响应handler实现了关于传输的功能。例如转换协议headers等等.
对于任何种类的传输,经常是指HTTP传输,当特定的查询字符串传递到servlet的时候用户可能允许Axis servlets执行任意的动作,以plug-in的方式。 (参考Axis Servlet Query String Plug-ins).当查询字符串handler的类名被指导后,用户可以通过在<transport>中添加合适的<parameter>来启用它(插件)。
<transport name="http">
<parameter name="useDefaultQueryStrings" value="false" />
<parameter name="qs.name" value="class.name" />
</transport>
|
在上面的例子中,AxisServlet会处理的查询字符串是?name,它调用的类是class.name。
<parameter>元素的name属性必须加上前缀qs来表示这个元素定义了一个查询字符串handler。value属性值相实现了org.apache.axis.transport.http.QSHandler 接口的类。默认情况下,Axis提供了三个Axis servlet查询字符串handlers (?list, ?method, and ?wsdl). 查看Axis服务器配置文件来了解它们的定义。如果不希望使用默认的handlers,就设置"useDefaultQueryStrings" 为false。默认会被设置成true.
<transport name="name" pivot="handler type" >
定义了一个客户端的传输,当发送SOAP消息的时候来调用。"pivot"属性指定一个Handler来作为实际的传输sender,例如HTTPSender。请求和响应流和服务器端的设置相同. <typeMapping qname="ns:localName" classname="classname" serializer="classname" deserializer="classname"/> 每个typeMapping将一个XML qualified名字和一个Java类进行映射,使用一个序列器和反序列器。
<beanMapping qname="ns:localName" classname="classname">讲话的类型映射,使用一个预定义的序列器/反序列器来编码/解码JavaBeans。
<documentation>在<service>, <operation> 或者操作的<parameter>中使用。.是文档说明,生成wsdl的<wsdl:document>元素.
Example:
<operation name="echoString" >
<documentation>This operation echoes a string</documentation>
<parameter name="param">
<documentation>a string</documentation>
</parameter>
</operation>
|
全局的Axis配置参数
服务默认的是通过server-config.wsdd文件中的值来进行配置的。但是熟练的Axis用户可以写自己的配置handler,这样就可以将配置数据保存在LDAP服务器,数据库或者远程的web service等等。查看源代码来了解如何实现。也可以在web.xml文件中使自动的获取配置信息。但是Axis不推荐这样使用,因为最好将配置信息放在一个位置。
在server-config文件中,有一个全局配置部分,支持以名/值对的形式作为嵌套元素使用。
<globalConfiguration>
<parameter name="adminPassword" value="admin"/>
<parameter name="axis.servicesPath" value="/services/"/>
<parameter name="attachments.Directory" value="c:"temp"attachments"/>
<parameter name="sendMultiRefs" value="true"/>
<parameter name="sendXsiTypes" value="true"/>
<parameter name="attachments.implementation" value="org.apache.axis.attachments.AttachmentsImpl"/>
<parameter name="sendXMLDeclaration" value="true"/>
<parameter name="enable2DArrayEncoding" value="true"/>
<parameter name="dotNetSoapEncFix" value="false"/>
</globalConfiguration>
|
单独的Service(服务)配置
<service name="MyServiceName"
provider="java:RPC"
style="rpc|document|wrapped"
use="encoded|literal"
streaming="off|on"
attachment="MIME|DIME|NONE">
<parameter name="className" value="org.apache.mystuff.MyService"/>
<parameter name="allowedMethods" value="method1 method2 method3"/>
<parameter name="wsdlTargetNamespace" value="http://mystuff.apache.org/MyService"/>
<parameter name="wsdlServiceElement" value="MyService"/>
<parameter name="wsdlServicePort" value="MyServicePort"/>
<parameter name="wsdlPortType" value="MyPort"/>
<parameter name="wsdlSoapActionMode" value="NONE|DEFAULT|OPERATION"/>
<parameter name="SingleSOAPVersion" value="1.1|1.2/>
<documentation>Service level info</documentation>
<endpointURL>http://example.com:5050/my/custom/url/to/service</endpointURL>
<wsdlFile>/path/to/wsdl/file</wsdlFile>
<namespace>http://my.namespace.com/myservice</namespace>
<handlerInfoChain>handlerChainName</handlerInfoChain>
<operation ... />
<typeMapping ... />
<beanMapping ... />
</service>
|
单独的Operation(操作)配置
<operation name="GetQuote"
qname="operNS:GetQuote"
returnQName="GetQuoteResult"
returnType="xsd:float"
soapAction=""
returnHeader="true|false">
<documentation>Operation level documentation here</documentation>
<parameter name="ticker" type="tns:string"/>
<fault name="InvalidTickerFaultMessage"
qname="tickerSymbol"
class="test.wsdl.faults.InvalidTickerFaultMessage"
type="xsd:string"/>
</operation>
|
由于Service的配置和Operation的配置很容易理解,各个参数也都使用了self-explanation的表示,所以这里就不再赘述了。
同时Axis还定义日志配置以及一些预定义的Handler,详细内容,参考Axis的参考文档。
From:http://gocom.primeton.com/blog9288_29578.htm
http://dev.21tx.com/2005/07/14/13017.html
摘要: WSDL
<definitions
name="HelloWorld"
targetNamespace="http://xmlns.oracle.com/HelloWorld"
xmlns="http:...
阅读全文
一个 XML schema 中 elementFormDefault="?" 这一属性用来指示 XML Schema 处理程序把这个 XML schema 中定义的元素或者类型放到哪个命名空间。
一个schema中声明的元素或者类型只能归到两个命名空间中的某一个去,这两个是,无名命名空间和由targetSchema属性指明的目标命名空间。而targetSchema属性只能在xs:schema的定义中声明,因而,一个schema中的定义的元素或类型只可能归属于一个有名命名空间(但是还有可能归属于无名命名空间)。
当elementFormDefault="qualified" 时,所有全局元素的子元素将被以缺省方式放到目标命名空间,连同全局元素或者类型将被放到目标命名空间;而当elementFormDefault="unqualified" 时,所有全局元素的子元素将被以缺省方式放到无名命名空间。而属性的命名空间类似地由attributeFormDefault="?"来指明。
需要明白的是,elementFormDefault="?" 是有作用域的,并且是被继承的,除非在子定义中覆盖父定义。
下面三个例子说明了elementFormDefault的使用效果。红色表示属于已命名空间的元素,蓝色表示属于未命名空间的元素。
1.定义了目标命名空间, 全局elementFormDefault=“unqualified”。这时除了全局元素或者类型将归于目标命名空间外,局部元素将归于无名命名空间。
unqualified.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="aaaa" elementFormDefault="unqualified" attributeFormDefault="unqualified">
<xs:element name="c">
<xs:complexType>
<xs:sequence>
<xs:element name="c1" type="xs:double"/>
<xs:element name="c2" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
unqualified.xml
<?xml version="1.0" encoding="UTF-8"?>
<n:c xmlns:n="aaaa" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="aaaa unqualified.xsd">
<c1>3.141593E0</c1>
<c2>String</c2>
</n:c>
2. 定义了目标命名空间, 全局elementFormDefault=“qualified”。这时全局元素或者类型将归于目标命名空间,局部元素将以缺省方式归于目标命名空间。
qualified.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="aaaa" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="c">
<xs:complexType>
<xs:sequence>
<xs:element name="c1" type="xs:double"/>
<xs:element name="c2" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
qualified.xml
<?xml version="1.0" encoding="UTF-8"?>
<c xmlns="aaaa" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="aaaa qualified.xsd">
<c1>3.141593E0</c1>
<c2>String</c2>
</c>
3. 定义了目标命名空间, 全局elementFormDefault=“unqualified”。这时全局元素(c)或者类型将归于目标命名空间。局部元素(c1,c2)以缺省方式归于无名命名空间。局部元素(c3)在局部定义中使用form=“qualified”覆盖全局设定的 unqualified,这使得c3归于目标命名空间(如果它有子元素,子元素将以缺省方式归于目标命名空间)。
qualified2.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="aaaa" elementFormDefault="unqualified" attributeFormDefault="unqualified">
<xs:element name="c">
<xs:complexType>
<xs:sequence>
<xs:element name="c1" type="xs:double"/>
<xs:element name="c2" type="xs:string"/>
<xs:element name="c3" type="xs:integer" form="qualified"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
qualified2.xml
<?xml version="1.0" encoding="UTF-8"?>
<n:c xmlns:n="aaaa" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="aaaa qualified2.xsd">
<c1>3.141593E0</c1>
<c2>String</c2>
<n:c3>0</n:c3>
</n:c>
[FROM]http://bbs.w3china.org/dispbbs.asp?BoardID=23&replyID=19004&id=25672&star=1&skin=0
我们知道,在关系数据库标准中有四个事务隔离级别:
未提交读(Read Uncommitted):允许脏读,也就是可能读取到其他会话中未提交事务修改的数据
提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别
可重复读(Repeated Read):可重复读。在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别。在SQL标准中,该隔离级别消除了不可重复读,但是还存在幻象读
串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞
查看InnoDB系统级别的事务隔离级别:
mysql> SELECT @@global.tx_isolation;
+-----------------------+
| @@global.tx_isolation |
+-----------------------+
| REPEATABLE-READ |
+-----------------------+
1 row in set (0.00 sec)
查看InnoDB会话级别的事务隔离级别:
mysql> SELECT @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.00 sec)
修改事务隔离级别:
mysql> set global transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)
mysql> set session transaction isolation level read committed;
Query OK, 0 rows affected (0.00 sec)
InnoDB的可重复读隔离级别和其他数据库的可重复读是有区别的,不会造成幻象读(phantom read),所谓幻象读,就是同一个事务内,多次select,可以读取到其他session insert并已经commit的数据。下面是一个小的测试,证明InnoDB的可重复读隔离级别不会造成幻象读。测试涉及两个session,分别为session 1和session 2,隔离级别都是repeateable read,关闭autocommit
mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.00 sec)
mysql> set autocommit=off;
Query OK, 0 rows affected (0.00 sec)
session 1 创建表并插入测试数据
mysql> create table test(i int) engine=innodb;
Query OK, 0 rows affected (0.00 sec)
mysql> insert into test values(1);
Query OK, 1 row affected (0.00 sec)
session 2 查询,没有数据,正常,session1没有提交,不允许脏读
mysql> select * from test;
Empty set (0.00 sec)
session 1 提交事务
mysql> commit;
Query OK, 0 rows affected (0.00 sec)
session 2 查询,还是没有数据,没有产生幻象读
mysql> select * from test;
Empty set (0.00 sec)
以上试验版本:
mysql> select version();
+-------------------------+
| version() |
+-------------------------+
| 5.0.37-community-nt-log |
+-------------------------+
1 row in set (0.00 sec)
--EOF--
From:http://bbs.itren.cn/html/bbs41739.html
第1章 SQL语句处理的过程 在调整之前我们需要了解一些背景知识,只有知道这些背景知识,我们才能更好的去调整sql语句。
本节介绍了SQL语句处理的基本过程,主要包括:
· 查询语句处理
· DML语句处理(insert, update, delete)
· DDL 语句处理(create .. , drop .. , alter .. , )
· 事务控制(commit, rollback)
SQL 语句的执行过程(SQL Statement Execution)
图3-1 概要的列出了处理和运行一个sql语句的需要各个重要阶段。在某些情况下,Oracle运行sql的过程可能与下面列出的各个阶段的顺序有所不同。如DEFINE阶段可能在FETCH阶段之前,这主要依赖你如何书写代码。
对许多oracle的工具来说,其中某些阶段会自动执行。绝大多数用户不需要关心各个阶段的细节问题,然而,知道执行的各个阶段还是有必要的,这会帮助你写出更高效的SQL语句来,而且还可以让你猜测出性能差的SQL语句主要是由于哪一个阶段造成的,然后我们针对这个具体的阶段,找出解决的办法。
图 3-1 SQL语句处理的各个阶段
DML语句的处理
本节给出一个例子来说明在DML语句处理的各个阶段到底发生了什么事情。假设你使用Pro*C程序来为指定部门的所有职员增加工资。程序已经连到正确的用户,你可以在你的程序中嵌入如下的SQL语句:
EXEC SQL UPDATE employees
SET salary = 1.10 * salary WHERE department_id = :var_department_id; var_department_id是程序变量,里面包含部门号,我们要修改该部门的职员的工资。当这个SQL语句执行时,使用该变量的值。
每种类型的语句都需要如下阶段:
· 第1步: Create a Cursor 创建游标
· 第2步: Parse the Statement 分析语句
· 第5步: Bind Any Variables 绑定变量
· 第7步: Run the Statement 运行语句
· 第9步: Close the Cursor 关闭游标
如果使用了并行功能,还会包含下面这个阶段:
· 第6步: Parallelize the Statement 并行执行语句
如果是查询语句,则需要以下几个额外的步骤,如图 3所示:
· 第3步: Describe Results of a Query 描述查询的结果集
· 第4步: Define Output of a Query 定义查询的输出数据
· 第8步: Fetch Rows of a Query 取查询出来的行
下面具体说一下每一步中都发生了什么事情:.
第1步: 创建游标(Create a Cursor)
由程序接口调用创建一个游标(cursor)。任何SQL语句都会创建它,特别在运行DML语句时,都是自动创建游标的,不需要开发人员干预。多数应用中,游标的创建是自动的。然而,在预编译程序(pro*c)中游标的创建,可能是隐含的,也可能显式的创建。在存储过程中也是这样的。
第2步:分析语句(Parse the Statement)
在语法分析期间,SQL语句从用户进程传送到Oracle,SQL语句经语法分析后,SQL语句本身与分析的信息都被装入到共享SQL区。在该阶段中,可以解决许多类型的错误。
语法分析分别执行下列操作:
l 翻译SQL语句,验证它是合法的语句,即书写正确
l 实现数据字典的查找,以验证是否符合表和列的定义
l 在所要求的对象上获取语法分析锁,使得在语句的语法分析过程中不改变这些对象的定义
l 验证为存取所涉及的模式对象所需的权限是否满足
l 决定此语句最佳的执行计划
l 将它装入共享SQL区
l 对分布的语句来说,把语句的全部或部分路由到包含所涉及数据的远程节点
以上任何一步出现错误,都将导致语句报错,中止执行。
只有在共享池中不存在等价SQL语句的情况下,才对SQL语句作语法分析。在这种情况下,数据库内核重新为该语句分配新的共享SQL区,并对语句进行语法分析。进行语法分析需要耗费较多的资源,所以要尽量避免进行语法分析,这是优化的技巧之一。
语法分析阶段包含了不管此语句将执行多少次,而只需分析一次的处理要求。Oracle只对每个SQL语句翻译一次,在以后再次执行该语句时,只要该语句还在共享SQL区中,就可以避免对该语句重新进行语法分析,也就是此时可以直接使用其对应的执行计划对数据进行存取。这主要是通过绑定变量(bind variable)实现的,也就是我们常说的共享SQL,后面会给出共享SQL的概念。
虽然语法分析验证了SQL语句的正确性,但语法分析只能识别在SQL语句执行之前所能发现的错误(如书写错误、权限不足等)。因此,有些错误通过语法分析是抓不到的。例如,在数据转换中的错误或在数据中的错(如企图在主键中插入重复的值)以及死锁等均是只有在语句执行阶段期间才能遇到和报告的错误或情况。
查询语句的处理
查询与其它类型的SQL语句不同,因为在成功执行后作为结果将返回数据。其它语句只是简单地返回成功或失败,而查询则能返回一行或许多行数据。查询的结果均采用表格形式,结果行被一次一行或者批量地被检索出来。从这里我们可以得知批量的fetch数据可以降低网络开销,所以批量的fetch也是优化的技巧之一。
有些问题只与查询处理相关,查询不仅仅指SELECT语句,同样也包括在其它SQL语句中的隐含查询。例如,下面的每个语句都需要把查询作为它执行的一部分:
INSERT INTO table SELECT...
UPDATE table SET x = y WHERE...
DELETE FROM table WHERE...
CREATE table AS SELECT...
具体来说,查询
· 要求读一致性
· 可能使用回滚段作中间处理
· 可能要求SQL语句处理描述、定义和取数据阶段
第3步: 描述查询结果(Describe Results of a Query)
描述阶段只有在查询结果的各个列是未知时才需要;例如,当查询由用户交互地输入需要输出的列名。在这种情况要用描述阶段来决定查询结果的特征(数据类型,长度和名字)。
第4步: 定义查询的输出数据(Define Output of a Query)
在查询的定义阶段,你指定与查询出的列值对应的接收变量的位置、大小和数据类型,这样我们通过接收变量就可以得到查询结果。如果必要的话,Oracle会自动实现数据类型的转换。这是将接收变量的类型与对应的列类型相比较决定的。
第5步: 绑定变量(Bind Any Variables)
此时,Oracle知道了SQL语句的意思,但仍没有足够的信息用于执行该语句。Oracle 需要得到在语句中列出的所有变量的值。在该例中,Oracle需要得到对department_id列进行限定的值。得到这个值的过程就叫绑定变量(binding variables)
此过程称之为将变量值捆绑进来。程序必须指出可以找到该数值的变量名(该变量被称为捆绑变量,变量名实质上是一个内存地址,相当于指针)。应用的最终用户可能并没有发觉他们正在指定捆绑变量,因为Oracle 的程序可能只是简单地指示他们输入新的值,其实这一切都在程序中自动做了。因为你指定了变量名,在你再次执行之前无须重新捆绑变量。你可以改变绑定变量的值,而Oracle在每次执行时,仅仅使用内存地址来查找此值。如果Oracle 需要实现自动数据类型转换的话(除非它们是隐含的或缺省的),你还必须对每个值指定数据类型和长度。关于这些信息可以参考oracle的相关文档,如Oracle Call Interface Programmer's Guide
第6步: 并行执行语句(Parallelize the Statement )
ORACLE 可以在SELECTs, INSERTs, UPDATEs, MERGEs, DELETEs语句中执行相应并行查询操作,对于某些DDL操作,如创建索引、用子查询创建表、在分区表上的操作,也可以执行并行操作。并行化可以导致多个服务器进程(oracle server processes)为同一个SQL语句工作,使该SQL语句可以快速完成,但是会耗费更多的资源,所以除非很有必要,否则不要使用并行查询。
第7步: 执行语句(Run the Statement)
到了现在这个时候,Oracle拥有所有需要的信息与资源,因此可以真正运行SQL语句了。如果该语句为SELECT查询或INSERT语句,则不需要锁定任何行,因为没有数据需要被改变。然而,如果语句为UPDATE或DELETE语句,则该语句影响的所有行都被锁定,防止该用户提交或回滚之前,别的用户对这些数据进行修改。这保证了数据的一致性。对于某些语句,你可以指定执行的次数,这称为批处理(array processing)。指定执行N次,则绑定变量与定义变量被定义为大小为N的数组的开始位置,这种方法可以减少网络开销,也是优化的技巧之一。
第8步: 取出查询的行(Fetch Rows of a Query)
在fetch阶段,行数据被取出来,每个后续的存取操作检索结果集中的下一行数据,直到最后一行被取出来。上面提到过,批量的fetch是优化的技巧之一。
第9步: 关闭游标(Close the Cursor)
SQL语句处理的最后一个阶段就是关闭游标
DDL语句的处理(DDL Statement Processing)
DDL语句的执行不同与DML语句和查询语句的执行,这是因为DDL语句执行成功后需要对数据字典数据进行修改。对于DDL语句,语句的分析阶段实际上包括分析、查找数据字典信息和执行。事务管理语句、会话管理语句、系统管理语句只有分析与执行阶段,为了重新执行该语句,会重新分析与执行该语句。
事务控制(Control of Transactions)
一般来说,只有使用ORACLE编程接口的应用设计人员才关心操作的类型,并把相关的操作组织在一起,形成一个事务。一般来说,我门必须定义事务,这样在一个逻辑单元中的所有工作可以同时被提交或回滚,保证了数据的一致性。一个事务应该由逻辑单元中的所有必须部分组成,不应该多一个,也不应该少一个。
· 在事务开始和结束的这段时间内,所有被引用表中的数据都应该在一致的状态(或可以被回溯到一致的状态)
· 事务应该只包含可以对数据进行一致更改(one consistent change to the data)的SQL语句
例如,在两个帐号之间的转帐(这是一个事务或逻辑工作单元),应该包含从一个帐号中借钱(由一个SQL完成),然后将借的钱存入另一个帐号(由另一个SQL完成)。这2个操作作为一个逻辑单元,应该同时成功或同时失败。其它不相关的操作,如向一个帐户中存钱,不应该包含在这个转帐事务中。
在设计应用时,除了需要决定哪种类型的操作组成一个事务外,还需要决定使用BEGIN_DISCRETE_TRANSACTIO存储过程是否对提高小的、非分布式的事务的性能有作用。
[源自]http://blog.chinaunix.net/u2/61723/showart_482625.html
請教iframe和父窗口的問題。
一個頁面A.asp上含有iframe src="b.asp",在B.asp的頁面上有一個會員登入表單,要傳送到C.asp的頁面進行驗證和轉向到會員簡歷頁面。
這種佈局如果沒有特殊設置,會看到所有的動作都在A頁面上的那個IFRAME窗口,而A頁面不會動。
我想請教:
1、是否可以做到,在A頁面上按下B框架的表單提交後,連同A頁面整個轉向到會員驗證頁,而不是A不動,B頁自己轉向。
2、假如會員已登入,那麼在A頁面的iframe中顯示的是會員基本信息(佈局同上),並有退出按鈕,在另外一頁D.asp完成清空session功能。
當按下「退出」後,是否可以在B轉到D.asp頁面清空session值後,返回時能夠重整A頁面,使A顯現IFRAME內的是登入界面?
3、如果頁面上含有iframe,用光標在這個FRAME上拉來拉去,會看到這個框架頁會動,是否有辦法禁止?是不是和平時的禁止左右鍵方法一樣,在FRAME的SRC頁上設置?
謝謝!
答1:
<form target="_top">
答2:
D.asp
[code]
<%
' 清空Session 的操作
%>
<script>top.location.reload();</script>
[/code]
答3:
把 iframe 的內容尺寸設置的比 iframe 外尺寸小即可。就是說,定義 iframe 的 src 頁內容讓它的尺寸小於 A 頁上 iframe 元素的的尺寸。 |
非常感謝版主! |
再請教一個問題:是否可以在b.asp頁上不做css設置,使它能和父頁面a.asp共用一個style.css文件?
謝謝! |
哦,不知道二者能不能共用一個CSS文件,而不用要分別做CSS鏈接,
再頂一下,盼高手指點,謝謝! |
答:不能 |
哦,真是可惜了,謝謝!