long response time of webservice using ibatis and jaxws - java

I have a web service using JAX-WS and Ibatis, when analyzed with the New Relic tool can see that the running time is 17 seconds. Seeing the detail of the report shows that the database calls are fast, but what is delaying is this: JAXWSWebAppServlet.service (). Someone has an idea that can be ??
Thanks x your help.
PD: I would like to know where to locate JAXWSWebAppServlet.service () in my code. Any ideas??
The WS code:
#WebService(name = "WS_XXXXXX", portName = "WS_XXXXXSoap12HttpPort")
#BindingType(SOAPBinding.SOAP12HTTP_BINDING)
public class WS_GetPlanUsage {
#WebMethod(operationName = "xxxxxx")
#javax.jws.soap.SOAPBinding(parameterStyle = javax.jws.soap.SOAPBinding.ParameterStyle.WRAPPED)
public GetPlanUsageMapBean getPlanUsage(#WebParam(name = "phoneNumber", partName = "request") String phoneNumber,
#WebParam(name = "initialDate", partName = "request") String initialDate,
#WebParam(name = "finalDate", partName = "request") String finalDate) {
BReturn oBReturn = null;
GetPlanUsageResponse response = new GetPlanUsageResponse();
GetPlanUsageRequest rq = new GetPlanUsageRequest();
rq.setPhoneNumber(phoneNumber);
rq.setInitialDate(initialDate);
rq.setFinalDate(finalDate);
oBReturn = new GetPlanUsageBL().getPlanUsage(rq);
GetPlanUsageMapBean getPlanUsage = (GetPlanUsageMapBean)oBReturn.getObject();
return getPlanUsage;
}

Related

Passing a BODY of a POST request to the server

I have built a Restful-API Java(SpringBoot) and created the needed requests.
The following request is a POST Request to add new Category.
I have tested the POST request by POSTMAN, and it working as expected.
I am building the client-side in ASP.NET 5.x.x.
Now the problem appear when I am calling the post request, it seems the API doesn't receive the data (#RequestBody category) that has been send from the client.
Here is a code simple of how I have created them
Server Side:
#ResponseStatus(HttpStatus.CREATED)
#PostMapping(value = "/add", consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public CategoryDTO create(#RequestBody CategoryDTO category) {
log.info("Adding new Category Name: " + category.getName());
return categoryMapper.asCategoryDTO(categoryService.save(categoryMapper.asCategory(category)));
}
Client Side
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Category category)
{
Category newCategory = new Category();
// Serialize the concrete class into a JSON String
var stringPayload = JsonConvert.SerializeObject(category);
// Wrap the JSON inside a StringContent which then can be used by the HttpClient class
StringContent content = new StringContent(stringPayload);
content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
using (var httpClient = new HttpClient())
{
using (var response = await httpClient.PostAsync("http://localhost:8080/category/add", content))
{
string apiResponse = await response.Content.ReadAsStringAsync();
newCategory = JsonConvert.DeserializeObject<Category>(apiResponse);
}
}
return RedirectToAction("Index");
}
I don't know what is wrong there, could anybody help!
EDIT--
Here is the request via postman
EDIT
I have created another POST request but as a RequestParam instead of RequestBody
#ResponseStatus(HttpStatus.CREATED)
#PostMapping(value = "/add", produces = MediaType.APPLICATION_JSON_VALUE)
public CategoryDTO addCategory(#RequestParam(name = "categoryName") String categoryName){
return categoryMapper.asCategoryDTO(categoryService.addCategory(categoryName));
}
and created in the client side the request as following
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(Category category)
{
Category newCategory = new Category();
var parameters = new Dictionary<string, string> { { "categoryName", category.Name } };
var encodedContent = new FormUrlEncodedContent(parameters);
using (var httpClient = new HttpClient())
{
using (var response = await httpClient.PostAsync("http://localhost:8080/category/add", encodedContent))
{
string apiResponse = await response.Content.ReadAsStringAsync();
newCategory = JsonConvert.DeserializeObject<Category>(apiResponse);
}
}
return RedirectToAction("Index");
}
And It's works fine!
So the problem is how to pass the data via the httpClient, which need to be of type RequestBody (the data in the body not in the header!) also as a application/json.
So how to pass the data?
I suppose that your spring boot application just blocks POST request because you didn't provide instruction how to handle requests. Try to disable csrf protection like it did here: https://stackoverflow.com/a/48935484/13314717
It might be a problem in the naming convention. Starting with capital letters in properties in C#, and starting with lowercase in Java.
If your class looks like this in C#
class Category {
int Id;
string Name;
...
}
And like this in Java
class Category {
int id;
string name;
...
}
It is not going to work so you have to match the property names. So make either both id or both Id.

