JAX-WS client, incorrect soap request - The markup in the document following the root element must be well-formed - soap

I have generated a web service client using wsimport command line (JAX-WS) and generated Java objects using JAXB and separate XSD files.
But when I try to request, it gives following error from server side.
SAXException, cause: The markup in the document following the root element must be well-formed.
So I checked my soap request with a sample working soap message. Then I realized that there is a different between these two messages.
1. Sample working message.
<m:getMyDetail xmlns:m="http://axis.frontend.hi.example.net">
<MyDetailRQ xmlns="http://www.example.net/schemas/1005/06/messages"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.net/1005/06/messages ../xsd/MyDetailRQ.xsd"
version="2013/12">
2. Web service client generated soap message.
<ns3:getMyDetail xmlns:ns3="http://axis.frontend.hi.example.net" xmlns="http://www.
example.net/schemas/1005/06/messages" xmlns:ns2="http://www. example.net/wsdl/1005/06"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="MyDetailRQ">
As you can see, above expected MyDetailRQ wrapper tag element is missing but it generated as xsi:type="MyDetailRQ" attribute.
I’m not sure why this happen and how to fix this through my client project configurations.
Appreciate your help and advice.
Thanks
- Relevant WSDL part
<wsdl:types>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://axis.frontend.h1.example.com">
<element name="getMyDetail" type="xsd:anyType"/>
</schema>
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.com/wsdl/2005/06">
<element name="getMyDetailReturn" type="xsd:anyType"/>
</schema>
</wsdl:types>
<wsdl:message name="getMyDetailRequest">
<wsdl:part element="tns1:getMyDetail" name="part"/>
</wsdl:message>
<wsdl:message name="getMyDetailResponse">
<wsdl:part element="impl:getMyDetailReturn" name="getMyDetailReturn"/>
</wsdl:message>
<wsdl:portType name="MyService">
<wsdl:operation name="getMyDetail">
<wsdl:input message="impl:getMyDetailRequest" name="getMyDetailRequest"/>
<wsdl:output message="impl:getMyDetailResponse" name="getMyDetailResponse"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="MyServiceSoapBinding" type="impl:MyService">
<wsdl:operation name="getMyDetail">
<wsdlsoap:operation soapAction=""/>
<wsdl:input name="getMyDetailRequest">
<wsdlsoap:body use="literal"/>
</wsdl:input>
<wsdl:output name="getMyDetailResponse">
<wsdlsoap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="MyServiceService">
<wsdl:port binding="impl:MyServiceSoapBinding" name="MyService">
<wsdlsoap:address location="http://interface.example.com/xmls/ws/MyService"/>
</wsdl:port>
</wsdl:service>
- Relevant XSD part
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns="http://www.example.net/schemas/1005/06/messages" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.net/schemas/1005/06/messages" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:include schemaLocation="MyCommonTypes.xsd"/>
<xs:element name="MyDetailRQ">
- Relevant Java Object
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "MyDetailRQ", propOrder = {
"myCode"
})
#XmlRootElement(name = "MyDetailRQ")
public class MyDetailRQ
extends MainRequest
{
}
- web service client - service interface (Updated on 17-Oct-2014)
#WebService(name = "MyService", targetNamespace = "http://www.example.net/wsdl/1005/06")
#SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
#XmlSeeAlso({
com.myp.hi.frontend.axis.ObjectFactory.class,
com.myp.ObjectFactory.class
})
public interface MyService {
/**
*
* #param part
* #return
* returns java.lang.Object
*/
#WebMethod
#WebResult(name = "getMyDetailReturn", targetNamespace = "http://www.example.net/wsdl/1005/06", partName = "getMyDetailReturn")
public Object getMyDetail(
#WebParam(name = "getMyDetail", targetNamespace = "http://axis.frontend.hi.example.net", partName = "part")
Object part);
}
- ObjectFactory class (Updated on 17-Oct-2014)
#XmlRegistry
public class ObjectFactory {
private final static QName _GetMyDetail_QNAME = new QName("http://axis.frontend.hi.example.net", "getMyDetail");
public ObjectFactory() {
}
#XmlElementDecl(namespace = "http://axis.frontend.hi.example.net", name = "getMyDetail")
public JAXBElement<Object> createGetMyDetail(Object value) {
return new JAXBElement<Object>(_GetMyDetail_QNAME, Object.class, null, value);
}
}
-MyServiceService class (Updated on 17-Oct-2014)
#WebServiceClient(name = "MyServiceService", targetNamespace = "http://www.example.net/wsdl/1005/06", wsdlLocation = "http://interface.example.com/xmls/ws/MyService?wsdl")
#GZIP
public class MyServiceService
extends Service
{
private final static URL MYSERVICESERVICE_WSDL_LOCATION;
private final static WebServiceException MYSERVICESERVICE_EXCEPTION;
private final static QName MYSERVICESERVICE_QNAME = new QName("http://www.example.net/wsdl/1005/06", "MyServiceService");
static {
URL url = null;
WebServiceException e = null;
try {
url = new URL("http://interface.example.com/xmls/ws/MyService?wsdl");
} catch (MalformedURLException ex) {
e = new WebServiceException(ex);
}
MYSERVICESERVICE_WSDL_LOCATION = url;
MYSERVICESERVICE_EXCEPTION = e;
}
#WebEndpoint(name = "MyService")
public MyService getMyService() {
MyService port = super.getPort(new QName("http://www.example.net/wsdl/1005/06", "MyService"), MyService.class);
return port;
}
private static URL __getWsdlLocation() {
if (MYSERVICESERVICE_EXCEPTION!= null) {
throw MYSERVICESERVICE_EXCEPTION;
}
return MYSERVICESERVICE_WSDL_LOCATION;
}
}
- My Test class (Updated on 17-Oct-2014)
MyService myService = new MyServiceService().getMyService();
MyDetailRQ myDetailRQ = new MyDetailRQ();
myDetailRQ.setCredentials(credentials);
myDetailRQ.setLanguage("ENG");
myDetailRQ.setMyCode("52319");
MyDetailRS myDetailRS = (MyDetailRS) myService.getMyDetail(myService);

