Main Tutorials

JAX-WS Hello World Example – Document Style

In this tutorial, we show you how to use JAX-WS to create a SOAP-based web service (document style) endpoint. Compare with RPC style, it need some extra efforts to get it works.

Directory structure of this example

jaxws-document-hello-world--example

JAX-WS Web Service End Point

Here are the steps to create a document style web service in JAX-WS.

1. Create a Web Service Endpoint Interface

Actually, annotated with @SOAPBinding is optional, because the default style is document.

File : HelloWorld.java


package com.mkyong.ws;

import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;

//Service Endpoint Interface
@WebService
@SOAPBinding(style = Style.DOCUMENT, use=Use.LITERAL) //optional
public interface HelloWorld{
	
	@WebMethod String getHelloWorldAsString(String name);
	
}
Note
In JAX-WS development, convert from “RPC style” to “Document style” is very easy, just change the @SOAPBinding style option.

2. Create a Web Service Endpoint Implementation

File : HelloWorldImpl.java


package com.mkyong.ws;

import javax.jws.WebService;

//Service Implementation
@WebService(endpointInterface = "com.mkyong.ws.HelloWorld")
public class HelloWorldImpl implements HelloWorld{

	@Override
	public String getHelloWorldAsString(String name) {
		return "Hello World JAX-WS " + name;
	}

}

3. Create a Endpoint Publisher.

File : HelloWorldPublisher.java


package com.mkyong.endpoint;

import javax.xml.ws.Endpoint;
import com.mkyong.ws.HelloWorldImpl;

//Endpoint publisher
public class HelloWorldPublisher{
	
	public static void main(String[] args) {
	   Endpoint.publish("http://localhost:9999/ws/hello", new HelloWorldImpl());
    }

}

Wait, when you run the end point publisher, you will hits following error message :


Wrapper class com.mkyong.ws.jaxws.GetHelloWorldAsString is not found. 
    Have you run APT to generate them?

See this article. You need to use “wsgen” tool to generate necessary JAX-WS portable artifacts. Let move to next step.

4. wsgen command

Document style requires extra classes to run, you can use “wsgen” to generate all necessary Java artifacts (mapping classes, wsdl or xsd schema). The “wsgen” command is required to read a service endpoint implementation class :


wsgen -keep -cp . com.mkyong.ws.HelloWorldImpl

It will generate two classes, copy it to your “package.jaxws” folder.

File : GetHelloWorldAsString.java


package com.mkyong.ws.jaxws;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name = "getHelloWorldAsString", namespace = "http://ws.mkyong.com/")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getHelloWorldAsString", namespace = "http://ws.mkyong.com/")
public class GetHelloWorldAsString {

    @XmlElement(name = "arg0", namespace = "")
    private String arg0;

    /**
     * 
     * @return
     *     returns String
     */
    public String getArg0() {
        return this.arg0;
    }

    /**
     * 
     * @param arg0
     *     the value for the arg0 property
     */
    public void setArg0(String arg0) {
        this.arg0 = arg0;
    }

}

File : GetHelloWorldAsStringResponse.java


package com.mkyong.ws.jaxws;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name = "getHelloWorldAsStringResponse", namespace = "http://ws.mkyong.com/")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "getHelloWorldAsStringResponse", namespace = "http://ws.mkyong.com/")
public class GetHelloWorldAsStringResponse {

    @XmlElement(name = "return", namespace = "")
    private String _return;

    /**
     * 
     * @return
     *     returns String
     */
    public String getReturn() {
        return this._return;
    }

    /**
     * 
     * @param _return
     *     the value for the _return property
     */
    public void setReturn(String _return) {
        this._return = _return;
    }

}
Note
The “wsgen” tool is available in the “JDK_Path\bin\” folder. For detail, please read this JAX-WS : wsgen tool example article.

5. Done

Done, publish it and test it via URL : http://localhost:9999/ws/hello?wsdl.

Web Service Client

Create a web service client to access your published service.

File : HelloWorldClient.java