Dropwizard-Jaxws library soap client request

I am consuming a soap service using dropwizard-jaxws.
Managed to generate the relevant java classes using Apache CXF 3.4. Here's the generated interface IService.
#WebService(targetNamespace = "http://tempuri.org/", name = "IService")
#XmlSeeAlso({ObjectFactory.class})
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public interface IService {
#WebMethod(operationName = "PayBill", action = "http://tempuri.org/IService/PayBill")
#Action(input = "http://tempuri.org/IService/PayBill", output = "http://tempuri.org/IService/PayBillResponse")
#WebResult(name = "PayBillResponse", targetNamespace = "http://tempuri.org/", partName = "parameters")
public PayBillResponse payBill(
#WebParam(partName = "parameters", name = "PayBill", targetNamespace = "http://tempuri.org/")
PayBill parameters
);
I wrote this implementing class IserviceImpl in kotlin
#WebService(endpointInterface = "com.mmm.platform.utility.easy.IService",
targetNamespace = "http://tempuri.org/",
name = "IService",
wsdlLocation = "wsdl/mmm-easy.wsdl")
class IServiceImpl: IService {
override fun payBill(parameters: PayBill?): PayBillResponse {
var response = PayBillResponse();
response.setSctrxnid(parameters?.sctxnid);
return response;
}
This is my dropwizard Application class in kotlin
class UtilityServiceApplication : Application<UtilityServiceConfiguration>() {
private val jaxWsBundle = JAXWSBundle<Any>()
override fun initialize(bootstrap: Bootstrap<UtilityServiceConfiguration>?) {
bootstrap?.addBundle(jaxWsBundle)
}
override fun run(configuration: UtilityServiceConfiguration?, environment: Environment?) {
environment!!.jersey().register(
AccessEasyServiceResource(
jaxWsBundle.getClient(
ClientBuilder(IService::class.java,
"http://mmm.hhhhh.xyz/EMTerminalAPI/wsdl.svc")
.handlers(AccessEasyClientHandler()))))
}
}
Dropwizard resource class AccessServiceResource in kotlin for end-point /paybillone
#Path("/paybillone")
#Produces(MediaType.APPLICATION_JSON)
public class AccessServiceResource {
var serviceClient: IService? = null
constructor(serviceClient: IService) {
this.serviceClient = serviceClient;
}
#GET
#Timed
fun getFoo(): String {
val of = ObjectFactory()
var payBill = of.createPayBill()
payBill.sctxnid = of.createPayBillSctxnid(RandomStringUtils.randomAlphanumeric(15))
payBill.txntype = of.createPayBillTxntype("1")
payBill.payeecode = of.createPayBillPayeecode("POWER")
payBill.accountno = of.createPayBillAccountno("04246483624")
payBill.phoneno = of.createPayBillPhoneno("0700252181")
payBill.amount = of.createPayBillAmount("5000")
var payBillResponse = serviceClient?.payBill(payBill)
return payBillResponse?.receiptno?.value.toString()
}
This call var payBillResponse = serviceClient?.payBill(payBill) unfortunately returned an error response message missing mandatory values yet I clearly added them to the payBill object.
Qn 1 Is this the correct way of creating the request object, so I get the correct corresponding response payBillResponse?
Qn 2 How and where should I pass payBill so I get the correct response to that call?
Qn 3 The other issue is most likely my implementation of IServiceImpl is wrong, is it even required?

Can't cast ServiceClient to WSBindingProvider

So I have this web service(based on axis2) which is supposed to act as a client to other web service. But when trying to cast my servicePort (docManClient) to WSBindingProvider I get ClassCastException error:
com.sun.proxy.$Proxy283 cannot be cast to com.sun.xml.internal.ws.developer.WSBindingProvider
What confuses me is that this code works ok when execution from simple java application, but when execution from web service it fails. Also I've noticed that when executed from simple java application docManClient is a SEIStub object but when this code is executed inside my axis2 webservice, docManClient is JAXWSProxyHandler. I don't know if that helps or what should I do.
How can I fix or analyse deeply this classcast exception? Is there a way to avoid casting it to WSBindingProvider and set headers with JAXWSProxyHandler?
Thanks in advance.
DocumentManagement_Service docManService = new DocumentManagement_Service();
DocumentManagement docManClient = docManService.getBasicHttpBindingDocumentManagement();
DocumentManagement docManClientP = docManService.getBasicHttpBindingDocumentManagement(null);
try
{
// The namespace of the OTAuthentication object
final String ECM_API_NAMESPACE = "urn:api.ecm.opentext.com";
// Create a SOAP header
SOAPHeader header = MessageFactory.newInstance().createMessage().getSOAPPart().getEnvelope().getHeader();
// Add the OTAuthentication SOAP header element
SOAPHeaderElement otAuthElement = header.addHeaderElement(new QName(ECM_API_NAMESPACE, "OTAuthentication"));
// Add the AuthenticationToken SOAP element
SOAPElement authTokenElement = otAuthElement.addChildElement(new QName(ECM_API_NAMESPACE, "AuthenticationToken"));
authTokenElement.addTextNode(authToken);
// Set the SOAP header on the docManClient
//Object pt = docManService.getPort(do);
//ServiceClient sc = docManService.getServiceClient(docManService.getServiceName())
//BindingProvider bp = ((BindingProvider) docManClient);
((WSBindingProvider) docManClient).setOutboundHeaders(Headers.create(otAuthElement));
...
DocumentManagement:
/**
* This class was generated by the JAX-WS RI.
* JAX-WS RI 2.2.9-b130926.1035
* Generated source version: 2.2
*
*/
"urn:xxxx")
#XmlSeeAlso({
com.opentext.ecm.api.ObjectFactory.class,
com.opentext.livelink.service.core.ObjectFactory.class,
com.opentext.livelink.service.docman.ObjectFactory.class
})
public interface DocumentManagement {
/**
*
* #param nodeID
*/
#WebMethod(operationName = "RemoveFavorite", action = "urn:xxxx/RemoveFavorite")
#RequestWrapper(localName = "RemoveFavorite", targetNamespace = "urn:xxx", className = "xxxx.RemoveFavorite")
#ResponseWrapper(localName = "RemoveFavoriteResponse", targetNamespace = "urn:xxxx", className = "xxxx.RemoveFavoriteResponse")
public void removeFavorite(
#WebParam(name = "nodeID", targetNamespace = "urn:xxxx")
long nodeID);
DocumentManagement_Service:
/**
* This class was generated by the JAX-WS RI.
* JAX-WS RI 2.2.9-b130926.1035
* Generated source version: 2.2
*
*/
#WebServiceClient(name = "DocumentManagement", targetNamespace = "urn:xxx", wsdlLocation = "xxxx")
public class DocumentManagement_Service
extends Service
{
static {
URL url = null;
WebServiceException e = null;
try {
url = new URL("xxxx");
} catch (MalformedURLException ex) {
e = new WebServiceException(ex);
}
DOCUMENTMANAGEMENT_WSDL_LOCATION = url;
DOCUMENTMANAGEMENT_EXCEPTION = e;
}

Basic Authentication Java SOAP WebService Client

java artifacts for Soap Web Service Client using wsimport from a WSDL. Which produced:
AppPortalSMupdate.java with some sample code from it
public interface AppPortalSMupdate {
#WebMethod(operationName = "RetrieveAppPortalSMupdate", action = "Retrieve")
#WebResult(name = "RetrieveAppPortalSMupdateResponse", targetNamespace = "http://schemas.hp.com/SM/7", partName = "RetrieveAppPortalSMupdateResponse")
public RetrieveAppPortalSMupdateResponse retrieveAppPortalSMupdate(
#WebParam(name = "RetrieveAppPortalSMupdateRequest", targetNamespace = "http://schemas.hp.com/SM/7", partName = "RetrieveAppPortalSMupdateRequest")
RetrieveAppPortalSMupdateRequest retrieveAppPortalSMupdateRequest);
AppPortalSMupdate_Service.java
#WebServiceClient(name = "AppPortalSMupdate", targetNamespace = "http://schemas.hp.com/SM/7", wsdlLocation ="http://ss_user:sqzblsft#msmapptst001.lvh.com:13088/SM/7/AppPortalSMupdate.wsdl")
public class AppPortalSMupdate_Service extends Service{
private final static URL APPPORTALSMUPDATE_WSDL_LOCATION;
private final static WebServiceException APPPORTALSMUPDATE_EXCEPTION;
private final static QName APPPORTALSMUPDATE_QNAME = new QName("http://schemas.hp.com/SM/7", "AppPortalSMupdate");
static {
URL url = null;
WebServiceException e = null;
try {
url = new URL("http://ss_user:sqzblsft#msmapptst001.lvh.com:13088/SM/7/AppPortalSMupdate.wsdl");
} catch (MalformedURLException ex) {
e = new WebServiceException(ex);
}
APPPORTALSMUPDATE_WSDL_LOCATION = url;
APPPORTALSMUPDATE_EXCEPTION = e;
This is the call to in my main from test client class:
AppPortalSMupdate appUpdate = calc.getAppPortalSMupdate();
UpdateAppPortalSMupdateResponse appResponse = appUpdate.updateAppPortalSMupdate(requestMessage);
My question is the web service needs a user id and password. How do I add a user id and password in my call in the main. This is being used inside a liferay portlet.
use #HandlerChain annotation and configure them by implementing the SOAPHandler interface.
Let me know if you need more clarification.

Amazon API SOAP code generation from WSDL, Intellij

I generated Java code from the Amazon WSDL found here in Intellij. It appeared to have worked great. However, as I followed the tutorial found on this page I encountered a problem. The last line of the java code is calling a method itemSearch from the AWSECommerceServicePortType class. The only method description that was generated for that method was
#WebMethod(operationName = "ItemSearch", action = "http://soap.amazon.com/ItemSearch")
#RequestWrapper(localName = "ItemSearch", targetNamespace = "http://webservices.amazon.com/AWSECommerceService/2011-08-01", className = "com.shopit.amazon.ItemSearch")
#ResponseWrapper(localName = "ItemSearchResponse", targetNamespace = "http://webservices.amazon.com/AWSECommerceService/2011-08-01", className = "com.shopit.amazon.ItemSearchResponse")
public void itemSearch(
#WebParam(name = "MarketplaceDomain", targetNamespace = "http://webservices.amazon.com/AWSECommerceService/2011-08-01")
String marketplaceDomain,
#WebParam(name = "AWSAccessKeyId", targetNamespace = "http://webservices.amazon.com/AWSECommerceService/2011-08-01")
String awsAccessKeyId,
#WebParam(name = "AssociateTag", targetNamespace = "http://webservices.amazon.com/AWSECommerceService/2011-08-01")
String associateTag,
#WebParam(name = "XMLEscaping", targetNamespace = "http://webservices.amazon.com/AWSECommerceService/2011-08-01")
String xmlEscaping,
#WebParam(name = "Validate", targetNamespace = "http://webservices.amazon.com/AWSECommerceService/2011-08-01")
String validate,
#WebParam(name = "Shared", targetNamespace = "http://webservices.amazon.com/AWSECommerceService/2011-08-01")
ItemSearchRequest shared,
#WebParam(name = "Request", targetNamespace = "http://webservices.amazon.com/AWSECommerceService/2011-08-01")
List<ItemSearchRequest> request,
#WebParam(name = "OperationRequest", targetNamespace = "http://webservices.amazon.com/AWSECommerceService/2011-08-01", mode = WebParam.Mode.OUT)
Holder<OperationRequest> operationRequest,
#WebParam(name = "Items", targetNamespace = "http://webservices.amazon.com/AWSECommerceService/2011-08-01", mode = WebParam.Mode.OUT)
Holder<List<Items>> items);
It requires that I pass a lot more parameters than just the one it does in the example and it gives and error when compiling. Do I need to use a different setting for generating the java code.
you can use amazon-ecs.jar for amazon product api
I think much better to use official aws sdk for java: http://aws.amazon.com/sdkforjava/

Categories

Resources