Im doing restfull webservices with soap using websphere and RAD. After generating my javaclient classes when I run the test class I get the following error. Ive been searching the web but not finding the correct solution. PLEASE HELP!
ERROR:
Check method call
org.w3c.dom.DOMException: HIERARCHY_REQUEST_ERR: An attempt was made to insert a node where it is not permitted.
at org.apache.xerces.dom.CoreDocumentImpl.insertBefore(Unknown Source)
at org.apache.xerces.dom.NodeImpl.appendChild(Unknown Source)
at com.ibm.ws.webservices.engine.xmlsoap.SOAPPart.appendChild(SOAPPart.java:282)
at com.sun.xml.internal.bind.marshaller.SAX2DOMEx.startElement(SAX2DOMEx.java:177)
at com.sun.xml.internal.ws.message.AbstractMessageImpl.writeTo(AbstractMessageImpl.java:159)
at com.sun.xml.internal.ws.message.AbstractMessageImpl.readAsSOAPMessage(AbstractMessageImpl.java:194)
at com.sun.xml.internal.ws.handler.SOAPMessageContextImpl.getMessage(SOAPMessageContextImpl.java:80)
at test.CustomSoapHandler.handleMessage(CustomSoapHandler.java:37)
at test.CustomSoapHandler.handleMessage(CustomSoapHandler.java:1)
at com.sun.xml.internal.ws.handler.HandlerProcessor.callHandleMessage(HandlerProcessor.java:293)
at com.sun.xml.internal.ws.handler.HandlerProcessor.callHandlersRequest(HandlerProcessor.java:134)
at com.sun.xml.internal.ws.handler.ClientSOAPHandlerTube.callHandlersOnRequest(ClientSOAPHandlerTube.java:139)
at com.sun.xml.internal.ws.handler.HandlerTube.processRequest(HandlerTube.java:117)
at com.sun.xml.internal.ws.api.pipe.Fiber.__doRun(Fiber.java:599)
at com.sun.xml.internal.ws.api.pipe.Fiber._doRun(Fiber.java:558)
at com.sun.xml.internal.ws.api.pipe.Fiber.doRun(Fiber.java:543)
at com.sun.xml.internal.ws.api.pipe.Fiber.runSync(Fiber.java:440)
at com.sun.xml.internal.ws.client.Stub.process(Stub.java:223)
at com.sun.xml.internal.ws.client.sei.SEIStub.doProcess(SEIStub.java:136)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:110)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:90)
at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:119)
at $Proxy33.getHistory(Unknown Source)
at test.ServiceTest.historyTest(ServiceTest.java:64)
at test.ServiceTest.main(ServiceTest.java:100)
Exception in thread "main" java.lang.ExceptionInInitializerError
at java.lang.J9VMInternals.initialize(J9VMInternals.java:227)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:119)
at com.sun.xml.internal.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:90)
at com.sun.xml.internal.ws.client.sei.SEIStub.invoke(SEIStub.java:119)
at $Proxy33.getHistory(Unknown Source)
at test.ServiceTest.historyTest(ServiceTest.java:64)
at test.ServiceTest.main(ServiceTest.java:100)
Caused by: java.lang.ClassCastException: com.ibm.xml.xlxp2.jaxb.JAXBContextImpl incompatible with com.sun.xml.internal.bind.api.JAXBRIContext
at java.lang.ClassCastException.<init>(ClassCastException.java:58)
at com.sun.xml.internal.ws.fault.SOAPFaultBuilder.<clinit>(SOAPFaultBuilder.java:545)
at java.lang.J9VMInternals.initializeImpl(Native Method)
at java.lang.J9VMInternals.initialize(J9VMInternals.java:205)
... 6 more
Test Class:
package test;
import be.ipc.css.ws.GcssWebServiceService;
import be.ipc.css.ws.IGcssWebService;
import be.ipc.css.ws.InvalidItemIdStructureFault_Exception;
import be.ipc.css.ws.ProductNotAllowedFault_Exception;
import be.ipc.css.ws.common.Product;
import be.ipc.css.ws.history.GetHistoryInput;
import be.ipc.css.ws.history_output.GetHistoryOutput;
import be.ipc.css.ws.history_output.HistoryItem;
import be.ipc.css.ws.history_output.Type;
import javax.xml.namespace.QName;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Service;
import javax.xml.ws.handler.Handler;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
/**
* <strong>Project: TODO: project name</strong><br/>
* <b>Url:</b> TODO: url<br/>
* <b>Date:</b> 15.05.14<br/>
* <b>Time:</b> 23:42 <br/>
* Copyright(C) 2014 IT Service Plus <br/>
* <b>Description:</b><br/>
* TODO: description
*/
public class ServiceTest {
private static Service webService;
private static IGcssWebService servicePort;
public void initService() throws MalformedURLException {
URL url = new URL("http://cs-demo.ipc.be/CSS_UA2/services/gcssWebService/1.0");
QName qname = new QName("http://ws.css.ipc.be/", "GcssWebServiceService");
/*java.util.Properties props = System.getProperties();
props.setProperty("http.proxyHost", "proxy.test.com");
props.setProperty("http.proxyPort", "8080");*/
webService = GcssWebServiceService.create(url, qname);
servicePort = webService.getPort(IGcssWebService.class);
try {
CustomSoapHandler sh = new CustomSoapHandler("user_us", "*******");
List<Handler> new_handlerChain = new ArrayList<Handler>();
new_handlerChain.add(sh);
((BindingProvider)servicePort).getBinding().setHandlerChain(new_handlerChain);
} catch (Throwable e) {
e.printStackTrace();
}
//((BindingProvider)servicePort).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "user_us");
//((BindingProvider)servicePort).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "*******");
}
public void historyTest() throws ProductNotAllowedFault_Exception, InvalidItemIdStructureFault_Exception {
GetHistoryInput input = new GetHistoryInput();
input.setItemId("CC027607063NL");
input.setProduct(Product.EPG);
System.out.println("Check method call");
GetHistoryOutput output = servicePort.getHistory(input);
System.out.println("Check result");
//Assert.assertNotNull(output);
//Assert.assertNotNull(output.getHistory());
//Assert.assertNotNull(output.getHistory().getHistoryItem());
System.out.println("Received: " + output.getHistory().getHistoryItem().size() + "elements:");
System.out.println("-----------------------");
for(int i=0;i<output.getHistory().getHistoryItem().size();i++) {
HistoryItem it = output.getHistory().getHistoryItem().get(i);
System.out.println("#" + i + ": id=" + it.getId() + ", type=" + it.getType().value());
}
System.out.println("Check 3 history items");
//Assert.assertEquals(3, output.getHistory().getHistoryItem().size());
HistoryItem it1 = output.getHistory().getHistoryItem().get(0);
HistoryItem it2 = output.getHistory().getHistoryItem().get(1);
HistoryItem it3 = output.getHistory().getHistoryItem().get(2);
/*Assert.assertEquals(Type.QUMQ, it1.getType());
Assert.assertEquals(161L, it1.getId());
Assert.assertEquals(Type.SUM, it2.getType());
Assert.assertEquals(652L, it2.getId());
Assert.assertEquals(Type.L_1_Q, it3.getType());
Assert.assertEquals(13742L, it3.getId());*/
}
public static void main(String[] args) {
ServiceTest test = new ServiceTest();
try {
test.initService();
test.historyTest();
} catch(Exception e ){
e.printStackTrace();
}
}
}
Soap Handler:
package test;
import javax.xml.namespace.QName;
import javax.xml.soap.*;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import java.util.Set;
/**
* <strong>Project: TODO: project name</strong><br/>
* <b>Url:</b> TODO: url<br/>
* <b>Date:</b> 16.05.14<br/>
* <b>Time:</b> 0:48 <br/>
* Copyright(C) 2014 IT Service Plus <br/>
* <b>Description:</b><br/>
* TODO: description
*/
public class CustomSoapHandler implements SOAPHandler<SOAPMessageContext> {
private static final String AUTH_PREFIX = "wsse";
private static final String AUTH_NS =
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
private String username;
private String password;
public CustomSoapHandler(String username, String password) {
this.username = username;
this.password = password;
}
public boolean handleMessage(SOAPMessageContext context) {
try {
SOAPEnvelope envelope =
context.getMessage().getSOAPPart().getEnvelope();
SOAPFactory soapFactory = SOAPFactory.newInstance();
SOAPElement wsSecHeaderElm =
soapFactory.createElement("Security", AUTH_PREFIX, AUTH_NS);
Name wsSecHdrMustUnderstandAttr =
soapFactory.createName("mustUnderstand", "S",
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
wsSecHeaderElm.addAttribute(wsSecHdrMustUnderstandAttr, "1");
SOAPElement userNameTokenElm =
soapFactory.createElement("UsernameToken", AUTH_PREFIX,
AUTH_NS);
Name userNameTokenIdName =
soapFactory.createName("id", "wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
userNameTokenElm.addAttribute(userNameTokenIdName,
"UsernameToken-ORbTEPzNsEMDfzrI9sscVA22");
SOAPElement userNameElm =
soapFactory.createElement("Username", AUTH_PREFIX, AUTH_NS);
userNameElm.addTextNode(username);
SOAPElement passwdElm =
soapFactory.createElement("Password", AUTH_PREFIX, AUTH_NS);
Name passwdTypeAttr = soapFactory.createName("Type");
passwdElm.addAttribute(passwdTypeAttr,
"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
passwdElm.addTextNode(password);
userNameTokenElm.addChildElement(userNameElm);
userNameTokenElm.addChildElement(passwdElm);
wsSecHeaderElm.addChildElement(userNameTokenElm);
if (envelope.getHeader() == null) {
SOAPHeader sh = envelope.addHeader();
sh.addChildElement(wsSecHeaderElm);
} else {
SOAPHeader sh = envelope.getHeader();
sh.addChildElement(wsSecHeaderElm);
}
} catch (Throwable e) {
e.printStackTrace();
}
return true;
}
#Override
public boolean handleFault(SOAPMessageContext context) {
return false; //To change body of implemented methods use File | Settings | File Templates.
}
#Override
public void close(MessageContext context) {
//To change body of implemented methods use File | Settings | File Templates.
}
#Override
public Set<QName> getHeaders() {
return null;
}
}
The main reason for your error is incompatible JAXB implementation classes:
aused by: java.lang.ClassCastException: com.ibm.xml.xlxp2.jaxb.JAXBContextImpl incompatible with com.sun.xml.internal.bind.api.JAXBRIContext
Probably the best way to fix this is packaging your own version of JAXB within your application(inside the lib folder) and than change the class loader from WebSphere to be Parent Last.
After that, restart and try it again. If still doesn't work you can try adding your JAXB implementation libraries directly to the Application Server classloader. You can do that creating a directory under $WEBSPHERE_HOME/AppServer/classes and placing your JAXB implementation classes there. Be aware that this approach adds the dropped jars to all WebSphere instances running using this binary codebase.
You can learn more about WebSphere classloaders.
Hope this helps.
Related
I am using easymock framework to write UT's. I have one class which uses java.util.Properties in public function. Below is sample code:
public URI generateSASURI() throws CloudStorageException, DataProcessingException {
final String token = "token";
try {
return new URI(URIUtils.getAssetURI(azureStorageProperties.getProperty(StorageConstant.STORAGE_ACCOUNT_NAME)
, cloudBlob).toString() + "?" + token);
} catch (URISyntaxException e) {
throw new DataProcessingException("Error while creating SAS URL " + e.getMessage(), e);
}
}
where azureStorageProperties is instance of java.util.Properties, which is created as bean and injected in class.
Now while writing unit test case , i am trying to mock Properties azureStorageProperties, i am getting below error:
Unable to evaluate the expression Method threw 'java.lang.IllegalStateException' exception.
Below is ss:
Below is class to be tested:
package com.company.ops.azure.storage;
import com.company.ops.azure.storage.constants.StorageConstant;
import com.company.ops.azure.storage.dto.CloudBlob;
import com.company.ops.cloudopsfacade.dto.SignedUrlDTO;
import com.company.ops.cloudopsfacade.exception.storage.CloudStorageException;
import com.company.ops.cloudopsfacade.exception.storage.DataProcessingException;
import com.company.ops.azure.storage.util.URIUtils;
import com.company.ops.cloudopsfacade.storage.ICloudStorageClient;
import com.microsoft.azure.storage.blob.CloudBlobClient;
import com.microsoft.azure.storage.blob.SharedAccessBlobHeaders;
import com.microsoft.azure.storage.blob.SharedAccessBlobPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.inject.Inject;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.EnumSet;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
public class StorageClient implements ICloudStorageClient {
private static final Logger LOG = LoggerFactory.getLogger(StorageClient.class);
#Inject
private CloudBlobClient cloudBlobClient;
#Inject
Properties azureStorageProperties;
#Inject
private SASTokenGenerator sasTokenGenerator;
private long sasUrlDuration;
private Optional<String> sasUrlDurationKey;
public StorageClient() {
sasUrlDurationKey = Optional.ofNullable(System.getenv(StorageConstant.SAS_URL_DURATION_KEY));
if (sasUrlDurationKey.isPresent()) {
try {
sasUrlDuration = Integer.parseInt(sasUrlDurationKey.get());
} catch(NumberFormatException ex) {
LOG.debug("sasURLDurationKey invalid" + ex.getMessage());
sasUrlDuration = StorageConstant.DEFAULT_SAS_URL_DURATION;
}
} else {
sasUrlDuration = StorageConstant.DEFAULT_SAS_URL_DURATION;
}
}
//NOTE: This constructor is just created for test case. As #Mock of final class is NOT supported in easymock
public StorageClient(long sasUrlDuration, CloudBlobClient cloudBlobClient) {
this.sasUrlDuration = sasUrlDuration;
this.cloudBlobClient = cloudBlobClient;
}
/**
*
* #param containerName
* #param blob
* #param expiryTime
* #return {#link URI}
* #throws CloudStorageException
* #throws DataProcessingException
*/
private URI generateSASURI(String containerName,
String blob, Long expiryTime) throws CloudStorageException, DataProcessingException {
CloudBlob cloudBlob = new CloudBlob(Optional.ofNullable(containerName)
.orElseThrow(() -> new CloudStorageException("container name is null")),
Optional.ofNullable(blob).orElseThrow(() -> new CloudStorageException("blob name is null")));
//#TODO: Need to check permissions: Currently create and write assigned
final Set<SharedAccessBlobPermissions> permissions = EnumSet.of(SharedAccessBlobPermissions.WRITE, SharedAccessBlobPermissions.CREATE);
final SharedAccessBlobHeaders contentHeaders = new SharedAccessBlobHeaders();
//in case if duration need to set manually via api
if (Optional.ofNullable(expiryTime).isPresent()) {
sasUrlDuration = expiryTime;
}
sasTokenGenerator.sasTokenGeneratorInitializer(
cloudBlobClient,
cloudBlob,
permissions,
sasUrlDuration,
contentHeaders);
final String token = sasTokenGenerator.getToken();
try {
return new URI(URIUtils.getAssetURI(azureStorageProperties.getProperty(StorageConstant.STORAGE_ACCOUNT_NAME)
, cloudBlob).toString() + "?" + token);
} catch (URISyntaxException e) {
throw new DataProcessingException("Error while creating SAS URL " + e.getMessage(), e);
}
}
/**
*
* #param containerName
* #param blob
* #param expiryTime
* #return {#link URI}
* #throws CloudStorageException
* #throws DataProcessingException
*/
#Override
public SignedUrlDTO generateSignedUrl(String containerName, String blob, Long expiryTime)
throws CloudStorageException, DataProcessingException, MalformedURLException {
try {
URI uri = generateSASURI(containerName, blob, expiryTime);
SignedUrlDTO signedUrlDTO = new SignedUrlDTO();
signedUrlDTO.setSignedURL(uri.toURL());
return signedUrlDTO;
} catch (DataProcessingException ex) {
LOG.error(ex.getMessage());
throw ex;
} catch (CloudStorageException ex) {
LOG.error(ex.getMessage());
throw ex;
} catch (MalformedURLException e) {
LOG.error("Unable to get URL");
throw e;
}
}
}
Below is complete code for UT
package com.company.ops.azure.storage;
import com.company.ops.azure.constants.AzureConstants;
import com.company.ops.azure.storage.constants.StorageConstant;
import com.company.ops.azure.storage.util.URIUtils;
import com.company.ops.cloudopsfacade.dto.SignedUrlDTO;
import com.company.ops.cloudopsfacade.exception.storage.CloudStorageException;
import com.company.ops.cloudopsfacade.exception.storage.DataProcessingException;
import com.microsoft.azure.storage.StorageCredentials;
import com.microsoft.azure.storage.StorageCredentialsAccountAndKey;
import com.microsoft.azure.storage.blob.CloudBlobClient;
import org.easymock.*;
import static org.easymock.EasyMock.*;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import javax.inject.Inject;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.Properties;
#RunWith(EasyMockRunner.class)
public class StorageClientTest extends EasyMockSupport {
private CloudBlobClient cloudBlobClient;
#Mock
private SASTokenGenerator sasTokenGenerator;
#Mock
private Properties azureStorageProperties;
#Mock
private StorageClient storageClient; /*= /*new StorageClient(StorageConstant.DEFAULT_SAS_URL_DURATION,
cloudBlobClient, azureStorageProperties);*/
#Before
public void setup() throws URISyntaxException {
resetAll();
}
#After
public void tearDown() {
verifyAll();
}
#Test
public void testGenerateSASURI() throws MalformedURLException, CloudStorageException, DataProcessingException {
String containerName = "myprojectlocal";
String blob = "testfile";
Long expiryTime = 1000L;
/*Properties azureStorageProperties = EasyMock.createMockBuilder(Properties.class)
.addMockedMethod("getProperty", String.class).createMock();*/
//azureStorageProperties = new Properties();
// azureStorageProperties.setProperty(StorageConstant.STORAGE_ACCOUNT_NAME, "storage-account-name");
expect(azureStorageProperties.getProperty(StorageConstant.STORAGE_ACCOUNT_NAME)).andReturn("storage-account-name");
expect(sasTokenGenerator.getToken()).andReturn("token");
sasTokenGenerator.sasTokenGeneratorInitializer(anyObject(CloudBlobClient.class),
anyObject(),
anyObject(),
anyLong(),
anyObject());
expectLastCall();
//azureStorageProperties.getProperty(anyString()); //.andReturn("storage-account-name");
//expectLastCall();
//expect(azureStorageProperties.getProperty(StorageConstant.STORAGE_ACCOUNT_NAME)).andReturn("storage-account-name");
replayAll();
SignedUrlDTO signedUrlDTO = storageClient.generateSignedUrl(containerName, blob, expiryTime);
Assert.assertNotNull(signedUrlDTO);
}
private CloudBlobClient getCloudBlobClient() {
final StorageCredentials credentials = new StorageCredentialsAccountAndKey(TestConstants.STORAGE_ACCOUNT_NAME,
TestConstants.STORAGE_ACCOUNT_KEY);
try {
return new CloudBlobClient(URIUtils.getStorageAccountURI(TestConstants.STORAGE_ACCOUNT_NAME), credentials);
} catch (URISyntaxException e) {}
return null;
}
}
I'm writing a fairly simple restful web service project in Netbeans (used the Maven Web Application template). I am trying to run it on a Glassfish 4.1 server. I have used Tomcat in the past, but that's not really an option here. Basically, my problem is that I run the project, the server starts, but I just get a 404 error when I try to access the service in the browser.
Here is my source code:
package jp.go.aist.limrs;
import com.hp.hpl.jena.rdf.model.Model;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.websocket.server.PathParam;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import org.apache.commons.io.IOUtils;
#Path("/target")
public class ParserService
{
public static final String SERVER_LOC = "http://localhost:8080/LiMRS/";
public static final String MAPPINGS_LOC = "export.txt";
private String targetUrl;
private String microData;
private Model uDataModel;
private Model mappingsModel;
public ParserService() {}
public ParserService( String url )
{
this.targetUrl = url;
try {
parseMicro(url);
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
#GET
#Path("/{url:.+}")
#Produces(MediaType.TEXT_PLAIN)
public String getMicro(#PathParam("url") String target)
{
this.targetUrl = target;
String domain = "_";
try {
URI uri = new URI(this.targetUrl);
domain = uri.getHost();
System.out.println("Domain is " + domain + "\n\n\n");
} catch (URISyntaxException ex) {
Logger.getLogger(jp.go.aist.LiMRS.LiMRService.class.getName()).log(Level.SEVERE, null, ex);
}
this.microData = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
"<rdf:RDF xml:base=\"http://dbpedia.org/ontology/\" " +
"xmlns:_=\"" + domain + "\">\n\n";
try
{
parseMicro(URLEncoder.encode(this.targetUrl, "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
return "";
}
return this.microData;
}
private void parseMicro(String target) throws MalformedURLException
{
try {
URL url = new URL("http://getschema.org/microdataextractor?url=" + target + "&out=rdf");
HttpURLConnection conn;
try {
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/json");
InputStream ins = conn.getInputStream();
StringWriter writer = new StringWriter();
IOUtils.copy(ins, writer, null);
this.microData += writer.toString() + ".";
} catch (IOException ex) {
Logger.getLogger(jp.go.aist.LiMRS.LiMRService.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (MalformedURLException ex) {
Logger.getLogger(jp.go.aist.LiMRS.LiMRService.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
The URL I'm using to test the service is: http://localhost:8080/LiMRS/target/http://www.rottentomatoes.com/m/jurassic_park/
(I know the URL is unencoded. There are forward slashes in the 'resource' part of the URL, after "/target/", but that is taken care of by the regex in the code and is not source of the problem.)
It's possible the problem is with the server itself, I don't know if there is any special configuration that needs to be done to Glassfish or if you can just run the project outright. I don't have a web.xml file. Unless I'm mistaken, I don't think I need one. What am I missing here?
You're going to need a web.xml or a Application/ResourceConfig subclass to configure the application. If you don't want to use a web.xml, the easiest thing you can do is have an empty Application class annotated with #ApplicationPath. This will cause the registration of all #Path classes you have
#ApplicationPath("/")
public class JaxRsApplication extends Application {}
You can see more options here
I am a straight up newbie. After 2 weeks of research, I've arrived at this point, still very lost and desperate.
My goal: Retrieve data from EnergyStar Portfolio Manager Restful web services / API and put that data into a SQL database or an excel worksheet.
Progress so far:
1) I found an example code that seems like it would fit what I need well, except for the authentication part. I am more successful at getting WSDL services to work than RESTful services. Particularly for EnergySTAR, requiring some kind of authentication, which I can't seem to get around to.
2) The retrieve GET protocol: http://portfoliomanager.energystar.gov/webservices/home/test/api/reporting/designMetrics/get
My source code:
package com;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import com.User;
#Path("/wstest/property/")
public class UserManagementModule
{
#GET
#Path("/{propertyId}/design/metrics?measurementSystem=METRIC")
#Produces("application/xml")
public Response getUserById(#PathParam("propertyId") Integer id)
{
User user = new User();
user.setId(id);
return Response.status(200).entity(user).build();
}
}
package com;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlAccessorType(XmlAccessType.NONE)
#XmlRootElement(name = "propertyMetrics")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#XmlAttribute(name = "propertyId")
private int propertyId;
#XmlElement(name="metric")
private double metric;
#XmlAttribute(name = "designEnergyCost")
private double designEnergyCost;
#XmlAttribute(name = "designScore")
private double designScore;
#XmlAttribute(name = "designSiteTotal")
private double designSiteTotal;
#XmlAttribute(name = "designSiteIntensity")
private double designSiteIntensity;
#XmlAttribute(name = "designTargetEnergyCost")
private double designTargetEnergyCost;
#XmlAttribute(name = "designTargetTotalGHGEmissions")
private double designTargetTotalGHGEmissions;
#XmlAttribute(name = "designTargetSiteTotal")
private double designTargetSiteTotal;
#XmlAttribute(name = "designTargetSiteIntensity")
private double designTargetSiteIntensity;
#XmlAttribute(name = "designTargetSourceTotal")
private double designTargetSourceTotal;
#XmlAttribute(name = "designTargetSourceIntensity")
private double designTargetSourceIntensity;
#XmlAttribute(name = "medianEnergyCost")
private double medianEnergyCost;
#XmlAttribute(name = "medianTotalGHGEmissions")
private double medianTotalGHGEmissions;
#XmlAttribute(name = "medianScore")
private double medianScore;
public int getId() {
return propertyId;
}
public void setId(int propertyId) {
this.propertyId = propertyId;
}
public double getmendianScore() {
return medianScore;
}
//
// public void setFirstName(String firstName) {
// this.firstName = firstName;
// }
// public String getLastName() {
// return lastName;
// }
// public void setLastName(String lastName) {
// this.lastName = lastName;
// }
}
package tests;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import com.User;
public class RestClientXML {
public static void main(String[] args)
{
try
{
URL url = new URL(" https://portfoliomanager.energystar.gov/wstest/");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setRequestProperty("Accept", "application/xml");
if (conn.getResponseCode() != 200)
{
throw new RuntimeException("Failed : HTTP error code : " + conn.getResponseCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader((conn.getInputStream())));
String apiOutput = br.readLine();
System.out.println(apiOutput);
conn.disconnect();
JAXBContext jaxbContext = JAXBContext.newInstance(User.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
User user = (User) jaxbUnmarshaller.unmarshal(new StringReader(apiOutput));
System.out.println(user.getId());
/* System.out.println(user.getFirstName());
System.out.println(user.getLastName());
*/
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JAXBException e) {
e.printStackTrace();
}
}
}
I'm know there is some authentication that needs username and pw,so I also tried this piece instead of the RestClient class, but neither works.
public static void main(String[] args) {
CloseableHttpClient httpClient = null;
HttpPost httpPost = null;
CloseableHttpResponse response = null;
try {
httpClient = HttpClients.createDefault();
httpPost = new HttpPost("https://portfoliomanager.energystar.gov/wstest/");
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("content-type", "application/xml"));
StringEntity input = new StringEntity("{\"username\": \"yungv1\",\"password\": \"dummypassword\"}");
input.setContentType("application/xml");
httpPost.setEntity(input);
for (NameValuePair h : nvps)
{
httpPost.addHeader(h.getName(), h.getValue());
}
response = httpClient.execute(httpPost);
if (response.getStatusLine().getStatusCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ response.getStatusLine().getStatusCode());
}
BufferedReader br = new BufferedReader(new InputStreamReader(
(response.getEntity().getContent())));
String output;
System.out.println("Output from Server .... \n");
while ((output = br.readLine()) != null) {
System.out.println(output);
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try{
response.close();
httpClient.close();
}catch(Exception ex) {
ex.printStackTrace();
}
}
I know it's very sloppy. Can you please point the direction on how I can achieve my goal?
I also tried to run this, and keep getting the 401 errors, which I imagined the authentication fails. I don't know how else to trouble shoot this part and whether there's more thing I need to look into.
conn.setRequestProperty("Authorization", "Basic " + Base64.encodeBase64String((getWebServicesUsername() + ":" + getWebServicesPassword()).getBytes()));
Where conn is HttpURLConnection.
I want to add username and password to soap header in java by using PasswordText Type and axis2.
Code snippet I use
public static void WSSPasswordAuthentication(org.apache.axis2.client.ServiceClient client, String endPointUrl, String username, String password) throws CSException{
OMFactory omFactory = OMAbstractFactory.getOMFactory();
OMElement omSecurityElement = omFactory.createOMElement(new QName( "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "Security", "wsse"), null);
OMElement omusertoken = omFactory.createOMElement(new QName("http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", "UsernameToken","wsse"), null);
OMElement omuserName = omFactory.createOMElement(new QName("", "Username", "wsse"), null);
omuserName.setText(username);
OMElement omPassword = omFactory.createOMElement(new QName("", "Password", "wsse"), null);
omPassword.addAttribute("Type","http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText",null );
omPassword.setText(password);
omusertoken.addChild(omuserName);
omusertoken.addChild(omPassword);
omSecurityElement.addChild(omusertoken);
client.addHeader(omSecurityElement);
}
And resultant header :
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><wsu:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><Username>erapor</Username><Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">erapor</Password></wsu:UsernameToken></wsse:Security>
But
The header I want : <soapenv:Header><wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"><wsse:UsernameToken xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><wsse:Username>erapor</wsse:Username><wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">erapor</wsse:Password></wsse:UsernameToken></wsse:Security></soapenv:Header>
Otherwise I couldn't use the header
How can I modify?
You can use plain JAXWS if you have an option to resolve this instead of using AXIS2 on the client side. This is generic and easy to add these kind of security headers.
In your JDK 6.0 HOME (This example works only from JDK 6.0 and above)
jdk1.6.0_26\bin\wsimport is an utility available
You can create the stub using the wsimport utility
wsimport -keep -verbose http://localhost:8080/<WebserviceName>/services/<WebserviceName>?wsdl
Create a message handler
MessageHandler.java
package com.secure.client;
import java.util.Set;
import javax.xml.namespace.QName;
import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPEnvelope;
import javax.xml.soap.SOAPHeader;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.soap.SOAPHandler;
import javax.xml.ws.handler.soap.SOAPMessageContext;
public class MessageHandler implements SOAPHandler<SOAPMessageContext>{
#Override
public void close(MessageContext arg0) {
// TODO Auto-generated method stub
}
#Override
public Set getHeaders() {
// TODO Auto-generated method stub
return null;
}
#Override
public boolean handleFault(SOAPMessageContext context) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean handleMessage(SOAPMessageContext soapMessageContext) {
try {
boolean outMessageIndicator = (Boolean) soapMessageContext
.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
if (outMessageIndicator) {
SOAPEnvelope envelope = soapMessageContext.getMessage().getSOAPPart().getEnvelope();
SOAPHeader header = envelope.addHeader();
SOAPElement security = header.addChildElement("Security", "wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd");
SOAPElement usernameToken = security.addChildElement("UsernameToken", "wsse");
usernameToken.addAttribute(new QName("xmlns:wsu"), "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd");
SOAPElement username = usernameToken.addChildElement("Username", "wsse");
username.addTextNode("wsuser");
SOAPElement password = usernameToken.addChildElement("Password", "wsse");
password.setAttribute("Type", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText");
password.addTextNode("wspwd");
}
} catch (Exception ex) {
throw new WebServiceException(ex);
}
return true;
}
}
Create HeaderHandlerResolver.java
package com.secure.client;
import java.util.ArrayList;
import java.util.List;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.HandlerResolver;
import javax.xml.ws.handler.PortInfo;
public class HeaderHandlerResolver implements HandlerResolver {
#SuppressWarnings("unchecked")
public List<Handler> getHandlerChain(PortInfo portInfo) {
List<Handler> handlerChain = new ArrayList<Handler>();
MessageHandler hh = new MessageHandler();
handlerChain.add(hh);
return handlerChain;
}
}
You can create the client code using stub
Client.java
import javax.xml.ws.BindingProvider;
import com.secure.HelloService;
import com.secure.HelloServiceException;
import com.secure.HelloServicePortType;
public class Client {
public static void main(String[] args) {
HelloService service = new HelloService();
service.setHandlerResolver(new HeaderHandlerResolver());
HelloServicePortType port = service.getHelloServiceHttpSoap11Endpoint();
// Use the BindingProvider's context to set the endpoint
BindingProvider bp = (BindingProvider)port;
bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "http://localhost:8080/<WebserviceName>/services/<WebserviceName>");
System.out.println(port.getVersion());
try {
System.out.println(port.getHello("Zack"));
} catch (HelloServiceException e) {
e.printStackTrace();
}
}
}
I have written a sample CXF webservice program and deployed using,Apache in local machine.
This is my WSDL URL :
http://localhost:8080/SubstractWebService/SubWS?wsdl
And I am able to access it.
But when I am trying to run the client program it is throwing error -->
Exception in thread "main" javax.xml.ws.WebServiceException: org.apache.cxf.service.factory.ServiceConstructionException: Failed to create service.
at org.apache.cxf.jaxws.ServiceImpl.<init>(ServiceImpl.java:149)
at org.apache.cxf.jaxws.spi.ProviderImpl.createServiceDelegate(ProviderImpl.java:97)
at javax.xml.ws.Service.<init>(Unknown Source)
at com.service.substract.subwsdlfile.SubWSDLFile_Service.<init>(SubWSDLFile_Service.java:43)
at com.service.substract.subwsdlfile.SubWSDLFile_SubWSDLFileSOAP_Client.main(SubWSDLFile_SubWSDLFileSOAP_Client.java:53)
Caused by: org.apache.cxf.service.factory.ServiceConstructionException: Failed to create service.
at org.apache.cxf.wsdl11.WSDLServiceFactory.<init>(WSDLServiceFactory.java:94)
at org.apache.cxf.jaxws.ServiceImpl.initializePorts(ServiceImpl.java:203)
at org.apache.cxf.jaxws.ServiceImpl.<init>(ServiceImpl.java:147)
... 4 more
Caused by: javax.wsdl.WSDLException: WSDLException: faultCode=PARSER_ERROR: Problem parsing 'http://localhost:8080/SubstractWebService/SubWS?wsdl'.: java.io.FileNotFoundException: http://localhost:8080/SubstractWebService/SubWS?wsdl
at com.ibm.wsdl.xml.WSDLReaderImpl.getDocument(Unknown Source)
at com.ibm.wsdl.xml.WSDLReaderImpl.readWSDL(Unknown Source)
at com.ibm.wsdl.xml.WSDLReaderImpl.readWSDL(Unknown Source)
at org.apache.cxf.wsdl11.WSDLManagerImpl.loadDefinition(WSDLManagerImpl.java:244)
at org.apache.cxf.wsdl11.WSDLManagerImpl.getDefinition(WSDLManagerImpl.java:191)
at org.apache.cxf.wsdl11.WSDLServiceFactory.<init>(WSDLServiceFactory.java:92)
... 6 more
Caused by: java.io.FileNotFoundException: http://localhost:8080/SubstractWebService/SubWS?wsdl
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(Unknown Source)
at com.sun.org.apache.xerces.internal.impl.XMLVersionDetector.determineDocVersion(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
... 12 more
Client code
package com.service.substract.subwsdlfile;
/**
* Please modify this class to meet your needs
* This class is not complete
*/
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebResult;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.xml.bind.annotation.XmlSeeAlso;
/**
* This class was generated by Apache CXF 2.6.1
* 2012-12-09T17:44:09.725+05:30
* Generated source version: 2.6.1
*
*/
public final class SubWSDLFile_SubWSDLFileSOAP_Client {
private static final QName SERVICE_NAME = new QName("http://substract.service.com/SubWSDLFile/", "SubWSDLFile");
private SubWSDLFile_SubWSDLFileSOAP_Client() {
}
public static void main(String args[]) throws java.lang.Exception {
URL wsdlURL = SubWSDLFile_Service.WSDL_LOCATION;
if (args.length > 0 && args[0] != null && !"".equals(args[0])) {
File wsdlFile = new File(args[0]);
try {
if (wsdlFile.exists()) {
wsdlURL = wsdlFile.toURI().toURL();
} else {
wsdlURL = new URL(args[0]);
}
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
SubWSDLFile_Service ss = new SubWSDLFile_Service(wsdlURL, SERVICE_NAME);
SubWSDLFile port = ss.getSubWSDLFileSOAP();
{
System.out.println("Invoking substractOp...");
com.service.substract.substractwsschema.SubsbtractRequest _substractOp_substractRequest = new com.service.substract.substractwsschema.SubsbtractRequest();
_substractOp_substractRequest.setParam1(-735195532);
_substractOp_substractRequest.setParam2(633197322);
com.service.substract.substractwsschema.SubstractResponse _substractOp__return = port.substractOp(_substractOp_substractRequest);
System.out.println("substractOp.result=" + _substractOp__return);
}
System.exit(0);
}
}
package com.service.substract.subwsdlfile;
import java.net.MalformedURLException;
import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.WebEndpoint;
import javax.xml.ws.WebServiceClient;
import javax.xml.ws.WebServiceFeature;
import javax.xml.ws.Service;
/**
* This class was generated by Apache CXF 2.6.1
* 2012-12-09T17:44:09.805+05:30
* Generated source version: 2.6.1
*
*/
#WebServiceClient(name = "SubWSDLFile",
wsdlLocation = "http://localhost:8080/SubstractWebService?wsdl",
targetNamespace = "http://substract.service.com/SubWSDLFile/")
public class SubWSDLFile_Service extends Service {
public final static URL WSDL_LOCATION;
public final static QName SERVICE = new QName("http://substract.service.com/SubWSDLFile/", "SubWSDLFile");
public final static QName SubWSDLFileSOAP = new QName("http://substract.service.com/SubWSDLFile/", "SubWSDLFileSOAP");
static {
URL url = null;
try {
//url = new URL("http://localhost:8080/SubstractWebService?wsdl");
url = new URL("http://localhost:8080/SubstractWebService");
} catch (MalformedURLException e) {
java.util.logging.Logger.getLogger(SubWSDLFile_Service.class.getName())
.log(java.util.logging.Level.INFO,
"Can not initialize the default wsdl from {0}", "http://localhost:8080/SubstractWebService?wsdl");
}
WSDL_LOCATION = url;
}
public SubWSDLFile_Service(URL wsdlLocation) {
super(wsdlLocation, SERVICE);
}
public SubWSDLFile_Service(URL wsdlLocation, QName serviceName) {
super(wsdlLocation, serviceName);
}
public SubWSDLFile_Service() {
super(WSDL_LOCATION, SERVICE);
}
/**
*
* #return
* returns SubWSDLFile
*/
#WebEndpoint(name = "SubWSDLFileSOAP")
public SubWSDLFile getSubWSDLFileSOAP() {
return super.getPort(SubWSDLFileSOAP, SubWSDLFile.class);
}
/**
*
* #param features
* A list of {#link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in the <code>features</code> parameter will have their default values.
* #return
* returns SubWSDLFile
*/
#WebEndpoint(name = "SubWSDLFileSOAP")
public SubWSDLFile getSubWSDLFileSOAP(WebServiceFeature... features) {
return super.getPort(SubWSDLFileSOAP, SubWSDLFile.class, features);
}
}