package com.mkyong.client;
 
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;
import com.mkyong.ws.HelloWorld;
 
public class HelloWorldClient{
 
	public static void main(String[] args) throws Exception {
 
	URL url = new URL("http://localhost:9999/ws/hello?wsdl");
        QName qname = new QName("http://ws.mkyong.com/", "HelloWorldImplService");
 
        Service service = Service.create(url, qname);
 
        HelloWorld hello = service.getPort(HelloWorld.class);
 
         System.out.println(hello.getHelloWorldAsString("mkyong"));
 
    }
 
}

Output


Hello World JAX-WS mkyong

Tracing SOAP Traffic

From top to bottom, showing how SOAP envelope flows between client and server in this document style web service.

1. Request a WSDL file

First, client send a wsdl request to service endpoint :

Client send request :


GET /ws/hello?wsdl HTTP/1.1
User-Agent: Java/1.6.0_13
Host: localhost:9999
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive

Server send response :


HTTP/1.1 200 OK
Transfer-encoding: chunked
Content-type: text/xml;charset=utf-8

<?xml version="1.0" encoding="UTF-8"?>
	<!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. 
		RI's version is JAX-WS RI 2.1.1 in JDK 6. -->
	<!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. 
		RI's version is JAX-WS RI 2.1.1 in JDK 6. -->
<definitions 
	xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" 
	xmlns:tns="http://ws.mkyong.com/" 
	xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
	xmlns="http://schemas.xmlsoap.org/wsdl/" 
	targetNamespace="http://ws.mkyong.com/" 
	name="HelloWorldImplService">
<types>
<xsd:schema>
	<xsd:import namespace="http://ws.mkyong.com/" 
		schemaLocation="http://localhost:9999/ws/hello?xsd=1"></xsd:import>
</xsd:schema>
</types>

<message name="getHelloWorldAsString">
	<part name="parameters" element="tns:getHelloWorldAsString"></part>
</message>
<message name="getHelloWorldAsStringResponse">
	<part name="parameters" element="tns:getHelloWorldAsStringResponse"></part>
</message>

<portType name="HelloWorld">
	<operation name="getHelloWorldAsString">
		<input message="tns:getHelloWorldAsString"></input>
		<output message="tns:getHelloWorldAsStringResponse"></output>
	</operation>
</portType>

<binding name="HelloWorldImplPortBinding" type="tns:HelloWorld">

	<soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document">
	</soap:binding>
	<operation name="getHelloWorldAsString">
		<soap:operation soapAction=""></soap:operation>
		<input>
			<soap:body use="literal"></soap:body>
		</input>
		<output>
			<soap:body use="literal"></soap:body>
		</output>
	</operation>
	
</binding>

<service name="HelloWorldImplService">

<port name="HelloWorldImplPort" binding="tns:HelloWorldImplPortBinding">

<soap:address location="http://localhost:9999/ws/hello"></soap:address>

</port>
</service>
</definitions>

2. getHelloWorldAsString(String name)

A second call, client put method invoke request in SOAP envelope and send it to service endpoint. At the service endpoint, call the requested method and put the result in a SOAP envelope and send it back to client.

Client send request :


POST /ws/hello HTTP/1.1
SOAPAction: ""
Accept: text/xml, multipart/related, text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Content-Type: text/xml; charset=utf-8
User-Agent: Java/1.6.0_13
Host: localhost:9999
Connection: keep-alive
Content-Length: 224

<?xml version="1.0" ?>
	<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
		<S:Body>
			<ns2:getHelloWorldAsString xmlns:ns2="http://ws.mkyong.com/">
				<arg0>mkyong</arg0>
			</ns2:getHelloWorldAsString>
		</S:Body>
	</S:Envelope>

Server send response :


HTTP/1.1 200 OK
Transfer-encoding: chunked
Content-type: text/xml; charset=utf-8