I have found a solution, but not sure whether perfect one.
What I have done is; pass a XML String to service and get response as a String from service.
Then manually do marshalling and un- marshalling.
See the example below.
MyService myService = new MyServiceService().getMyService();
MyDetailRQ myDetailRQ = new MyDetailRQ();
myDetailRQ.setCredentials(credentials);
myDetailRQ.setLanguage("ENG");
myDetailRQ.setMyCode("52319");
String requestStr = getStringFromJaxb(myDetailRQ.class, myDetailRQ);
String responseStr = (String) myService.getMyDetail(requestStr);
MyDetailRS myDetailRS = (MyDetailRS) getJaxbFromString(MyDetailRS.class, responseStr);
private static Object getJaxbFromString(Class<?> clazz, String xmlString) {
StringReader input = null;
Object o = null;
try {
input = new StringReader(xmlString);
JAXBContext context = JAXBContext.newInstance(clazz);
Unmarshaller um = context.createUnmarshaller();
o = um.unmarshal(input);
if (o instanceof JAXBElement)
o = ((JAXBElement<?>) o).getValue();
} catch (JAXBException e) {
e.printStackTrace();
} finally {
if (input != null)
input.close();
}
return o;
}
/**
* Helper method to get xml string from JAXB Object.
* #param clazz
* #param o
* #return
*/
private static String getStringFromJaxb(Class<?> clazz, Object o) {
String theXML = "";
try {
StringWriter writer = new StringWriter();
JAXBContext context = JAXBContext.newInstance(clazz);
Marshaller m = context.createMarshaller();
m.setProperty("com.sun.xml.bind.xmlDeclaration", Boolean.FALSE);
m.marshal(o, writer);
// output string to console
theXML = writer.toString();
} catch (Exception e) {
e.printStackTrace();
}
return theXML;
}

Related

Wcf Rest Call HTTP/1.1 400 Bad Request or HTTP/1.1 404 Not Found

