目的是使用 java 代码和 Sites REST API 创建资产。
首先,我在 11.1.1.8.0 站点或 JSK 的安装甚至源目录中都找不到 REST API 示例。相反,我在 11.1.1.6.0 服务器中找到了样本。
我在 POST 和 PUT 方法中更改基本 URL 后运行的代码:
/*
* $Logfile:$ $Revision:$ $Date:$ Copyright © 2010 FatWire Corporation, All
* Rights Reserved. Copyright 2010 FatWire Corporation. Title, ownership rights,
* and intellectual property rights in and to this software remain with FatWire
* Corporation. This software is protected by international copyright laws and
* treaties, and may be protected by other law. Violation of copyright laws may
* result in civil liability and criminal penalties.
*/
package com.fatwire.rest.samples.flex;
import javax.ws.rs.core.MediaType;
import com.fatwire.rest.beans.AssetBean;
import com.fatwire.rest.beans.Attribute;
import com.fatwire.rest.beans.Attribute.Data;
import com.fatwire.rest.beans.ErrorBean;
import com.fatwire.rest.beans.Parent;
import com.fatwire.wem.sso.SSO;
import com.fatwire.wem.sso.SSOException;
import com.fatwire.wem.sso.SSOSession;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.UniformInterfaceException;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.WebResource.Builder;
import com.fatwire.wem.sso.cas.conf.CASConfig;
/**
* <p>
* Sample JAVA class to demonstrate creation of new Flex assets using REST API
* exposed by Fatwire WEM module.
* </p>
* <p>
* For this class to function, the following are the pre-requisites:
* <ol>
* <li>The following jars are required in the classpath:
* <ul>
* <li>rest-api.jar</li>
* <li>wem-sso-api.jar</li>
* <li>jersey-client.jar</li>
* <li>jsr311-api.jar</li>
* <li>jersey-client.jar</li>
* <li>jersey-core.jar</li>
* </ul>
* </li>
* <li>The following configuration file is required in the classpath (in the
* example, the above file is referred to as <tt>ExampleCASConfig.xml</tt>.):
*
* <pre>
* <?xml version="1.0" encoding="UTF-8"?>
* <beans
* xmlns="http://www.springframework.org/schema/beans"
* xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
* xmlns:context="http://www.springframework.org/schema/context"
* xsi:schemaLocation="http://www.springframework.org/schema/beans
* http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
* http://www.springframework.org/schema/context
* http://www.springframework.org/schema/context/spring-context-2.5.xsd">
* <!-- DONOT CHANGE: Single Sign On provider -->
* <bean id="ssoprovider" class="com.fatwire.wem.sso.cas.CASProvider">
* <property name="config" ref="ssoconfig" />
* </bean>
* <!--
* Single Sign On configuration: change ONLY the following property:
* casUrl - URL of the CAS installation
* -->
* <bean id="ssoconfig" class="com.fatwire.wem.sso.cas.conf.CASConfig">
* <property name="casUrl" value="${cas-url}" />
* <property name="casRestPath" value="/v1" />
* </bean>
* </beans>
* </pre>
*
* </li>
* <li>The Content Server Installation must have the "FirstSiteII" sample site
* and the "Product_C" asset type. "Product_C" should be enabled in
* "FirstSiteII". There should not be an asset by the name of "Test Product_C"
* which is the name of the test asset.</li>
* </ol>
*
* @author Saikat Chaudhuri
*/
public final class CreateAsset
{
/**
* Main method. Run this method to create a basic asset using:
* <ul>
* <li>{@link #createUsingPut()}</li>
* <li>{@link #createUsingPost()}</li>
* </ul>
*
* @param args
*/
public static void main(String[] args)
{
createUsingPut();
// createUsingPost();
}
/**
* Run this method to create a basic asset using PUT.
*/
public static void createUsingPut()
{
// Step 1: Initiate Jersey client
Client client = Client.create();
// Step 2: Create a WebResource with the base URL
WebResource webResource =
client.resource("http://127.0.0.1:9080/cs/REST");
// Step 3: Authenticate over SSO-CAS to acquire a ticket specific to a
// service or a multi-ticket over multiple services.
SSOSession ssoSession = null;
String multiticket = null;
try
{
ssoSession = SSO.getSSOSession("ExampleCASConfig.xml");
multiticket = ssoSession.getMultiTicket("fwadmin", "xceladmin");
}
catch (SSOException e)
{
// Troubleshooting SSOException
// ============================
//
// Cause: CAS is not running.
// Remedy: Deploy CAS and start up the application server for CAS
// webapp.
//
// Cause: CAS is not configured.
// Remedy: Verify that the URL in the CAS config file,
// ExampleCASConfig.xml, is reachable.
//
// Cause: Username / password is invalid.
// Remedy: Use valid username / password to authenticate against
// CAS.
// Handle exception
e.printStackTrace();
}
// Step 4: Provide the ticket into the REST request
webResource = webResource.queryParam("multiticket", multiticket);
// Trying to create a Flex asset for the Flex asset type
// "Product_C" in the CS site "FirstSiteII"
String flexAssetSiteName = "FirstSiteII";
String flexAssetTypeName = "Product_C";
// Step 5: Specify the REST Resource URL into the WebResource
// For creating assets of type {typename} in the CS site {sitename},
// this is: {base_url}/sites/{sitename}/types/{typename}/assets/0
webResource =
webResource.path("sites").path(flexAssetSiteName).path("types")
.path(flexAssetTypeName).path("assets").path("0");
// Step 6: Create a Builder and set the desired response type
// Supported response types are:
// MediaType.APPLICATION_XML, or,
// MediaType.APPLICATION_JSON
Builder builder = webResource.accept(MediaType.APPLICATION_XML);
// Step 7: Instantiate and define the AssetBean for the asset
AssetBean sourceAsset = new AssetBean();
// Name - mandatory field
sourceAsset.setName("Test Product_C PUT");
// Description - optional field
sourceAsset.setDescription("Test Product_C PUT description");
// Add attributes / associations / parents as in the Asset type
// definition
Attribute sourceAssetAttribute = new Attribute();
Data sourceAssetAttributeData = new Data();
sourceAssetAttribute.setName("FSIISKU");
sourceAssetAttributeData.setStringValue("Test SKU");
sourceAssetAttribute.setData(sourceAssetAttributeData);
sourceAsset.getAttributes().add(sourceAssetAttribute);
sourceAssetAttribute = new Attribute();
sourceAssetAttributeData = new Data();
sourceAssetAttribute.setName("FSIILongDescription");
sourceAssetAttributeData.setStringValue("Test Long Description");
sourceAssetAttribute.setData(sourceAssetAttributeData);
sourceAsset.getAttributes().add(sourceAssetAttribute);
sourceAssetAttribute = new Attribute();
sourceAssetAttributeData = new Data();
sourceAssetAttribute.setName("FSIIPrice");
sourceAssetAttributeData.setDoubleValue(10.00);
sourceAssetAttribute.setData(sourceAssetAttributeData);
sourceAsset.getAttributes().add(sourceAssetAttribute);
sourceAssetAttribute = new Attribute();
sourceAssetAttributeData = new Data();
sourceAssetAttribute.setName("FSIIImage");
sourceAssetAttributeData.setStringValue("Media_C:1114083738411");
sourceAssetAttribute.setData(sourceAssetAttributeData);
sourceAsset.getAttributes().add(sourceAssetAttribute);
Parent parent = new Parent();
parent.setParentDefName("FSIIManufacturer");
parent.getAssets().add("Product_P:1114083739006");
sourceAsset.getParents().add(parent);
parent = new Parent();
parent.setParentDefName("FSIISubcategory");
parent.getAssets().add("Product_P:1114083739104");
sourceAsset.getParents().add(parent);
// Required: Must specify the site(s) for the asset
sourceAsset.getPublists().add(flexAssetSiteName);
// Required: Must specify the sub type for the Flex asset type
sourceAsset.setSubtype("FSII Product");
// Step 8: Invoke the REST request to create the asset
AssetBean resultAsset = builder.put(AssetBean.class, sourceAsset);
// If the REST call encounter a server side exception, the client
// receives a UniformInterfaceException at runtime.
// Troubleshooting UniformInterfaceException
// =========================================
//
// Cause: HTTP 403: User does not have permission to access the REST
// resource.
// Remedy: Use an authorized CAS user to use this REST resource.
//
// Cause: HTTP 404: Either site and/or asset type does not exist, or the
// asset type is not enabled in the site.
// Remedy: Verify existence of the site and/or asset type, if necessary
// create the site and/or type and make sure that the type is enabled in
// the site.
//
// Cause: HTTP 500: Generic server side exception.
// Remedy: Verify that the source AssetBean has been provided with all
// mandatory attributes, associations as per type definition, verify
// that at least one site has been provided in the publist attribute of
// the AssetBean.
//
// Cause: UnmarshalException.
// Remedy: Verify that the correct bean has been provided in the
// argument for put().
}
/**
* Run this method to create a basic asset using POST.
*/
public static void createUsingPost()
{
// Step 1: Initiate Jersey client
Client client = Client.create();
// Step 2: Create a WebResource with the base URL
WebResource webResource =
client.resource("http://127.0.0.1:9080/cs/REST");
// Step 3: Authenticate over SSO-CAS to acquire a ticket specific to a
// service or a multi-ticket over multiple services.
SSOSession ssoSession = null;
String multiticket = null;
try
{
ssoSession = SSO.getSSOSession("ExampleCASConfig.xml");
multiticket = ssoSession.getMultiTicket("fwadmin", "xceladmin");
}
catch (SSOException e)
{
// Troubleshooting SSOException
// ============================
//
// Cause: CAS is not running.
// Remedy: Deploy CAS and start up the application server for CAS
// webapp.
//
// Cause: CAS is not configured.
// Remedy: Verify that the URL in the CAS config file,
// ExampleCASConfig.xml, is reachable.
//
// Cause: Username / password is invalid.
// Remedy: Use valid username / password to authenticate against
// CAS.
// Handle exception
e.printStackTrace();
}
// Step 4: Provide the ticket into the REST request
webResource = webResource.queryParam("multiticket", multiticket);
// Trying to create a Flex asset for the Flex asset type
// "Product_C" in the CS site "FirstSiteII"
String flexAssetSiteName = "FirstSiteII";
String flexAssetTypeName = "Product_C";
// Step 5: Specify the REST Resource URL into the WebResource
// For creating assets of type {typename} in the CS site {sitename},
// this is: {base_url}/sites/{sitename}/types/{typename}/assets
webResource =
webResource.path("sites").path(flexAssetSiteName).path("types")
.path(flexAssetTypeName).path("assets");
// Step 6: Create a Builder and set the desired response type
// Supported response types are:
// MediaType.APPLICATION_XML, or,
// MediaType.APPLICATION_JSON
Builder builder = webResource.accept(MediaType.APPLICATION_XML);
// Step 7: Instantiate and define the AssetBean for the asset
AssetBean sourceAsset = new AssetBean();
// Name - mandatory field
sourceAsset.setName("Test Product_C POST");
// Description - optional field
sourceAsset.setDescription("Test Product_C POST description");
// Add attributes / associations / parents as in the Asset type
// definition
Attribute sourceAssetAttribute = new Attribute();
Data sourceAssetAttributeData = new Data();
sourceAssetAttribute.setName("FSIISKU");
sourceAssetAttributeData.setStringValue("Test SKU");
sourceAssetAttribute.setData(sourceAssetAttributeData);
sourceAsset.getAttributes().add(sourceAssetAttribute);
sourceAssetAttribute = new Attribute();
sourceAssetAttributeData = new Data();
sourceAssetAttribute.setName("FSIILongDescription");
sourceAssetAttributeData.setStringValue("Test Long Description");
sourceAssetAttribute.setData(sourceAssetAttributeData);
sourceAsset.getAttributes().add(sourceAssetAttribute);
sourceAssetAttribute = new Attribute();
sourceAssetAttributeData = new Data();
sourceAssetAttribute.setName("FSIIPrice");
sourceAssetAttributeData.setDoubleValue(10.00);
sourceAssetAttribute.setData(sourceAssetAttributeData);
sourceAsset.getAttributes().add(sourceAssetAttribute);
sourceAssetAttribute = new Attribute();
sourceAssetAttributeData = new Data();
sourceAssetAttribute.setName("FSIIImage");
sourceAssetAttributeData.setStringValue("Media_C:1114083738411");
sourceAssetAttribute.setData(sourceAssetAttributeData);
sourceAsset.getAttributes().add(sourceAssetAttribute);
Parent parent = new Parent();
parent.setParentDefName("FSIIManufacturer");
parent.getAssets().add("Product_P:1114083739006");
sourceAsset.getParents().add(parent);
parent = new Parent();
parent.setParentDefName("FSIISubcategory");
parent.getAssets().add("Product_P:1114083739104");
sourceAsset.getParents().add(parent);
// Required: Must specify the site(s) for the asset
sourceAsset.getPublists().add(flexAssetSiteName);
// Required: Must specify the sub type for the Flex asset type
sourceAsset.setSubtype("FSII Product");
// Step 8: Invoke the REST request to create the asset
ClientResponse resp = builder.post(ClientResponse.class, sourceAsset);
// The "Location" header provides the element URI
// which can be used to read back the asset which was created.
String elementURI = resp.getHeaders().get("Location").get(0);
// If the REST call encounter a server side exception, the client
// receives a UniformInterfaceException at runtime.
// Troubleshooting UniformInterfaceException
// =========================================
//
// Cause: HTTP 403: User does not have permission to access the REST
// resource.
// Remedy: Use an authorized CAS user to use this REST resource.
//
// Cause: HTTP 404: Either site and/or asset type does not exist, or the
// asset type is not enabled in the site.
// Remedy: Verify existence of the site and/or asset type, if necessary
// create the site and/or type and make sure that the type is enabled in
// the site.
//
// Cause: HTTP 500: Generic server side exception.
// Remedy: Verify that the source AssetBean has been provided with all
// mandatory attributes, associations as per type definition, verify
// that at least one site has been provided in the publist attribute of
// the AssetBean.
//
// Cause: UnmarshalException.
// Remedy: Verify that the correct bean has been provided in the
// argument for post().
}
}
添加 JAR 我在 JSK 安装目录中的示例注释中搜索了每个 JAR 名称并添加了它们。
罐子:
- jersey-client-1.1.4.1.jar
- jersey-core-1.1.4.1.jar
- jsr311-api-1.1.1.jar
- 休息-api-11.1.1.8.0.jar
- wem-sso-api-11.1.1.8.0.jar
显然,我们还需要这些 JAR,但未提及:
- cas-client-core-3.1.9.jar
- wem-sso-api-cas-11.1.1.8.0.jar
- 春天2.5.6.jar
- commons-logging-1.1.1.jar
从源代码注释中,我提取了用作 spring 配置的 XML 文件,在 ssoconfig bean 中添加了 casUrl 值,并将 casRestPath 的属性名称更改为 restPath,因为它在类中不存在。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!-- DONOT CHANGE: Single Sign On provider -->
<bean id="ssoprovider" class="com.fatwire.wem.sso.cas.CASProvider">
<property name="config" ref="ssoconfig"/>
</bean>
<!-- Single Sign On configuration: change ONLY the following property: casUrl
- URL of the CAS installation -->
<bean id="ssoconfig" class="com.fatwire.wem.sso.cas.conf.CASConfig">
<property name="casUrl" value="http://127.0.0.1:9080/cas" />
<property name="restPath" value="/v1" />
</bean>
</beans>
我运行 POST 方法的异常:
Jan 08, 2014 5:43:50 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@4c08964: startup date [Wed Jan 08 17:43:50 GMT+02:00 2014]; root of context hierarchy
Jan 08, 2014 5:43:50 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [ExampleCASConfig.xml]
Jan 08, 2014 5:43:50 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@3c200d0: defining beans [ssoprovider,ssoconfig]; root of factory hierarchy
Exception in thread "main" com.sun.jersey.api.client.UniformInterfaceException: PUT http://127.0.0.1:9080/cs/REST/sites/FirstSiteII/types/Product_C/assets/0?multiticket=multi-ST-39-DPgghOvnBCAAggKLAHpa-_tmp_1374099243365 returned a response status of 401
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:563)
at com.sun.jersey.api.client.WebResource.access$300(WebResource.java:69)
at com.sun.jersey.api.client.WebResource$Builder.put(WebResource.java:475)
at com.fatwire.rest.samples.flex.CreateAsset.createUsingPut(CreateAsset.java:222)
at com.fatwire.rest.samples.flex.CreateAsset.main(CreateAsset.java:97)
在调试时,我发现响应返回状态为 401 。
我运行 PUT 方法的异常:
Jan 09, 2014 12:03:36 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@4c08964: startup date [Thu Jan 09 12:03:36 GMT+02:00 2014]; root of context hierarchy
Jan 09, 2014 12:03:36 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [ExampleCASConfig.xml]
Jan 09, 2014 12:03:36 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@3c200d0: defining beans [ssoprovider,ssoconfig]; root of factory hierarchy
Exception in thread "main" com.sun.jersey.api.client.UniformInterfaceException: PUT http://127.0.0.1:9080/cs/REST/sites/FirstSiteII/types/Product_C/assets/0?multiticket=multi-ST-7-kejMYvRWO1cua39MfPYn-_tmp_1374099243365 returned a response status of 401
at com.sun.jersey.api.client.WebResource.handle(WebResource.java:563)
at com.sun.jersey.api.client.WebResource.access$300(WebResource.java:69)
at com.sun.jersey.api.client.WebResource$Builder.put(WebResource.java:475)
at com.fatwire.rest.samples.flex.CreateAsset.createUsingPut(CreateAsset.java:222)
at com.fatwire.rest.samples.flex.CreateAsset.main(CreateAsset.java:97)
没有与代码中的资产同名的现有资产。fwadmin 用户经过测试,但 JSK 的默认配置以及将其添加到所有安全组和角色(当然包括 REST)之后。样本中所有使用的资产 ID/s(用于父母等)检查,它们存在。