<?xml version="1.0" ?>
	<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
		<S:Body>
			<ns2:getHelloWorldAsStringResponse xmlns:ns2="http://ws.mkyong.com/">
				<return>Hello World JAX-WS mkyong</return>
			</ns2:getHelloWorldAsStringResponse>
		</S:Body>
	</S:Envelope>

Download Source Code

About Author

author image
Founder of Mkyong.com, love Java and open source stuff. Follow him on Twitter. If you like my tutorials, consider make a donation to these charities.

Comments

Subscribe
Notify of
48 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments
Siva
6 years ago

Hi Friends, One doubt. i sawthe JAX WS spec. From that they mentioned, implements of JAX WS are Metro Project in GlassFish
Apache CXF
Apache Axis2
JBossWS in JBoss
IBM WebSphere Jax-Ws in WebSphere
Oracle Weblogic.
In this example which implementation have been used. Please advice.

Abdulbaset
9 years ago

Hi,
I am trying to send XML Document to Web Service built on C# Dot Net how to do it?

Bar??
10 years ago

Hi,
I am newbie in this topic and I want to ask something. I have Java SE (Kepler). What stuff do I need to run code. Have I got Tomcat, can I use Wamp server . At last, how can I run “wsgen -keep -cp . com.mkyong.ws.HelloWorldImpl” and where I should run this code.(path?) ?

Thank you in advance.

saigonvangem
10 years ago

Hi All,

I have the same concern with Asbek, everyone can give me explaination about this?
“com.mkyong.ws.HelloWorld;

HelloWorld class is serverside code.How can you import it in client side?”

Regards,
saigonvangem

Java GUY
10 years ago
Reply to  saigonvangem

You are right you cannot import an interface located on the service in your client side code, but you have an the same interface on the client side it would work fine. The author forgot to mention in this tutorial about using wsimport to generate client side code using wsdl file from the server. The same step is explained in an earlier tutorial featuring RPC document type of RPC type which just one tutorial above this one in the main page.

lavanya hema
10 years ago

Hi kong,

This example is really good for understanding/executing the example. I think your example is best way to start jax ws webservice. i have below comments
i used below commands to run the example. plz make a note and change if required

wsgen -cp bin -d bin com.mykong.ws.HelloWorldImpl

wsgen -s src -cp bin -d bin com.mykong.ws.HelloWorldImpl

toanbom
4 years ago

hi all,
I have a question: How to remove “ns…” and replace “return” in response xml:
– “ns2:ReceiveMOResponse” i want to xml format response: “ReceiveMOResponse”
– “return” to “ReceiveMOResult”

Pardeep
6 years ago

How to handle multiPart in wsdl. if wsdl file has more then one part in the message. For example:

How to handle this as axis2 in supporting multiparts in document/litral style.
Please help me here.

Pardeep
6 years ago
Reply to  Pardeep

Below is the example:
————————————

misa
7 years ago

what is this, client, server, publisher, xml, SOAP and this is a solution for busines. I do not need java for java , i need java for busines. So much classes, text, and at the end I belive does not work … no thank*s

Suvankar
8 years ago

Hi,
I’m net to JAX-WS can you tell me how can I remove chunked from Transfer-Encoding from response?

Snehal Vasava
9 years ago

Hi…
I am new in this topic and i want to ask somethig. I have ready made wsdl web service i want to use this in my project. In this web service i want to pass some parameters. How can I do this?

allisok07
10 years ago

can you share a sample code for jax-ws + ejb3 and jax-rs+ejb3?

saiid
10 years ago

hi everybody
i not found solution to my problem. i use jax ws maven plugin to generate the wsdl file for my web services.
after a successfully building i not found the wsdl file in any folder in my project. but i found the .class

any suggestion or solution

Raj
10 years ago

Good Article,

I have a Question here or i can say i am having the problem which i am trying to solve on the same way.

I am referring the

“Server send response” Section

And about the following line

I do not want the request to be in another location, i want to embed it in the same wsdl file, is there any way for this.

If i use way which is configured in spirng config.. i am getting it embed in wsdl, when i use annotations it is creating it another location.