I am having trouble while sending the request to a rest service. The service works fine on my desktop, but getting the following error when i host on the IIS.
HTTP/1.1 400 Bad Request when i use https
HTTP/1.1 404 Not Found when i use http
Here is my web.config
<system.serviceModel>
<bindings>
<webHttpBinding>
<binding name="webBinding">
<security mode="Transport">
</security>
</binding>
</webHttpBinding>
</bindings>
<services>
<service
behaviorConfiguration="CoreService.DialService.DialServiceBehavior"
name="CoreService.DialService.TelephonyService">
<endpoint behaviorConfiguration="webBehavior" binding="webHttpBinding"
bindingConfiguration="webBinding"
contract="CoreService.DialService.ITelephonyService"/>
</service>
</services>
<behaviors>
<endpointBehaviors>
<behavior name="webBehavior">
<webHttp helpEnabled="true"/>
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="CoreService.DialService.DialServiceBehavior">
<serviceMetadata httpsGetEnabled="true" httpGetEnabled="true"/>
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
<protocolMapping>
<add binding="webHttpBinding" scheme="http"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true"
multipleSiteBindingsEnabled="true"/>
<diagnostics>
<messageLogging logEntireMessage="true" logMalformedMessages="true"
logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="true"
maxMessagesToLog="3000" maxSizeOfMessageToLog="2000"/>
</diagnostics>
</system.serviceModel>
Service Contract
[WebInvoke(UriTemplate = "/Dial", Method = "POST", RequestFormat =
WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
[OperationContract]
Objects.Response.Telephony.DialResponse
Dial(Objects.Request.Telephony.DialRequest request);
Here is the client
DialRequest DialRequest = new DialRequest();
DialResponse DialResponse = new DialResponse();
DialRequest.ProjectID = "AMS0103300";
DialRequest.DialFromExtension = "1234";
DialRequest.OutDialCode = "51";
DialRequest.RequestBy = "HC User";
DialRequest.DialToPhoneNumber = "1234567890";
DialRequest.RequestDate = DateTime.Now;
DialRequest.ApplicationID = Guid.Parse("F5EE534B-B5ED-4ADD-B671-
CCF7C05057A7");
DataContractJsonSerializer ser =
new
DataContractJsonSerializer(typeof(Objects.Request.Telephony.DialRequest));
MemoryStream mem = new MemoryStream();
ser.WriteObject(mem, DialRequest);
string data =
Encoding.UTF8.GetString(mem.ToArray(), 0, (int)mem.Length);
WebClient webClient = new WebClient();
webClient.Headers["Content-type"] = "application/json";
webClient.Encoding = Encoding.UTF8;
var result = webClient.UploadString("https://test.xxxx.com/DialService/TelephonyService.svc/Dial","POST", data);
I have tried with different values in protocolMapping, but the results are same. Any help will be appreciated.
It seems to me that there are no errors in you project. Besides protocol mapping is the new feature in Net4.5, which could help us simplify settings.
https://learn.microsoft.com/en-us/dotnet/framework/wcf/simplified-configuration
How to make WCF Service Use HTTPS protocol
There might be some small problems during the process of hosting the service on the IIS.
Could you access the WSDL page successfully?
Like the following form.
We might need to enable the WCF feature in the control panel.
I have made an example, wish it is useful to you.
Server-side (WCF service application).
IService1
[ServiceContract]
public interface IService1
{
[OperationContract]
[WebGet]
string GetData(int value);
[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);
[OperationContract]
[WebInvoke(UriTemplate ="/MyTest",Method ="POST",RequestFormat =WebMessageFormat.Json,ResponseFormat =WebMessageFormat.Json)]
string Test(CompositeType compositeType);
}
[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello ";
[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
public override string ToString()
{
return $"The BoolValue is {boolValue}, StringValue is {stringValue}";
}
}
Service1.svc.cs
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite == null)
{
throw new ArgumentNullException("composite");
}
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
public string Test(CompositeType compositeType)
{
return compositeType.ToString();
}
}
Web.config
<system.serviceModel>
<behaviors>
<serviceBehaviors>
<behavior>
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior>
<webHttp />
</behavior>
</endpointBehaviors>
</behaviors>
<bindings>
<webHttpBinding>
<binding name="mybinding">
<security mode="Transport">
<transport clientCredentialType="None"></transport>
</security>
</binding>
</webHttpBinding>
</bindings>
<protocolMapping>
<add binding="webHttpBinding" scheme="http"/>
<add binding="webHttpBinding" scheme="https" bindingConfiguration="mybinding"/>
</protocolMapping>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
IIS(new website)
Client(generate the data contract by adding service reference)
static void Main(string[] args)
{
//for validating the self-signed certificated.
ServicePointManager.ServerCertificateValidationCallback += delegate
{
return true;
};
ServiceReference1.CompositeType composite = new ServiceReference1.CompositeType()
{
StringValue = "Hello",
BoolValue = true
};
DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(ServiceReference1.CompositeType));
MemoryStream ms = new MemoryStream();
serializer.WriteObject(ms, composite);
string data = Encoding.UTF8.GetString(ms.ToArray(), 0, (int)ms.Length);
WebClient webclient = new WebClient();
webclient.Headers["Content-type"] = "application/json";
webclient.Encoding = Encoding.UTF8;
var result = webclient.UploadString("https://localhost:8734/service1.svc/MyTest", "POST", data);
Console.WriteLine(result);
WebClient webclient2 = new WebClient();
webclient2.Headers["Content-type"] = "application/json";
webclient2.Encoding = Encoding.UTF8;
var result2 = webclient2.UploadString("http://localhost:8733/service1.svc/MyTest", "POST", data);
Console.WriteLine(result2);
}
Result.
Besides, PostMan is good choice to test Rest style service.
Feel free to let me know if the problem still exists.

Native Client - Serialization Exception when executing Continuous Query

I'm trying to set up a simple Java <-> #C/.NET proof of concept using Apache Geode, specifically testing the continuous query functionality using the .NET native client. Using a regular Query works fine from .NET, only the Continuous Query has an issue. I run into my problem when I call the Execute() method on the continuous query object. The specific error I get is
Got unhandled message type 26 while processing response, possible serialization mismatch
I'm only storing simple strings in the cache region so I'm a bit surprised that I'm having serialization issues. I've tried enabling PDX serialization on both sides (and running without it), it doesn't seem to make a difference. Any ideas?
Here is my code for both sides:
Java
Starts a server, puts some data, and then keeps updating a given cache entry.
public class GeodePoc {
public static void main(String[] args) throws Exception {
ServerLauncher serverLauncher = new ServerLauncher.Builder().setMemberName("server1")
.setServerBindAddress("localhost").setServerPort(10334).set("start-locator", "localhost[20341]")
.set(ConfigurationProperties.LOG_LEVEL, "trace")
.setPdxReadSerialized(true)
.set(ConfigurationProperties.CACHE_XML_FILE, "cache.xml").build();
serverLauncher.start();
Cache c = CacheFactory.getAnyInstance();
Region<String, String> r = c.getRegion("example_region");
r.put("test1", "value1");
r.put("test2", "value2");
System.out.println("Cache server successfully started");
int i = 0;
while (true) {
r.put("test1", "value" + i);
System.out.println(r.get("test1"));
Thread.sleep(3000);
i++;
}
}
}
Server cache.xml
<?xml version="1.0" encoding="UTF-8"?>
<cache xmlns="http://geode.apache.org/schema/cache" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd"
version="1.0">
<cache-server bind-address="localhost" port="40404"
max-connections="100" />
<pdx>
<pdx-serializer>
<class-name>org.apache.geode.pdx.ReflectionBasedAutoSerializer</class-name>
<parameter name="classes">
<string>java.lang.String</string>
</parameter>
</pdx-serializer>
</pdx>
<region name="example_region">
<region-attributes refid="REPLICATE" />
</region>
</cache>
.NET Client
public static void GeodeTest()
{
Properties<string, string> props = Properties<string, string>.Create();
props.Insert("cache-xml-file", "<path-to-cache.xml>");
CacheFactory cacheFactory = new CacheFactory(props)
.SetPdxReadSerialized(true).SetPdxIgnoreUnreadFields(true)
.Set("log-level", "info");
Cache cache = cacheFactory.Create();
cache.TypeRegistry.PdxSerializer = new ReflectionBasedAutoSerializer();
IRegion<string, string> region = cache.GetRegion<string, string>("example_region");
Console.WriteLine(region.Get("test2", null));
PoolManager pManager = cache.GetPoolManager();
Pool pool = pManager.Find("serverPool");
QueryService qs = pool.GetQueryService();
// Regular query example (works)
Query<string> q = qs.NewQuery<string>("select * from /example_region");
ISelectResults<string> results = q.Execute();
Console.WriteLine("Finished query");
foreach (string result in results)
{
Console.WriteLine(result);
}
// Continuous Query (does not work)
CqAttributesFactory<string, object> cqAttribsFactory = new CqAttributesFactory<string, object>();
ICqListener<string, object> listener = new CacheListener<string, object>();
cqAttribsFactory.InitCqListeners(new ICqListener<string, object>[] { listener });
cqAttribsFactory.AddCqListener(listener);
CqAttributes<string, object> cqAttribs = cqAttribsFactory.Create();
CqQuery<string, object> cquery = qs.NewCq<string, object>("select * from /example_region", cqAttribs, false);
Console.WriteLine(cquery.GetState());
Console.WriteLine(cquery.QueryString);
Console.WriteLine(">>> Cache query example started.");
cquery.Execute();
Console.WriteLine();
Console.WriteLine(">>> Example finished, press any key to exit ...");
Console.ReadKey();
}
.NET Cache Listener
public class CacheListener<TKey, TResult> : ICqListener<TKey, TResult>
{
public virtual void OnEvent(CqEvent<TKey, TResult> ev)
{
object val = ev.getNewValue() as object;
TKey key = ev.getKey();
CqOperation opType = ev.getQueryOperation();
string opStr = "DESTROY";
if (opType == CqOperation.OP_TYPE_CREATE)
opStr = "CREATE";
else if (opType == CqOperation.OP_TYPE_UPDATE)
opStr = "UPDATE";
Console.WriteLine("MyCqListener::OnEvent called with key {0}, op {1}.", key, opStr);
}
public virtual void OnError(CqEvent<TKey, TResult> ev)
{
Console.WriteLine("MyCqListener::OnError called");
}
public virtual void Close()
{
Console.WriteLine("MyCqListener::close called");
}
}
.NET Client cache.xml
<client-cache
xmlns="http://geode.apache.org/schema/cache"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd"
version="1.0">
<pool name="serverPool" subscription-enabled="true">
<locator host="localhost" port="20341"/>
</pool>
<region name="example_region">
<region-attributes refid="CACHING_PROXY" pool-name="serverPool" />
</region>
</client-cache>
This ended up being a simple oversight on my part. In order for continuous query to function you must include the geode-cq dependency on the Java side. I didn't do this, and this caused the exception.

Spring AOP #Aspect J : how do I give Aspects access to other classes

I am quite new to Java and Spring. I would like to find out if it is possible and if so how I can get my aspects to apply to more than one class without having to call the method from the class where the aspects "work".
This is my main class. Aspects work on any methods I call diresctly from this class, but will not work on any of the other methods called by other classes (even if they are not internal)
public class AopMain {
public static void main(String[] args) {
String selection = "on";
ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
do {
try{
System.out.println("Enter 'length' for a length conversion and 'temperature' for a temperature conversion and 'quit' to quit");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
selection = br.readLine();
if(selection.contentEquals("length")) {
LengthService lengthService = ctx.getBean("lengthService", LengthService.class);
lengthService.runLengthService();
lengthService.display();
}
else if(selection.contentEquals("temperature")) {
TemperatureService temperatureService = new TemperatureService();
temperatureService.runTempertureService();
temperatureService.display();
}
}
catch (Exception e) {
System.out.println("Input error");
}
} while (!selection.contentEquals("quit"));
}
}
This is one of the conversion service classes:
public class TemperatureService {
String fromUnit = null;
String toUnit = null;
double val = 0;
double converted = 0;
public void runTempertureService() {
Scanner in = new Scanner(System.in);
System.out.println("Convert from (enter C, K, F): ");
fromUnit = in.nextLine();
System.out.println("Convert to (enter C, K, F): ");
toUnit = in.nextLine();
TemperatureConverter from = new TemperatureConverter(fromUnit);
TemperatureConverter to = new TemperatureConverter(toUnit);
System.out.println("Value:");
val = in.nextDouble();
double celcius = from.toCelcius(val);
converted = to.fromCelcius(celcius);
from.display(val, fromUnit, converted, toUnit);
System.out.println(val + " " + fromUnit + " = " + converted + " " + toUnit);
}
public String[] display(){
String[] displayString = {Double.toString(val), fromUnit, Double.toString(converted), toUnit};
return displayString;
}
}
And this is one of the conversion classes:
public class TemperatureConverter {
final double C_TO_F = 33.8;
final double C_TO_C = 1;
final double C_TO_KELVIN = 274.15;
private double factor;
public TemperatureConverter(String unit) {
if (unit.contentEquals("F"))
factor = C_TO_F;
else if(unit.contentEquals("C"))
factor = C_TO_C;
else if(unit.contentEquals("K"))
factor = C_TO_KELVIN;
}
public double toCelcius(double measurement) {
return measurement * factor;
}
public double fromCelcius(double measurement) {
return measurement/factor;
}
public TemperatureConverter() {}
public void display(double val, String fromUnit, double converted, String toUnit) {}
}
This is my configuration file:
<?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:aop="http://www.springframework.org/schema/aop" 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.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<aop:aspectj-autoproxy/>
<bean name= "lengthConverter" class= "converter.method.LengthConverter"/>
<bean name= "temperatureConverter" class= "converter.method.TemperatureConverter"/>
<bean name= "lengthService" class= "converter.service.LengthService" autowire = "byName"/>
<bean name= "temperatureService" class= "converter.service.TemperatureService"/>
<bean name="ValidationAspect" class= "converter.aspect.ValidationAspect" />
<bean name="DisplayAspect" class= "converter.aspect.DisplayAspect" />
</beans>
I want to be able to apply an aspect to functions of the converter class called by the service class but like I have mentioned, it doesnt work unnless the method is called from the main class directly. (the display function was originally part of the converter class but I moved it so that the aspect would work). Also why will an aspect not pick up the newline() method call?
Edit:
This is one of my aspects:
#Aspect
public class DisplayAspect {
#AfterReturning(pointcut = "execution(* display(..))", returning = "retVal")
public void fileSetUp(Object retVal) {
System.out.println("So we found the display things");
Writer writer = null;
String[] returnArray = (String[]) retVal;
try {
System.out.println("inside try");
String text = "The opertion performed was: " + returnArray[0] + " in " + returnArray[1] + " is " + returnArray[2] + " " + returnArray[3] + "\n";
File file = new File("Log.txt");
writer = new BufferedWriter(new FileWriter(file, true));
writer.write(text);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
I want to be able to apply an aspect to functions of the converter class
Well, then change your pointcut so as intercept the methods (not functions, they are called methods) you want to handle in your advice. At the moment the pointcut is
execution(* display(..))
I.e. it will intercept all methods named display with any number of parameters and any return type. If you want to intercept all converter methods instead, change it to
execution(* converter.method.TemperatureConverter.*(..))
instead.
like I have mentioned, it doesnt work unnless the method is called from the main class directly.
I need to guess because this description is unclear, but probably What you are trying to describe is that the advice is only applied if the TemperatureService.display() is called from outside the class, not from a method within TemperatureService. This is a known and well described limitation of Spring AOP, see Spring Manual, chapter 9.6, "Proxying mechanisms": Due to the proxy-based "AOP lite" approach of Spring AOP, this cannot work because internal calls to methods of this, are not routed through the dynamic proxy created by the Spring container. Thus, Spring AOP only works for inter-bean calls, not intra-bean ones. If you need to intercept internal calls, you need to switch to full-blown AspectJ, which can be easily integrated into Spring applications via LTW (load-time weaving) as described in chapter 9.8, "Using AspectJ with Spring applications".

primefaces FileUploadEvent returns null

I'm trying to upload a file with primefaces fileuploader but it returns null,
addPhotos.xhtml :
<h:form id="importDevicesForm" enctype="multipart/form-data">
<h:outputText value="Photo :" />
<p:fileUpload id="scriptUpload"
widgetVar="importDevicesWidget"
fileUploadListener="#{docBean.file}"
auto="true"
label="Choisir une photo.."
mode="advanced"
allowTypes="/(\.|\/)(gif|jpe?g|png)$/">
<h:outputText value="Description :" />
<p:commandButton value="Ajouter" action="#{docBean.ajouter_photo}"/>
</h:form>
My backing bean : I want to upload the file an use an outputStream to write the file in filesystem.
#ManagedBean(name = "docBean")
#SessionScoped
public class DocumentBean implements Serializable {
private static final long serialVersionUID = 1L;
private UploadedFile file = null;
private File doc;
private InfoDAO docdao = new InfoDaoImpl();
public UploadedFile getFile() {
return file;
}
public void setFile(FileUploadEvent event) {
this.file = event.getFile();
}
public String ajouter_photo() throws SQLException, IOException
{
System.out.println("call");
File targetFolder = new File("C:/images/upload");
InputStream inputStream = this.file.getInputstream();
OutputStream out = new FileOutputStream(new File(targetFolder,
this.file.getFileName()));
int read = 0;
byte[] bytes = new byte[1024];
while ((read = inputStream.read(bytes)) != -1) {
out.write(bytes, 0, read);
}
inputStream.close();
out.flush();
out.close();
Document f = new Document();
f.setDescription(targetFolder.getPath());
docdao.Ajouter_info(f);
}
here is the exception
Avertissement: #{docBean.ajouter_photo}: java.lang.NullPointerException
javax.faces.FacesException: #{docBean.ajouter_photo}: java.lang.NullPointerException
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:117)
Here, it is for your reference.
upload.xhtml
<h:form enctype="multipart/form-data">
<p:fileUpload value="#{PrimefacesFileUpload.uploadedFile}" mode="simple" sizeLimit="50000"
allowTypes="/(\\\\\\\\./\\\\\\\\/)(gif|jpe?g|png|txt)$/"/>
<p:growl id="messages" showDetail="true"/>
<p:commandButton value="Submit" actionListener="#{PrimefacesFileUpload.upload}" ajax="false"/>
</h:form>
PrimefacesFileUpload.java
#ManagedBean(name = "PrimefacesFileUpload")
public class PrimefacesFileUpload {
private UploadedFile uploadedFile;
public void setUploadedFile(UploadedFile uploadedFile) {
this.uploadedFile = uploadedFile;
}
public UploadedFile getUploadedFile() {
return uploadedFile;
}
public void upload(ActionEvent event) {
String fileName = uploadedFile.getFileName();
byte[] content = uploadedFile.getContents();
String contentType = uploadedFile.getContentType();
// Keep upload file
FacesContext.getCurrentInstance().addMessage("messages", new FacesMessage("Successful! " + uploadedFile.getFileName() + " is uploaded."));
}
}
web.xml - Make sure to config
<filter>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
<init-param>
<param-name>thresholdSize</param-name>
<param-value>51200</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>PrimeFaces FileUpload Filter</filter-name>
<servlet-name>Faces Servlet</servlet-name>
</filter-mapping>
Try following code:
xhtml:
<h:form enctype="multipart/form-data">
<p:fileUpload
id="scriptUpload"
widgetVar="importDevicesWidget"
fileUploadListener="#{imageUpload_2.handleFileUpload}"
value="#{imageUpload_2.uploaded_image}"
auto="true"
label="Choisir une photo.."
mode="advanced"
allowTypes="/(\.|\/)(gif|jpe?g|png)$/"
/>
<p:commandButton id="btn_save"
value="Save To Database"
actionListener="#{imageUpload_2.btn_save_clicked}"/>
</h:form>
jsf:
#ManagedBean
#ViewScoped
public class ImageUpload_2 implements Serializable {
UploadedFile uploaded_image;
public UploadedFile getUploaded_image() {
return uploaded_image;
}
public void setUploaded_image(UploadedFile uploaded_image) {
this.uploaded_image = uploaded_image;
}
String upload_location;
public String getUpload_location() {
return upload_location;
}
public void setUpload_location(String upload_location) {
this.upload_location = upload_location;
}
public void handleFileUpload(FileUploadEvent event) {
uploaded_image = event.getFile();
ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
String v_file_ext = uploaded_image.getFileName().split("\\.")[(uploaded_image.getFileName().split("\\.").length) - 1];
upload_location = servletContext.getRealPath("") + File.separator + "temp-images" + File.separator + "3" + "." + v_file_ext;
FileImageOutputStream imageOutput;
try {
imageOutput = new FileImageOutputStream(new File(upload_location));
imageOutput.write(uploaded_image.getContents(), 0, uploaded_image.getContents().length);
imageOutput.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void btn_save_clicked(ActionEvent event) {
byte[] file = new byte[uploaded_image.getContents().length];
System.arraycopy(uploaded_image.getContents(), 0, file, 0, uploaded_image.getContents().length);
//ent.setImg(file);
//yourfacade.create(ent);
}
public ImageUpload_2() {
}
}
Where ent is the object of Entity Class and img (setImg) is database column of BLOB type.You just need to create "temp-images" folder in you project under web folder where xhtml files are lying. Tell me if you are still having any issue.

Element is not an instance of type

I am using Linq To XSD to send data over MSMQ. Here is my sending code
public void Send()
{
string criMessageQueuePath = ConfigurationManager.AppSettings["CRIMessageQueuePath"];
if (!MessageQueue.Exists(criMessageQueuePath))
{
MessageQueue.Create(criMessageQueuePath, false);
}
var messageQueue = new MessageQueue(criMessageQueuePath) { Label = "CRI Message Queue" };
messageQueue.Formatter = new XmlMessageFormatter(new[] { typeof(XML) });
var transaction = new MessageQueueTransaction();
transaction.Begin();
messageQueue.Send(CreateAuction(1), transaction);
messageQueue.Send(CreateAuction(2), transaction);
messageQueue.Send(CreateAuction(3), transaction);
messageQueue.Send(CreateAuction(4), transaction);
messageQueue.Send(CreateAuction(5), transaction);
transaction.Commit();
}
private XML CreateAuction(int id)
{
var message = new XML {id = id};
return message;
}
Here is my receiving code
public IEnumerable<string> Receive()
{
string criMessageQueuePath = ConfigurationManager.AppSettings["CRIMessageQueuePath"];
var messageQueue = new MessageQueue(criMessageQueuePath);
Message[] messages = messageQueue.GetAllMessages();
foreach (Message message in messages)
{
message.Formatter = new XmlMessageFormatter(new[] { typeof(XML) });
yield return message.Body.ToString();
}
messageQueue.Purge();
}
I've tried lots of variations of this code but can't figure out why I can't get a valid XML object out the other end.
Currently, my code is failing when I call it
static void Main()
{
var sender = new Sender.Sender();
sender.Send();
var receiver = new Receiver.Receiver();
foreach (var xml in receiver.Receive())
{
var typedXML = XML.Parse(xml);
Console.WriteLine(typedXML.id);
}
}
The line it fails on is var typedXML = XML.Parse(xml);. The error is
Element is not an instance of type Domain.XML
The XSD for the object is
<?xml version="1.0" encoding="Windows-1252"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="Domain">
<xs:element name="XML">
<xs:complexType>
<xs:sequence>
<xs:element name="id" type="xs:int" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Looking at the value of xml on the line
var typedXML = XML.Parse(xml);
I can see that it generates this
"<XML>\r\n <XML xmlns=\"Domain\">\r\n <id>1</id>\r\n </XML>\r\n</XML>"
In other words it generates an additional xml node around the whole xml. If I remove this extra node in the debugger then it all works. what am I doing wrong?
This is the result of using hte XmlMessageFormatter as it serializes your object and wraps it in XML. I would suggest that you write your XML document directly to the BodyStream property instead.
var msg = new Message();
var writer = new StreamWriter(msg.BodyStream);
writer.Write(xmlDoc.ToString());
writer.Flush();
queue.Send(msg);
This way you have full Control over what is sent in your queue. The formatters are mostly there for legacy use and should not be used when sending XML documents as messages.