Apache cxf jax-rs implementation with xml databind - jax-rs

I configured my rest service to implement content negotiation through Variant.
On jersey all works fine but on apache cxf something goes wrong.
No message body writer has been found for class ContentType: application/xml
It seems thath when I construct the response as xml type it cannnot find the correct body writer.
I configured jax-rs with jacksonJaxbJsonProvider and all works great with json databind.
<jaxrs:providers>
<bean class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider" />
</jaxrs:providers>
cxf-rt-frontend-jaxrs version 3.0.3
jackson-databind: 2.4.2
Any idea?

Add a #XmlRootElement(name="order") generated xml cannot be <orderId>data<orderId>, it should have root element. Thus updated code would look like
#XmlRootElement(name="order")
#XmlType(propOrder = { "orderId"})
public class OrderForConfirmationEmail implements Serializable {
#XmlElement
public long getOrderId() {
long orderId = new Random().nextLong();
return orderId;
}
}
Generated xml is
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><order xmlns="http://com.kp.swasthik/so/schema">
<orderId>369317779145370211</orderId>
</order>
and json is
{"orderId":6812414735706519327}

Related

RestSharp AddJsonBody serialization camel case

I'm using RestSharp v107.1.1 in a .net 5.0 core web app and when i add an object to my RestRequest with AddJsonBody it's serializing the property names in camel casing.
How do i make RestSharp not modify the property names when serializing!?
request.AddJsonBody(new { IHateCamelCase = "why you do this!" });
results in
CONTENT <root type="object"> <iHateCamelCase type="string">why you do this!</iHateCamelCase> </root>
when it should look like this
CONTENT <root type="object"> <IHateCamelCase type="string">why you do this!</iHateCamelCase> </root>
An example would be great!
You need to configure the serializer as you would do with anything else.
var options = new JsonSerializerOptions(JsonSerializerDefaults.General);
client.UseSystemTextJson(options);

How can I attach BinarySecurityToken in request header(.net core)

I want to create something like below
<soapenv:Header>
<wsse:Security>
<wsse:BinarySecurityToken EncodingType="XXXX" ValueType="XXX">Token
</wsse:BinarySecurityToken>
</wsse:Security>
</soapenv:Header>
I manage to acheive this by using the below code, which is working (well Kind of!)
using (new OperationContextScope(experianProxy.InnerChannel))
{
DataContractJsonSerializer serializer =new
DataContractJsonSerializer(typeof(BinarySecurityToken));
MessageHeader header = MessageHeader.CreateHeader("wsse:Security", "",
_token,serializer);
OperationContext.Current.OutgoingMessageHeaders.Add(header);
var interactiveResponse = experianProxy.InteractiveAsync(new Root()).Result;
return interactiveResponse.OutputRoot.ToString();
}
and
[XmlRoot(ElementName = "wsse:BinarySecurityToken", Namespace = "")]
public sealed class BinarySecurityToken : IXmlSerializable
{...}
Now the request going out is,
<soapenv:Header>
<wsse:Security><wsse_x003A_BinarySecurityToken ValueType="xxxx"
EncodingType="wsse:Base64Binary"
>XXXXXXXXXXX</wsse_x003A_BinarySecurityToken>
</wsse:Security>
</soapenv:Header>
Converting cdata didn't help.
Can someone please point out what am I missing? Any help is much appreciated.
Thank you.
The scope of OperationContextScope is only valid within the using statement. after the instance of OperationContextScope is released, the OperationContext is restored and the message header is no longer valid. if you try to call the method in the using statement, you will find your custome header.
You can use the IClientMessageInspector interface if you want to permanently add message headers to requests.
https://social.msdn.microsoft.com/Forums/vstudio/en-US/f1f29779-0121-4499-a2bc-63ffe8025b21/wcf-security-soap-header

Spring Data Rest Jpa insert #Lob field

I have a spring data rest service, that expose a resource like:
#Entity
public class Resource{
private String name;
#Lob
private byte[] data;
private String contentType;
}
How should be a json to insert a resource of this type?
AFAIK, SDR does not handle multipart requests or responses yet, as it can only do JSON.
You can run SDR at the same time as a regular Spring MVC servlet (it's one line of code in your config).
I would suggest using a regular Spring MVC controller for your file upload/download, and SDR for the rest (pun intended).
You don't need JSON.
"name" and "contentType" are part of the http header (respectively "Content-Type" and "Content-Disposition: filename")
"data" is the HTTP body. Its encoding depends of "Content-Encoding"
Maybe you should use "ResourceResolvers" plugged with JPA.
Spring Content was designed for exactly this.
Assuming you are using Spring Boot then you can add LOB handling as follows:
pom.xml
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-jpa-boot-starter</artifactId>
<version>0.0.11</version>
</dependency>
<dependency>
<groupId>com.github.paulcwarren</groupId>
<artifactId>spring-content-rest-boot-starter</artifactId>
<version>0.0.11</version>
</dependency>
Add a Store:
#SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#StoreRestResource(path="resourceContent")
public interface ResourceContentStore extends ContentStore<Resource,String> {}
}
Associate content with your entity entity:
#Entity
public class Resource {
private String name;
#ContentId
private String contentId;
#ContentLength
private long contentLength = 0L;
#MimeType
private String mimeType = "text/plain";
}
That's all that you should need. When you application starts Spring Content will see the dependencies on the Spring Content JPA/REST modules and it will inject an implementation of the ResourceContentStore store for JPA as well as an implementation of a controller (at /resourceContent) that supports that maps GET, POST, PUT and DELETE requests onto the underlying Store interface. The REST endpoint will be available under.
i.e.
curl -X PUT /resourceContent/{resourceId} will create or update an resource's content
curl -X GET /resourceContent/{resourceId} will fetch the resource's content
curl -X DELETE /resourceContent/{resourceId} will delete the resources content
There are a couple of getting started guides here. They use Spring Content for the Filesystem but the modules are interchangeable. The JPA reference guide is here. And there is a tutorial video here.
HTH