Let me know if i missed anything / need more info.

Ferda
10 years ago

Hello Mkyong,
First of all I liked your tutorials really. It is very descriptive. I tried this one . I can publish the web service and run the client. It works perfect. My web service code and client code is part of a larger project. When I deploy my war file on Tomcat I get error which is below. My Tomcat version is : 7.0.40 . I ran tomcat as a stnadalone application by startup.bat file (as an administrator). The deployment problem is caused because of web service codes because when i remove them I can deploy rest of the application. I will be very happy if you can help me. I have to finish this (masters) project in at most 2 days.
Ferda

SEVERE: WSSERVLET11: failed to parse runtime descriptor: com.sun.xml.ws.util.Ser
viceConfigurationError: com.sun.xml.ws.policy.jaxws.spi.PolicyFeatureConfigurato
r: Provider com.sun.xml.ws.addressing.policy.AddressingFeatureConfigurator is sp
ecified in jar:file:/C:/Program%20Files/Apache/apache-tomcat-7.0.40/webapps/ROOT
/WEB-INF/lib/webservices-rt.jar!/META-INF/services/com.sun.xml.ws.policy.jaxws.s
pi.PolicyFeatureConfiguratorbut could not be instantiated: java.lang.ClassCastEx
ception: Cannot cast com.sun.xml.ws.addressing.policy.AddressingFeatureConfigura
tor to com.sun.xml.ws.policy.jaxws.spi.PolicyFeatureConfigurator
com.sun.xml.ws.util.ServiceConfigurationError: com.sun.xml.ws.policy.jaxws.spi.P
olicyFeatureConfigurator: Provider com.sun.xml.ws.addressing.policy.AddressingFe
atureConfigurator is specified in jar:file:/C:/Program%20Files/Apache/apache-tom
cat-7.0.40/webapps/ROOT/WEB-INF/lib/webservices-rt.jar!/META-INF/services/com.su
n.xml.ws.policy.jaxws.spi.PolicyFeatureConfiguratorbut could not be instantiated
: java.lang.ClassCastException: Cannot cast com.sun.xml.ws.addressing.policy.Add
ressingFeatureConfigurator to com.sun.xml.ws.policy.jaxws.spi.PolicyFeatureConfi
gurator
at com.sun.xml.ws.util.ServiceFinder.fail(ServiceFinder.java:258)
at com.sun.xml.ws.util.ServiceFinder.access$300(ServiceFinder.java:151)
at com.sun.xml.ws.util.ServiceFinder$LazyIterator.next(ServiceFinder.jav
a:465)
at com.sun.xml.ws.util.ServiceFinder$CompositeIterator.next(ServiceFinde
r.java:402)
at com.sun.xml.ws.policy.jaxws.PolicyUtil.addServiceProviders(PolicyUtil
.java:97)
at com.sun.xml.ws.policy.jaxws.PolicyUtil.(PolicyUtil.java:83)
at com.sun.xml.ws.policy.jaxws.PolicyWSDLGeneratorExtension.loadConfigur
ators(PolicyWSDLGeneratorExtension.java:476)
at com.sun.xml.ws.policy.jaxws.PolicyWSDLGeneratorExtension.start(Policy
WSDLGeneratorExtension.java:124)
at com.sun.xml.ws.wsdl.writer.WSDLGeneratorExtensionFacade.start(WSDLGen
eratorExtensionFacade.java:71)
at com.sun.xml.ws.wsdl.writer.WSDLGenerator.generateDocument(WSDLGenerat
or.java:407)
at com.sun.xml.ws.wsdl.writer.WSDLGenerator.doGeneration(WSDLGenerator.j
ava:330)
at com.sun.xml.ws.db.DatabindingImpl.generateWSDL(DatabindingImpl.java:2
30)
at com.sun.xml.ws.server.EndpointFactory.generateWSDL(EndpointFactory.ja
va:553)
at com.sun.xml.ws.server.EndpointFactory.create(EndpointFactory.java:278
)
at com.sun.xml.ws.server.EndpointFactory.createEndpoint(EndpointFactory.
java:147)
at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:574)
at com.sun.xml.ws.api.server.WSEndpoint.create(WSEndpoint.java:557)
at com.sun.xml.ws.transport.http.DeploymentDescriptorParser.parseAdapter
s(DeploymentDescriptorParser.java:260)
at com.sun.xml.ws.transport.http.DeploymentDescriptorParser.parse(Deploy
mentDescriptorParser.java:152)
at com.sun.xml.ws.transport.http.servlet.WSServletContextListener.parseA
daptersAndCreateDelegate(WSServletContextListener.java:131)
at com.sun.xml.ws.transport.http.servlet.WSServletContainerInitializer.o
nStartup(WSServletContainerInitializer.java:65)
at org.apache.catalina.core.StandardContext.startInternal(StandardContex

Ferda
10 years ago
Reply to  Ferda

Hello Again my problem is solved when i add metro jars https://metro.java.net/2.0/ under webinf/lib .
Putting same files under tomcat/lib did not solve the problem. Thank you for your time…

Ferda

Dawid Furman
11 years ago

So clearly explanation. Thank you very much

best regards,
FurmanS

chetan
11 years ago

How we can generates the server code form a WSDL file like other web service framework
JAX-WS provides any tool for this?.

Vamsi
11 years ago

Hi,
I can see the namespace defined at element level. Can this be moved to envelope level in jax-ws?

<ns2:getHelloWorldAsStringResponse xmlns:ns2="http://ws.mkyong.com/">
jssay
11 years ago

I am new to web sevice, can you clarify what ‘s difference between RPC and Document style. thanks in advance.

sl
11 years ago

What is this publisher class? I’d like to know how to deploy this service onto a Tomcat server.

Sridhar
11 years ago

Hi, How is this is a Document style messaging? The SOAP-BODY has method name as the first element. Isn’t this still going the RPC way ?

vm
11 years ago

hi

i’m trying to consume a web service doclit type but it’s published under https protocol and the clients that i’m using are not able to cosume it, what kind of extra work need to be done in order for this to work

thanks

Ben Glasser
11 years ago

Hey great article, but I have absolutely no experience with web services and I don’t know how to publish the service after I create. You say simply “now publish and test it” but how \_(o.O)_/

Kunal
11 years ago

Hi

I have looked at many of your (Mkyoung) web pages recently. You have done an excellent job in posting very useful information.

I ran above example, I am not getting soap envelope back from server response. it is just an xml. Can you please let me know how can I get it ?

Thanks
K

Mao
11 years ago
Reply to  Kunal

You should see in tracing soap traffic point above or you can test with soapUI to see envelope request and response easily.

AR
11 years ago

I’m confused on step 5. How do I publish to http://localhost:9999/ws/hello?wsdl? Also, am I suppose to have a WSDL in my project somewhere? I don’t see where a WSDL is created in the tutorial.

I’m using Tomcat 7 if that helps answer my question.

Thanks

AR
11 years ago
Reply to  AR

To publish I just had to run HelloWorldPublisher…duh

So I can see the WSDL at http://localhost:8080/ws/hello?wsdl after running HelloWorldPublisher. But when I run HelloWorldClient I get the error bellow. Any idea what I can be doing wrong?

Exception in thread "main" javax.xml.ws.WebServiceException: {http://ws.hello.com}HelloWorldImplService is not a valid service. Valid services are: {http://ws.hello.com/}HelloWorldImplService
	at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:220)
	at com.sun.xml.internal.ws.client.WSServiceDelegate.<init>(WSServiceDelegate.java:165)
	at com.sun.xml.internal.ws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:93)
	at javax.xml.ws.Service.<init>(Service.java:56)
	at javax.xml.ws.Service.create(Service.java:680)
	at com.hello.client.HelloWorldClient.main(HelloWorldClient.java:15)
