JAXWS et Netbeans
* Utilisation transparente (et facile)
* Création d’un projet Web (web application)
* Ajout de Services Web
* A partir de POJO
* A partir de WSDL
* Création de clients par génération de stubs (skelette)
Utilisation de JAXWS dans netbeans
* Exemple de création de service:
* Faire un projet Web Application et
Utilisation de JAXWS dans netbeans
* Exemple de création de service:
Utilisation de JAXWS dans netbeans
Cliquer sur non
* Exemple de service:
Utilisation de JAXWS dans netbeans
* Exemple de service:
Utilisation de JAXWS dans netbeans
* Consommation d’un service en utilisant un proxy qui est généré (par la cmd wsimport)
* Création d’un projet Java application
* New Web service Client => generation de stubs
* Dans le code, faire insertion de code, appel de service Web
Utilisation de JAXWS dans netbeans
Utilisation de JAXWS dans netbeans
Consommation d’un service Choix du service :
Utilisation de JAXWS dans netbeans
Consommation d’un service Insertion de code :
Utilisation de JAXWS dans netbeans
Consommation d’un service en mode asynchrone
Puis insertion de code comme precedemment
JAWS et Gest. Des Exceptions,
Stateful WS
1. Gestion des exceptions BIG PICTURE
Try{
… ..
}
Catch Exception e{
Throw new XXXXX
VOIR APRESXXX ()}
Erreurs SOAP (fault code Fault string
… )
Try{
…}
Catch Exception
ou ..
}
=> =>
serveur Réponse soap client
Le message texte est encapsulé dans fault string et est récupérable chez le client
Resp: S. SALVA IUT licence pro
JAXWS et gest. Des exceptions
MODE FACILE
Utiliser Unmodeled Faults => Runtime exception
throw new RuntimeException("Please enter a name."); //Unmodeled fault
JAXWS et gest. Des exceptions
MODE PERSONALISE => Modeled Faults
https://docs.oracle.com/cd/E24329_01/web.1211/e24965/faults.htm#WSADV633 Exemple complet avec FaultString et Detail :
Exception CheckVerifyFault
JAXWS et gen. De SoapFault
@WebFault(name="CheckVerifyFault")
public class CheckVerifyFault extends Exception { private CheckFaultBean faultInfo;
public CheckVerifyFault(String message, CheckFaultBean faultInfo) { super(message);
this.faultInfo = faultInfo;
}
public CheckVerifyFault(String message, CheckFaultBean faultInfo, Throwable cause) {
super(message, cause);
this.faultInfo = faultInfo;
}
public CheckFaultBean getFaultInfo() { return faultInfo;
} }
JAXWS et gen. De SoapFault
class CheckFaultBean { private String message;
public CheckFaultBean() { }
public CheckFaultBean(String message) { this.message = message;
}
public String getMessage() { return message;
} }
JAXWS et gen. De SoapFault
Dans le code du service:
throw new CheckVerifyFault("Fault Detected", new CheckFaultBean("detail"));
Dans le WSDL généré :
<operation name="getbook"><input wsam:Action="http://ws/S1/getbookRequest"
message="tns:getbook"/><output wsam:Action="http://ws/S1/getbookResponse"
message="tns:getbookResponse"/>
<fault message="tns:CheckVerifyFault" name="CheckVerifyFault"
wsam:Action="http://ws/S1/getbook/Fault/CheckVerifyFault"/>
</operation>
JAXWS Statefull WS
2 possibilités :
• Par creation de session HTTP
• Passage de la session dans les messages,
• Plus légé au niveau du serveur
• Par l’annotation @stateful
• Création d’instance au niveau du serveur
JAXWS Statefull WS
Création de session HTTP
https://docs.oracle.com/cd/E14571_01/web.1111/e13734/stateful.htm#WSADV234 Besoin de modifier le code du serveur ET le code du client
JAXWS Statefull WS
https://docs.oracle.com/cd/E14571_01/web.1111/e13734/stateful.htm#WSADV234 Dans le code du service :
@WebService
public class ShoppingCart {
@Resource // Step 1
private WebServiceContext wsContext; // Step 2 public int addToCart(Item item) {
// Find the HttpSession
MessageContext mc = wsContext.getMessageContext(); // Step 3 HttpSession session =
((javax.servlet.http.HttpServletRequest)mc.get(MessageContext.SERVLET_REQUEST)).
getSession();
JAXWS Statefull WS
Suite du service (code exemple, depend de la logique à mettre en place)
if (session == null)
throw new WebServiceException("No HTTP Session found");
// Get the cart object from the HttpSession (or create a new one)
List<Item> cart = (List<Item>)session.getAttribute("myCart"); // Step 4 if (cart == null)
cart = new ArrayList<Item>();
// Add the item to the cart (note that Item is a class defined // in the WSDL)
cart.add(item);
// Save the updated cart in the HTTPSession (since we use the same // "myCart" name, the old cart object will be replaced)
session.setAttribute("myCart", cart);
// return the number of items in the stateful cart return cart.size();
} }
JAXWS Statefull WS
Utilisation de la session chez le client :
ShoppingCart proxy = new CartService().getCartPort();
((BindingProvider)proxy).getRequestContext().put(BindingProvider.SESSION_MAINTAIN_PR OPERTY, true);
// Create a new Item object with a part number of '123456' and an item // count of 4.
Item item = new Item('123456', 4);
// After first call, we'll print '1' (the return value is the number of objects // in the Cart object)
System.out.println(proxy.addToCart(item));
// After the second call, we'll print '2', since we've added another // Item to the stateful, saved Cart object.
System.out.println(proxy.addToCart(item));
* Par annotation @stateful
* https://javaee.github.io/metro-jax-ws/doc/user-guide/release- documentation.html#users-guide-stateful-webservice
* Importer dans votre projet les lib jaxws et jaxb
* Ajouter le module adressing avec @adressing
* Module qui je cite « provides transport-neutral mechanisms to address Web services and messages. »
JAXWS Statefull WS
* Par annotation @stateful
* Exemple:
@Stateful
@WebService(serviceName = "Serv")
@Addressing public class Serv { private String chaine;
/**
* This is a sample web service operation
*/
@WebMethod(operationName = "addchaine")
public synchronized String addchaine(@WebParam(name = "name") String txt) {// ou public static chaine = chaine + txt;
return chaine ; }
}
JAXWS Statefull WS
PHP et Soap
Resp: S. SALVA IUT licence pro
Possibilité de créer des services web et des clients avec PHP5 Les web services:
1.Création (manuelle) du fichier WSDL 2.Création du service web en PHP5:
Possibilités:
fonctions natives frameworks:
nusoap par exemple (http://sourceforge.net/projects/nusoap/)
(génération du wsdl, mais parfois il faut quasiment le définir dans le code)
Resp: S. SALVA IUT licence pro
Code du web service (http://stackoverflow.com/questions/2573494/php5-and-soap- wsdl)
<?php
function getRot13($pInput) {
$rot = str_rot13($pInput);
return($rot);
}
function getMirror($pInput) {
$mirror = strrev($pInput);
return $mirror;
}
ini_set("soap.wsdl_cache_enabled", "0");
$server = new SoapServer('scramble.wsdl');
$server->addFunction("getRot13");
$server->addFunction("getMirror");
$server->handle();
<?php
// turn off the WSDL cache
ini_set("soap.wsdl_cache_enabled", "0");
$client = new SoapClient("http://localhost/test/scramble.wsdl");
$origtext = "mississipi";
print("The original text : $origtext\n");
$mirror = $client->getMirror($origtext);
print("The mirrored text : $mirror\n");
$scramble = $client->getRot13($mirror);
print("The scrambled text : $scramble\n");
Code client:
Si plusieurs paramètres: utiliser array
Resp: S. SALVA IUT licence pro
Resp: S. SALVA IUT licence pro
Code du client: méthode soapcall (méthode PHP) /* Initialize webservice with your WSDL */
$client = new SoapClient("http://localhost/Service1?wsdl");
/* Set your parameters for the request */
$params = array(
“isbn" => “1234”,
"description" => “Book",
"amount" => 500, );
/* Invoke webservice method with your parameters, in this case: Buy */
$response = $client->__soapCall(“Buy", array($params));
/* Print webservice response */
var_dump($response);
SOAP et Springboot
* Oui c’est possible
* Mais il faut écrire les schéma XML (ceux en debut du WSDL) à la main L
Soap et Springboot
* Oui c’est possible
* Approche Top-down (je passe)
* Approche Bottom-Up
* D’après la doc spring il faut écrire les schéma XML (ceux en debut du WSDL) à la main L
* https://spring.io/guides/gs/producing-web-service/
* Ici: pas besoin de schémas ? https://blog.sodifrance.fr/creer-des-services-web- soap-simplement-avec-jax-ws-et-spring-boot-part-i/
Soap et Springboot
Create an XML Schema to Define the Domain
<xs:element name="getCountryRequest">
<xs:complexType>
<xs:sequence>
<xs:element name="name"
type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element
name="getCountryResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="country"
type="tns:country"/>
</xs:sequence>
</xs:complexType>
</xs:element>
Soap et Springboot
<xs:complexType name="country">
<xs:sequence>
<xs:element name="name"
type="xs:string"/>
<xs:element name="population"
type="xs:int"/>
<xs:element name="capital"
type="xs:string"/>
<xs:element name="currency"
type="tns:currency"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="currency">
<xs:restriction base="xs:string">
<xs:enumeration value="GBP"/>
<xs:enumeration value="EUR"/>
<xs:enumeration value="PLN"/>
</xs:restriction>
</xs:simpleType>
</xs:schema>
* Create Country Service Endpoint (code du service)
@Endpoint public class CountryEndpoint {
private static final String NAMESPACE_URI = "http://spring.io/guides/gs-producing-web- service";
private CountryRepository countryRepository;
@PayloadRoot(namespace = NAMESPACE_URI, localPart = "getCountryRequest")
@ResponsePayload
public GetCountryResponse getCountry(@RequestPayload GetCountryRequest request) { GetCountryResponse response = new GetCountryResponse();
response.setCountry());
return response; } }
Soap et Springboot
* Configuration
Des namespaces, des schemas, des noms d’opération dans
src/main/java/com/example/producingwebservice/WebServiceConfig.jav a
Soap et Springboot
* Make the Application Executable
@SpringBootApplication
public class ProducingWebServiceApplication { public static void main(String[] args) {
SpringApplication.run(ProducingWebServiceApplication.class, args); } }
Soap et Springboot
* Faire un client
* https://spring.io/guides/gs/consuming-web-service/
* Plus simple?
* Utilise wsimport pour générer les stubs dans target/generated-sources
* Faire une classe fille à WebServiceGatewaySupport pour préparer les appels
* Configurer la sérialisation / deserialisation
* Et appel
Soap et Springboot
* Faire un client
* https://spring.io/guides/gs/consuming-web-service/
@SpringBootApplication
public class ConsumingWebServiceApplication { public static void main(String[] args) {
SpringApplication.run(ConsumingWebServiceApplication.class, args); }
@Bean CommandLineRunner lookup(CountryClient quoteClient) { return args -> { String country = "Spain";
if (args.length > 0) { country = args[0]; }
GetCountryResponse response = quoteClient.getCountry(country);
System.err.println(response.getCountry().getCurrency());
};
} }
Soap et Springboot
2 mots sur la sécurité
Il existe plusieurs standards de sécurité :
•WS-Security: standard proposé par Microsoft pour la sécurisation des services interopérables. Plus large que SAML, il intègre le traitement de l'authentification, du chiffrement et de l'intégrité des données.
•XML encryption : cryptage de documents XML
•XML signature: signature digitale dans un document XML
•SAML-XML: (security assertions markup language) spécifie une procédure d’authentification
•XKMS: utilisation de clés publiques
Resp: S. SALVA IUT licence pro
Implémentations
• Des API payantes L, ou
• http://ws.apache.org/wss4j/ en lien avec https://cxf.apache.org/docs/ws- security.html, spingboot compliant ?
• HTTPS
• Ex: https://www.codeflow.site/fr/article/webservices__jax-ws__application- authentication-with-jax-ws
Resp: S. SALVA IUT licence pro
Parefeu XML:
se déploie en aval du pare-feu traditionnel
conçu spécifiquement pour inspecter les flux XML et SOAP sur protocoles de base HTTP/HTTPS et éventuellement sur des protocoles tiers
sécurité sur:
•la validation des messages,
•l’« obfuscation » des exceptions,
•la détection des intrusions,
•le routage selon le type de contenu,
•la transition de protocoles
•la sécurité au niveau de la couche de message.
Resp: S. SALVA IUT licence pro
Manque de performance ?
Mais apporte sécurité, transactions, Uniformité
Mode SMTP pour envoi importants
A recommander pour transactions sensibles entre sites
Resp: S. SALVA IUT licence pro