Création de services REST à l'aide de la structure de mappage de la commande de contrôleur et des beans de données basée sur la configuration
Procédure
-
Créez votre gestionnaire de ressources, en suivant le format spécifié en tant que base.
Le gestionnaire de ressources de l'exemple suivant accepte deux ressources. L'un obtient des données CatalogEntry à partir d'un bean de données, et l'autre met à jour les données CatalogEntry avec une commande :
import java.util.logging.Logger; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import com.ibm.commerce.beans.DataBean; import com.ibm.commerce.catalog.beans.CatalogEntryDataBean; import com.ibm.commerce.catalogmanagement.commands.CatalogEntryUpdateCmd; import com.ibm.commerce.command.ControllerCommand; import com.ibm.commerce.foundation.logging.LoggingHelper; import com.ibm.commerce.rest.classic.core.AbstractConfigBasedClassicHandler; /** * This is a very simple REST handler that extends the configuration-based REST * classic handler. It demonstrates how to create REST resources based on a * {@link DataBean} and a {@link ControllerCommand} with minimal coding, as all * the input/output information is stored in a configuration mapping file. * */ @Path("store/{storeId}/sample") public class SampleCatalogEntryClassicRestHandler extends AbstractConfigBasedClassicHandler { /** * IBM Copyright notice field. */ public static final String COPYRIGHT = com.ibm.commerce.copyright.IBMCopyright.SHORT_COPYRIGHT; private static final String CLASSNAME = RestClassicDataBeanHandler.class.getName(); private static final Logger LOGGER = LoggingHelper.getLogger(RestClassicDataBeanHandler.class); private static final String RESOURCE_NAME = "sample"; /* * (non-Javadoc) * @see com.ibm.commerce.foundation.rest.resourcehandler.IResourceHandler#getResourceName() */ @Override public String getResourceName() { return RESOURCE_NAME; } /** * Used with WC to instantiate handler. */ public SampleCatalogEntryClassicRestHandler() { super(); } /** * A sample REST GET that executes the {@link CatalogEntryDataBean} based on * the request parameters and profile specified. * * @param storeId * @param responseFormat * @param profileName * @param catalogEntryID * @return the response */ @GET @Path("catalogEntry") @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.APPLICATION_XHTML_XML, MediaType.APPLICATION_ATOM_XML }) public Response processRequest( @PathParam("storeId") String storeId, @QueryParam("responseFormat") String responseFormat, @QueryParam("profileName") String profileName, @QueryParam("catalogEntryID") String catalogEntryID) { final String METHODNAME = "processRequest(String storeId, String profileName, String responseFormat, String catalogEntryID) "; boolean entryExitTraceEnabled = LoggingHelper.isEntryExitTraceEnabled(LOGGER); if (entryExitTraceEnabled) { Object[] objArr = new Object[] { storeId, profileName, responseFormat, catalogEntryID }; LOGGER.entering(CLASSNAME, METHODNAME, objArr); } Response result = executeConfigBasedBeanWithContext(CatalogEntryDataBean.class.getName(), profileName, responseFormat, null); if (entryExitTraceEnabled) { LOGGER.exiting(CLASSNAME, METHODNAME, result); } return result; } /** * A sample REST POST that executes the {@link CatalogEntryUpdateCmd} based on * the request parameters and profile specified. * * @param storeId * @param responseFormat * @param profileName * @return the response */ @POST @Path("catalogEntryUpdate") @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML, MediaType.APPLICATION_XHTML_XML, MediaType.APPLICATION_ATOM_XML }) public Response processRequest(@PathParam("storeId") String storeId, @QueryParam(value = "responseFormat") String responseFormat, @QueryParam(value = "profileName") String profileName) { final String METHODNAME = "processRequest(String storeId, String profileName, String responseFormat) "; boolean entryExitTraceEnabled = LoggingHelper.isEntryExitTraceEnabled(LOGGER); if (entryExitTraceEnabled) { Object[] objArr = new Object[] { storeId, profileName, responseFormat }; LOGGER.entering(CLASSNAME, METHODNAME, objArr); } Response result = executeConfigBasedCommandWithContext(CatalogEntryUpdateCmd.class.getName(), profileName, responseFormat, storeId, null); if (entryExitTraceEnabled) { LOGGER.exiting(CLASSNAME, METHODNAME, result); } return result; } } -
Déterminez quelle classe de point d'entrée (bean de données ou commande de contrôleur) vous souhaitez utiliser dans votre gestionnaire de ressources.
Les appels REST nécessitent généralement un gestionnaire qui contient un point d'entrée dans la classe de gestionnaire classique basée sur la configuration. Les points d'entrée suivants sont disponibles par défaut :
public Response executeConfigBasedBeanWithContext(String beanClassName, String profileName, String responseFormat, Map<String, Object> paramOverrideMap)Cette méthode définit la requête de démarrage
{@link BusinessContextService}, puis délègue à{@link #executeConfigBasedBean(String, String, String, Map)}, et termine finalement la requête BCS.Les paramètres suivants sont disponibles par défaut :- beanClassName
- Le nom de la classe de bean de données.
- profileName
- Le nom de profil du bean de données dans la configuration.
- responseFormat
- Le format de réponse à utiliser pour générer le résultat.
- paramOverrideMap
- Définit tous les paramètres que vous souhaitez ajouter ou remplacer à partir de l'objet de requête associé à ce gestionnaire.
public JSONObject executeConfigBasedBean(String beanClassName, String profileName, String responseFormat, Map<String, Object> paramOverrideMap) throws ExceptionCette méthode traite une requête de bean de données à l'aide des mappages de profil basés sur la configuration. Elle suppose que
{@link BusinessContextService}est traité par l'appleant.Les paramètres d'entrée sont automatiquement complétés en fonction des paramètres de chemin d'accès spécifiés dans l'URL, suivis de n'importe quel paramètre de requête.
Une mappe de remplacement peut être fournie pour injecter plus de paramètres ou remplacer les paramètres préexistants.
Les paramètres suivants sont disponibles par défaut :- beanClassName
- Le nom de la classe de bean de données.
- profileName
- Le nom de profil du bean de données dans la configuration.
- responseFormat
- Le format de réponse à utiliser pour générer le résultat.
- paramOverrideMap
- Définit tous les paramètres que vous souhaitez ajouter ou remplacer à partir de l'objet de requête associé à ce gestionnaire.
public Response executeConfigBasedCommandWithContext(String commandInterfaceName, String profileName, String responseFormat, String storeId, Map<String, Object> paramOverrideMap)Cette méthode définit la requête de démarrage
{@link BusinessContextService}, puis délègue à* {@link #executeControllerCommand(String, String, TypedProperty, String)}, et termine finalement la requête BCS.Les paramètres suivants sont disponibles par défaut :- commandInterfaceName
- Le nom de l'interface de commande de contrôleur.
- profileName
- Le nom de profil de la commande de contrôleur dans la configuration.
- responseFormat
- Le format de réponse à utiliser pour générer le résultat.
- paramOverrideMap
- Définit tous les paramètres que vous souhaitez ajouter ou remplacer à partir de l'objet de requête associé à ce gestionnaire.
public JSONObject executeConfigBasedCommand(String pCmdInterfaceName, String profileName, String responseFormat, String storeId, Map<String, Object> paramOverrideMap) throws ExceptionCette méthode traite une requête de commande de contrôleur à l'aide des mappages de profil basés sur la configuration. Elle suppose que
{@link BusinessContextService}est traité par l'appleantLes paramètres d'entrée sont automatiquement complétés en fonction des paramètres de chemin d'accès spécifiés dans l'URL, suivis de n'importe quel paramètre qui se trouve dans le corps de la requête.
Une mappe de remplacement peut être fournie pour injecter plus de paramètres ou remplacer les paramètres préexistants.
Bien que l'ID de magasin soit spécifié dans l'appel de méthode, il n'est pas automatiquement inclus dans la liste des paramètres fournis pour remplir les méthodes d'accès set de la commande. Vous devez l'ajouter explicitement à la mappe de remplacement ou l'inclure avec les paramètres du chemin d'accès de l'URL ou le corps de la requête.
- pCmdInterfaceName
- Le nom de l'interface de commande du contrôleur.
- profileName
- Le nom de profil de la commande de contrôleur dans la configuration.
- responseFormat
- Le format de réponse à utiliser pour générer le résultat.
- storeId
- ID du magasin.
- paramOverrideMap
- Définit tous les paramètres que vous souhaitez ajouter ou remplacer à partir de l'objet de requête associé à ce gestionnaire.
-
Créez les fichiers de mappage XML à l'aide de l'utilitaire restClassicSampleGen ou manuellement.
- Recommandation : A l'aide de l'utilitaire restClassicSampleGen :
Accédez au répertoire WCDE_installdir\bin et exécutez l'utilitaire :
restClassicSampleGen.bat searchType=searchType basePackage=basePackage locationType=locationType location=location outputDir=outputDir classTypes=classTypes inputPrefix=inputPrefix sampleDepth=sampleDepth additionalClassPath=additionalClassPath
Où :- searchType
- Utilisez ABSOLUTE lorsque vous indiquez explicitement les classes pour lesquelles générer des mappages.
- basePackage
- Le package Java de base (à l'exclusion de la dernière période) pour lequel générer des mappages.
- locationType
- Utilisez FILE pour spécifier qu'un fichier contenant des entrées séparées par des lignes de modèles d'expression régulière Java ou de classes explicites au format com/example/MyClass.java est utilisé .
- emplacement
- Si la valeur locationType FILE a été spécifiée, il s'agit du chemin d'accès au fichier.
- outputDir
- Le répertoire de sortie. Ce répertoire est créé s'il n'existe pas. Les sous-répertoires sont créés pour chaque type de classe généré.
- classTypes
- Une ou plusieurs des valeurs séparées par des virgules DATABEAN, CONTROLLERCOMMAND et ALL.
- inputPrefix
- Spécifie les caractères pour préfixer les paramètres d'entrée dans le fichier de mappage.
- sampleDepth
- Profondeur des mappages à créer lors de la traversée récursive des classes.
- additionalClassPath
- Spécifie les fichiers JAR et les répertoires supplémentaires à inclure pour localiser les classes, qui sont séparées par ;.
Remarque :- Si des espaces sont utilisés dans l'une des valeurs de la propriété, vous devez entourer l'ensemble de la propriété et de la valeur avec des guillemets. Par exemple, "property1=value 1".
- Les valeurs prédéfinies telles que ABSOLUTE sont insensibles à la casse.
Par exemple :- Pour générer un mappage pour le bean de données spécifié :
restClassicSampleGen.bat location=com.ibm.commerce.catalog.beans.AttributeFloatValueDataBean outputDir=C:/Temp/ClassicSamples - Pour générer des mappages pour les beans de données uniquement, à partir du package de base
com.example.myclasses, en spécifiant un modèle directement en tant que propriété, et en ajoutant à tous les paramètres d'entrée le préfixe q :restClassicSampleGen.bat searchType=pattern basePackage=com.example.myclasses classTypes=DATABEAN "location=.*" inputPrefix=q outputDir=C:/Temp/ClassicSamples - Pour générer les classes spécifiées dans un fichier, avec une profondeur de mappage de 1. Ensuite, ajoutez un fichier JAR et un répertoire au chemin d'accès de classe pour localiser les classes :
restClassicSampleGen.bat locationType=file "location=C:/users/admin/mapping list.txt" sampleDepth=1 "additionalClassPath=c:/lib/MyJar.jar;c:/classdir" outputDir=c:/users/admin/samples
Assurez-vous que l'utilitaire s'exécute correctement. Consultez le fichier WCDE_installdir\logs\restclassic.log pour en savoir plus.
- Sinon, pour créer manuellement les fichiers de mappage XML, créez des fichiers de mappage qui ressemblent aux exemples suivants et enregistrez-les aux emplacements suivants :
- Rest.war/WebContent/WEB-INF/config/beanMapping-ext
- Le répertoire sert à publier de nouveaux beans de données, ou étendre les beans de données existants.
- Rest.war/WebContent/WEB-INF/config/commandMapping-ext
- Le répertoire sert à publier de nouvelles commandes de contrôleur ou à étendre les commandes de contrôleur existantes.
Exemple de fichier de mappage de beans de données (com.ibm.commerce.catalog.beans.CatalogEntryDataBean.xml) :<?xml version="1.0" encoding="UTF-8"?> <bean> <profiles> <profile name="sample"> <inputs> <input inputName="associationType" methodName="setAssociationType"/> <input inputName="attachmentUsage" methodName="setAttachmentUsage"/> <input inputName="availabilityDate" methodName="setAvailabilityDate"/> <input inputName="baseItemId" methodName="setBaseItemId"/> <input inputName="buyable" methodName="setBuyable"/> <input inputName="catalogEntryID" methodName="setCatalogEntryID"/> <input inputName="compactProperties" methodName="setCompactProperties"/> <input inputName="description" methodName="setDescription"/> <input inputName="discontinueDate" methodName="setDiscontinueDate"/> <input inputName="endDate" methodName="setEndDate"/> <input inputName="endOfServiceDate" methodName="setEndOfServiceDate"/> <input inputName="field1" methodName="setField1"/> <input inputName="field2" methodName="setField2"/> <input inputName="field3" methodName="setField3"/> <input inputName="field4" methodName="setField4"/> <input inputName="field5" methodName="setField5"/> <input inputName="initKey_catalogEntryReferenceNumber" methodName="setInitKey_catalogEntryReferenceNumber"/> <input inputName="itemspc_id" methodName="setItemspc_id"/> <input inputName="language_id" methodName="setLanguage_id"/> <input inputName="lastOrderDate" methodName="setLastOrderDate"/> <input inputName="lastUpdate" methodName="setLastUpdate"/> <input inputName="manufacturerName" methodName="setManufacturerName"/> <input inputName="manufacturerPartNumber" methodName="setManufacturerPartNumber"/> <input inputName="markForDelete" methodName="setMarkForDelete"/> <input inputName="memberId" methodName="setMemberId"/> <input inputName="oid" methodName="setOid"/> <input inputName="onAuction" methodName="setOnAuction"/> <input inputName="onSpecial" methodName="setOnSpecial"/> <input inputName="partNumber" methodName="setPartNumber"/> <input inputName="shipping" methodName="setShipping"/> <input inputName="startDate" methodName="setStartDate"/> <input inputName="state" methodName="setState"/> <input inputName="url" methodName="setUrl"/> </inputs> <outputs> <output methodName="getApplicableContractIds" outputName="applicableContractIds"/> <output methodName="getAvailabilityDate" outputName="availabilityDate"/> <output methodName="getAvailabilityDay" outputName="availabilityDay"/> <output methodName="getAvailabilityMonth" outputName="availabilityMonth"/> <output methodName="getAvailabilityYear" outputName="availabilityYear"/> <output methodName="getBaseItemIdInEJBType" outputName="baseItemId"/> <output methodName="getBuyableInEJBType" outputName="buyable"/> <output methodName="getCatalogEntryID" outputName="catalogEntryID"/> <output methodName="getCatalogEntryReferenceNumberInEJBType" outputName="catalogEntryReferenceNumber"/> <output methodName="getDiscontinueDate" outputName="discontinueDate"/> <output methodName="getDiscontinueDay" outputName="discontinueDay"/> <output methodName="getDiscontinueMonth" outputName="discontinueMonth"/> <output methodName="getDiscontinueYear" outputName="discontinueYear"/> <output methodName="getEndDate" outputName="endDate"/> <output methodName="getEndDay" outputName="endDay"/> <output methodName="getEndMonth" outputName="endMonth"/> <output methodName="getEndOfServiceDate" outputName="endOfServiceDate"/> <output methodName="getEndOfServiceDay" outputName="endOfServiceDay"/> <output methodName="getEndOfServiceMonth" outputName="endOfServiceMonth"/> <output methodName="getEndOfServiceYear" outputName="endOfServiceYear"/> <output methodName="getEndYear" outputName="endYear"/> <output methodName="getField1InEJBType" outputName="field1"/> <output methodName="getField2InEJBType" outputName="field2"/> <output methodName="getField3InEJBType" outputName="field3"/> <output methodName="getField4" outputName="field4"/> <output methodName="getField5" outputName="field5"/> <output methodName="getFormattedAvailabilityDate" outputName="formattedAvailabilityDate"/> <output methodName="getFormattedDiscontinueDate" outputName="formattedDiscontinueDate"/> <output methodName="getFormattedEndDate" outputName="formattedEndDate"/> <output methodName="getFormattedEndOfServiceDate" outputName="formattedEndOfServiceDate"/> <output methodName="getFormattedLastOrderDate" outputName="formattedLastOrderDate"/> <output methodName="getFormattedStartDate" outputName="formattedStartDate"/> <output methodName="isAnyMerchandisingAssociated" outputName="isAnyMerchandisingAssociated"/> <output methodName="isBundle" outputName="isBundle"/> <output methodName="isCalculatedContractPriced" outputName="isCalculatedContractPriced"/> <output methodName="isCatalogEntryAllowedPriceRanges" outputName="isCatalogEntryAllowedPriceRanges"/> <output methodName="isDynamicKit" outputName="isDynamicKit"/> <output methodName="isItem" outputName="isItem"/> <output methodName="isListPriced" outputName="isListPriced"/> <output methodName="isMerchandisingAssociated" outputName="isMerchandisingAssociated"/> <output methodName="isPackage" outputName="isPackage"/> <output methodName="isProduct" outputName="isProduct"/> <output methodName="getItemspc_idInEJBType" outputName="itemspc_id"/> <output methodName="getLanguage_idInEJBType" outputName="language_id"/> <output methodName="getLastOrderDate" outputName="lastOrderDate"/> <output methodName="getLastOrderDay" outputName="lastOrderDay"/> <output methodName="getLastOrderMonth" outputName="lastOrderMonth"/> <output methodName="getLastOrderYear" outputName="lastOrderYear"/> <output methodName="getLastUpdateInEJBType" outputName="lastUpdate"/> <output methodName="getManufacturerName" outputName="manufacturerName"/> <output methodName="getManufacturerPartNumber" outputName="manufacturerPartNumber"/> <output methodName="getMarkForDeleteInEJBType" outputName="markForDelete"/> <output methodName="getMemberIdInEJBType" outputName="memberId"/> <output methodName="getObjectPath" outputName="objectPath"/> <output methodName="getOid" outputName="oid"/> <output methodName="getOnAuctionInEJBType" outputName="onAuction"/> <output methodName="getOnSpecialInEJBType" outputName="onSpecial"/> <output methodName="getParentCatalogEntryIds" outputName="parentCatalogEntryIds"/> <output methodName="getPartNumber" outputName="partNumber"/> <output methodName="getStartDate" outputName="startDate"/> <output methodName="getStartDay" outputName="startDay"/> <output methodName="getStartMonth" outputName="startMonth"/> <output methodName="getStartYear" outputName="startYear"/> <output methodName="getState" outputName="state"/> <output methodName="getType" outputName="type"/> <output methodName="getUrl" outputName="url"/> </outputs> </profile> </profiles> </bean>Exemple de fichier de mappage de commande de contrôleur (com.ibm.commerce.catalogmanagement.commands.CatalogEntryUpdateCmd.xml) :<?xml version="1.0" encoding="UTF-8"?> <command> <profiles> <profile name="sample"> <inputs> <input inputName="URL" methodName="setURL"/> <input inputName="XMLdetail" methodName="setXMLdetail"/> <input inputName="auxdescription1" methodName="setAuxdescription1"/> <input inputName="auxdescription2" methodName="setAuxdescription2"/> <input inputName="availabilityDate" methodName="setAvailabilityDate"/> <input inputName="availabilitydate" methodName="setAvailabilitydate"/> <input inputName="available" methodName="setAvailable"/> <input inputName="buyable" methodName="setBuyable"/> <input inputName="catEntURL" methodName="setCatEntURL"/> <input inputName="catentryId" methodName="setCatentryId"/> <input inputName="descLanguage" methodName="setDescLanguage"/> <input inputName="discontinueDate" methodName="setDiscontinueDate"/> <input inputName="endDate" methodName="setEndDate"/> <input inputName="endOfServiceDate" methodName="setEndOfServiceDate"/> <input inputName="expirationdate" methodName="setExpirationdate"/> <input inputName="field1" methodName="setField1"/> <input inputName="field2" methodName="setField2"/> <input inputName="field3" methodName="setField3"/> <input inputName="field4" methodName="setField4"/> <input inputName="field5" methodName="setField5"/> <input inputName="fullimage" methodName="setFullimage"/> <input inputName="keyword" methodName="setKeyword"/> <input inputName="lastOrderDate" methodName="setLastOrderDate"/> <input inputName="longdescription" methodName="setLongdescription"/> <input inputName="markfordelete" methodName="setMarkfordelete"/> <input inputName="memberId" methodName="setMemberId"/> <input inputName="mfname" methodName="setMfname"/> <input inputName="mfpartnumber" methodName="setMfpartnumber"/> <input inputName="name" methodName="setName"/> <input inputName="onauction" methodName="setOnauction"/> <input inputName="onspecial" methodName="setOnspecial"/> <input inputName="partnumber" methodName="setPartnumber"/> <input inputName="published" methodName="setPublished"/> <input inputName="shortdescription" methodName="setShortdescription"/> <input inputName="startDate" methodName="setStartDate"/> <input inputName="thumbnail" methodName="setThumbnail"/> </inputs> <outputs> <output methodName="getCatentryId" outputName="catentryId"/> <output methodName="getPartnumber" outputName="partnumber"/> </outputs> </profile> </profiles> </command>
- Recommandation : A l'aide de l'utilitaire restClassicSampleGen :