MM
11 years ago
Reply to  AR

in your GetHelloWorldAsString.java and GetHelloWorldAsStringRepsonse.java files, change the add “/” to the namespace.
So it would be

namespace = "http://ws.hello.com/
Sandeep
11 years ago

Hi,

In the document style web service as u mentioned we have to genereate WS artifacts but i am able to run web service without genereting it with wsgen.
But u mentioned that it will give error msg as

“Wrapper class com.mkyong.ws.jaxws.GetHelloWorldAsString is not found.
Have you run APT to generate them?”

Kindly explain it
Thanks

Vinay
10 years ago
Reply to  Sandeep

Apparently the JDK(1.6.0_13 and below) was not using right version of required JARS.
Its fixed in the new JDK’s.

Dino
10 years ago
Reply to  Sandeep

I had the same question, so I did a experiment. Here is my observation,

With JDK 6 (more precisely 1.6.0_45), I encountered the error (but my error says INFO: Dynamically creating request wrapper Class com.mkyong.ws.jaxws.GetHelloWorldAsString on ). And after running wsgen, the publisher just worked fine.

With JDK 7, I was able to publish the service with no need to run wsgen.

Vinay
10 years ago
Reply to  Dino

Dino,

“INFO: Dynamically creating request wrapper Class com.mkyong.ws.jaxws.GetHelloWorldAsString on” is not a ERROR. Its a message printed out. I guess this question was never answered.