Custom xml validation inside eclipse plugin with Custom Validator?

I want to validate a custom content type document(xml kind), with an custom validator. Want to validate it with a xsd, but only after certain preprocessing of main document.
Normal xml validator can't be used because-
1.) The schema location(xsd) & namespaces are not defined in the main document file.
2.) And bcz of first reason & many more, want to do some preprocessing to the document file, before applying xsd validation.
So I want to use the xml validator, but only after preprocessing of my file.
My plugin.xml is as follows:
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension
point="org.eclipse.core.runtime.contentTypes">
<content-type
id="com.xyz.ide.core.contentType.dummy"
base-type="org.eclipse.core.runtime.xml"
file-extensions="blabla"
/>
</extension>
<extension
point="org.eclipse.wst.sse.ui.sourcevalidation">
<validator
scope="total"
class="mc.CustomValidator"
id="com.xyz.myValidator">
<contentTypeIdentifier
id="com.xyz.ide.core.contentType.dummy">
<partitionType
id="org.eclipse.wst.xml.XML_DEFAULT">
</partitionType>
</contentTypeIdentifier>
</validator>
</extension>
</plugin>
CustomValidator.java
public class CustomValidator implements ISourceValidator, IValidator {
XMLValidator validator = new XMLValidator();
IDocument document;
public void validate(IValidationContext helper, IReporter reporter) {
String fileContent = this.document.get();
final InputStream is = new ByteArrayInputStream(fileContent.toLowerCase().getBytes());
// Whats the problem in this line???
XMLValidationReport report = validator.validate("/home/rchawla/xmlWorkspace/abc.xsd", is);
ValidationMessage[] messages = report.getValidationMessages();
for(ValidationMessage message:messages){
System.out.println(message.getMessage());
}
}
I can hit the validate method on running the plugin in debug mode, but
the document is not getting validated with the xsd.
What is wrong in the above method as,
ValidationMessage[] messages = report.getValidationMessages(); is giving zero messages, even though the there are errors in the main document file.
I also had a lot of trouble trying to make org.eclipse.wst.sse.ui.sourcevalidation extension point work. I ended up using another extension point org.eclipse.wst.validation.validatorV2. The only difference between the 2 validators is that this one is only triggered when you save a file, not while you are typing. See an example bellow :
<extension id="customValidator" name="Custom Validator" point="org.eclipse.wst.validation.validatorV2">
<validator class="aaa.bbb.CustomValidator" markerId="customMarker" version="3">
<include>
<rules>
<contentType id="customContentType" exactMatch="false"/>
</rules>
</include>
</validator>
</extension>
Your implementation of the validator should override org.eclipse.wst.validation.AbstractValidator.

NServiceBus allows control over deserialization?

I am trying to integrate a legacy application with NServiceBus by wrapping XML exports from the application with a NServiceBus "wrapper" which basically strips out namespaces and adds the envelope and NSB namespace.
I have the basic solution working but only if the root element of the XML export exactly matches the NServiceBus message type name.
For example if the xml is:
<?xml version="1.0"?>
<Messages xmlns="http://tempuri.net/MyMessagesNamespace">
<!-- Note: the "V1" -->
<PolicyEndorsedV1>
...
</PolicyEndorsedV1>
</Messages>
then my handler code can happily deserialize:
namespace MyMessagesNamespace
{
public class PolicyEndorsedV1Handler : IHandleMessages<PolicyEndorsedV1>
{
public void Handle(PolicyEndorsedV1 message)
{
// All work fine!
...
}
}
}
However, if the export XML is
<?xml version="1.0"?>
<Messages xmlns="http://tempuri.net/MyMessagesNamespace">
<!-- Note: the "V1" has been removed -->
<PolicyEndorsed>
...
</PolicyEndorsed>
</Messages>
this will not be deserialised. NServiceBus tells me System.TypeLoadException: Could not handle type 'Beazley.Messages.Risks.Events.PolicyEndorsed', which is understandable as the only information it's got to go on is the name of the root node on the incoming xml.
I have tried to control the deserialization behaviour by adding some of the .Net Serialization attributes to my message definition:
[XmlRoot(ElementName = "PolicyEndorsed", Namespace = "", IsNullable = false)]
public partial class PolicyEndorsedV1
{
...
}
but this is ignored because NServiceBus uses it's own serializer (called XmlMessageSerializer) and not .Net's own XmlSerializer.
So does anyone know how I can do this? I think it would be nice to have the option to decouple the Xml names with their NSB messaging counterparts.
Many thanks
Does PolicyEndorsedV1 inherit from PolicyEndorsed?
If so, use IHandleMessages<PolicyEndorsed>, and PolicyEndorsedV1Handler will handle both types of objects.
For example:
public class PolicyEndorsedV1Handler : IHandleMessages<PolicyEndorsed>
{
public void Handle(PolicyEndorsed message)
{
// Handles both PolicyEndorsed and PolicyEndorsedV1 messages
}
}