Satish
11 years ago
Reply to  Sandeep

Even for me it works and the generated wsld also correct as per the document style.. I don’t know, I believe that is not required with standalone.

b12
11 years ago
Reply to  Sandeep

I am seeing the same thing. Can you explain why? Also can you talk to the difference between running wsgen as you have shown here vs running wsimport on the wsdl for generating classes on the client side as covered here: http://java.dzone.com/articles/jax-ws-hello-world.

Appreciate all your doing here! thanks!

Vijayendra
11 years ago
Reply to  Sandeep

Same with me.I am able to run the web service without using wsgen.I just changed the style to DOCUMENT and it is running.

wantolearn
11 years ago

Hi, thank you for always providing very informative and easy to read tutorial.

I have a dumb question about web services in general if you don’t mind.
In this example, you created web service end point as standalone.

public static void main(String[] args) {
Endpoint.publish(“http://localhost:9999/ws/hello”, new HelloWorldImpl());
}

But I know, I can also generate the web services using eclipse which then will run as web app on server like tomcat.

What is the difference between these two? I mean is there any standard way of doing it or preferred way? any pro and con?

Any comment will be very much appreciated. Thanks

Mahran ALSHIEKH
10 years ago
Reply to  mkyong

Hello Mkyoung,

In this case if I want to run the previous example as web app what should I do?

Many thanks in advance.

Levan
12 years ago

Hi.

Thank you for very informative and compact tutorials.

In step 4. WSGEN, instead of copying, one can use an “-s ” argument in conjunction with “-keep” to specify where to place generated source files.

For instance:

wsgen -keep -s  -cp . com.mkyong.ws.HelloWorldImpl

so the generated source files will end up in /jaxws folder.

Levan
12 years ago
Reply to  Levan

Sorry, in the above comment some part was for some reason truncated.
After the “-s” argument should follow the path to desired directory:

wsgen -keep -s path/to/some/directory -cp . com.mkyong.ws.HelloWorldImpl

Then the generated source files will end up in “path/to/some/directory/jaxws” folder.

Srinivas
12 years ago

Please mention the difference between RPC and document style of Webservices

Asbek
12 years ago

Hi,

com.mkyong.ws.HelloWorld;

HelloWorld class is serverside code.How can you import it in client side?

Regards,
Aslan

saigonvangem
10 years ago
Reply to  Asbek

Hi All,

I have the same concern with Asbek, everyone can give me explaination about this?
“com.mkyong.ws.HelloWorld;

HelloWorld class is serverside code.How can you import it in client side?”

Regards,
saigonvangem

polo
9 years ago
Reply to  saigonvangem

test