request definition in wadl file - jersey

Is there any way the wadl can tells the request type. For example the following PUT method expect a xml data type of "setBlockRequest", is there any way I can reference it to the xml schema(xsd file) to define the content of "setBlockRequest"?
This wadl is generated by Jersey.
<resource path="/appliance/{device_id}/update_multiple_values">
<param xmlns:xs="http://www.w3.org/2001/XMLSchema" name="device_id" style="template" type="xs:string"/>
<method id="setBlockValue" name="PUT">
<request>
<ns2:representation xmlns:ns2="http://wadl.dev.java.net/2009/02" xmlns="" element="setBlockRequest" mediaType="application/xml"/>
</request>
</method>
</resource>}

yes, there is. See http://www.w3.org/Submission/wadl/#x3-40001.3 (<grammars> tag).
Jersey now generated it automatically for you but only for cases where your type is annotated with JAXB annotations. (This is valid since Jersey 1.13 if I remember correctly, so you might want to give it a try).

Related

Rest DSL path typing to a POJO, can I register the POJO as a Bean and call the id to reference it?

This is a very low impact "issue" and I'm just looking out to learn something new about Camel and how it works.
I'm working to build a springboot service using camel context routes, and while it's working fine (so far), I'd like to set the rest path type to a class without having to explicitly call the package location, and instead, reference the class as a bean and use it's id to call it.
I have defined a camelContext, I have the rest, restConfigurations and the necessary http methods (get, post, put...), here's a mock of what I have right now.
I've registered a ServiceImpl class as a bean and have given it the id Service. In the Route, I can call the bean using a ref to it's id, and select the method that I want.
<beans xmlns ...>
...
<!-- start services -->
<bean class="com.daniel.rest-project.services.ServiceImpl" id="Service"/>
<!-- end services -->
...
<camelContext id="context" xmlns="http://camel.apache.org/schema/spring">
<rest bindingMode="au <!-- <to id="to-7b30ace2-b26d-4301-8bb0-ef007d566ab3" uri="direct:501"/> -->to" enableCORS="true" id="rest">
...
<post consumes="application/json" id="newTask" produces="application/json" uri="/task" type="com.daniel.rest-project.vo.TaskVO">
<description>New Task Object</description>
<param description="Task Object Body." name="body" required="true" type="body"/>
<to uri="direct:newTask"/>
</post>
...
</rest>
...
<route id="route-task-new">
<from id="from-task-new" uri="
<bean id="to-task-new" method="newTask" ref="Service"/>
</route>
...
</camelContext>
</beans>
Now, I've actually got implemented around 150 routes (project is pretty big) and I'm tired of having to declare the rest post type, right now it's using something not really similar to com.daniel.rest-project.vo..
There's a ton of classes that are named similarly and due to internal reasons, best practices are scarce, naming conventions are weird, there's more than one package I need to go to, etc.
It would feel a lot more organized to just define all the objects I need at the start of the XML file and reference them as I go, instead of having to state the whole way there every time, so, is there a way I can define those classes at the start, just like the services, and tell the post rest path to use the id of the bean, instead of having to give it the whole class location? There must be a way and I'm sure I've just been blind enough not to see it in the documentation for the past weeks.
Here's one of the methods I've tried thus far:
<!-- start classes -->
<bean class="com.daniel.rest-project.vo.TaskVO" id="TaskVO"/>
<!-- end classes -->
and then, tell the path to do something like this
<post consumes="application/json" id="newTask" produces="application/json" uri="/task" type="TaskVO">
<description>New Task Object</description>
<param description="Task Object Body." name="body" required="true" type="body"/>
<to uri="direct:newTask"/>
</post>
Which resulted in the following error:
Caused by: org.apache.camel.FailedToCreateRouteException: Failed to create route newTask: Route(newTask)[[From[rest:post:/task?routeId=newTask&... because of java.lang.ClassNotFoundException: TaskVO
at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:209)
at org.apache.camel.impl.DefaultCamelContext.startRoute(DefaultCamelContext.java:1143)
..........
Caused by: org.apache.camel.RuntimeCamelException: java.lang.ClassNotFoundException: TaskvO
at org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1830)
at org.apache.camel.impl.DefaultRouteContext.commit(DefaultRouteContext.java:206)
at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:1307)
at org.apache.camel.model.RouteDefinition.addRoutes(RouteDefinition.java:204)
TaskVO implements Serializable, and only has one, empty, public constructor, followed by all of it's getters and setters.

Proper ObjectFactory in MyBatis TypeHandler

I'm creating a project in Spring-ws with MyBatis.
I have many web services definitions in xsd.
Spring is creating POJO classes based on xsd.
The problem is that in xsd I have fields that have parameter nillable="true"
like this:
<xs:element name="numericParam" type="xs:int" minOccurs="0" maxOccurs="1" nillable="true"/>
That field in generated POJO looks like this:
protected JAXBElement<Integer> numericParam;
I want to create custom TypeHandler in MyBatis config, to handle JAXBElement<Integer> types, but how can I know which ObjectFactory to use.
Is it possible to know which mapper is calling my custom TypeHandler? In TypeHandler all I have is column name.
This is not possible currently (version 3.4.6) in mybatis. No information about the context (like enclosing type or mapper method) is passed to handler.
If you do want to use jaxb generated types you would need to create a handler per field (of cause it make sense to have common base that would implement all the logic).

How to create two instances of the same spring controller, each with a different base #requestMapping

I have a spring controller (MyController) which servers data as json.
With a few configuration changes, I will be able to reuse the same controller and have it serve the same data, but as xml, not json.
I'd love to be able to create myControllerInstanceA, and configure it to use /json as a base url, then create myControllerInstanceB and have it use /xml as a base url.
The only way I can think of to do this is to subclass MyController, and set the subclass's #requestMapping to /xml. I'd rather be able to do some configuration in my springap-servlet.xml to achieve the same effect.
Is this possible?
I'm guessing some of you spring wizards reading this might be thinking "why the heck would he want to do that". So I'll explain the techniques i'm using: I'm creating a controller, which adds simple java beans to a ModelAndView. The controller also ads a view. The view takes the java beans and serializes them to json, or to xml, depending on how the controller was configured. I think there is probably a more Spring-ish way to do this, but this approach seemed simple and straightforward enough. Also, it allows me to work with a JSON library I'm familiar with, rather than the one that Spring seems set up to use. Points for anyone who tells me the Spring way to do it -- how to easily serve the same data as either json or xml, reusing controller code as much as possible.
Use ContentNegotiatingViewResolver to resolve the views. This resolve will use different configured views to render the model based on the request's Accepts Header or extension. By default it uses the MappingJacksonJsonView for JSON and you will have to configure an Xml Marshaller for use with the MarshallingView.
With this configuration you can have each annotated method support infinite data formats.
Check out this example.
I'm not sure if you're asking for this, but Spring 3 has ContentNegotiationResolver which can help to return json or xml:
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="mediaTypes">
<map>
<entry key="xml" value="application/xml"/>
<entry key="json" value="application/json"/>
</map>
</property>
</bean>
And in the controller you can map json and xml to the same controller method.
#Controller
class MyClass(){
#RequestMapping(value={"/yourURL.json", "/yourURL.xml"})
public Object yourController(){
return Object
}
}

Spring RegisterSingleton

I have a following object:
public class TestObject
{
public String Something { get; set; }
}
and a following objects file:
<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.net http://www.springframework.net/xsd/spring-objects.xsd">
<object id="TestObject" type="SpringTest.TestObject" autowire="byName"/>
</objects>
What I would like to do is to register singleton and get the TestObject. I am doing this like so:
IConfigurableApplicationContext context = new XmlApplicationContext("objects.xml");
context.ObjectFactory.RegisterSingleton("Something", "something to test");
object obj = context.GetObject("TestObject");
But the objects property Something is always null. I think that this should work or am I doing something wrong?
Many thanks!
I'm not sure what the problem statement is exactly (never used Spring for .NET). But if you want what Don Kirkby suggest you should lookup TargetSources in the reference documentation (assuming that the .NET implementation has them, too).
I think your Something property is not getting set because singletons are instantiated when the application context is instantiated. When you call RegisterSingleton, the TestObject has already been created. The bean wiring is only done when a bean is created.
You might be able to work around this problem by making the singleton instantiate lazily. That way it isn't instantiated until the first time it's requested. Hopefully, that's after you've registered the other singletons it needs.
I don't know exactly what you're trying to accomplish, but if I wanted to change the wiring between some singleton beans at run time without making the beans aware of it, I would introduce some wrapper objects. Each wrapper would implement an interface and then just delegate all methods to its current target bean. To change the wiring, you just change the wrapper's target.
Update: as yawn suggested, Spring.NET has hot-swappable target sources that let you swap out the implementation of a bean at run time. Here's some sample code from the documentation that shows how to swap the bean implementation:
HotSwappableTargetSource swapper =
(HotSwappableTargetSource) objectFactory.GetObject("swapper");
object oldTarget = swapper.swap(newTarget);
The XML definitions in the documentation look like this:
<object id="initialTarget" type="MyCompany.OldTarget, MyCompany">
</object>
<object id="swapper"
type="Spring.Aop.Target.HotSwappableTargetSource, Spring.Aop">
<constructor-arg><ref local="initialTarget"/></constructor-arg>
</object>
<object id="swappable"
type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop">
<property name="targetSource">
<ref local="swapper"/>
</property>
</object>
Why aren't you using scope="singleton" if you want a singleton or am I missing something?

How can I mix and match custom Spring schema types with traditional Spring schema types?

Let's say I have a class Person with properties name and age, and it can be configured with Spring like so:
<beans:bean id="person" class="com.mycompany.Person">
<beans:property name="name" value="Mike"/>
<beans:property name="age" value="38"/>
</beans:bean>
I'd like to have a custom Spring schema element for it, which is easy to do, allowing me to have this in my Spring configuration file:
<Person name="Mike" age="38"/>
The schema definition would look something like this:
<xsd:complexType name="Person">
<xsd:complexContent>
<xsd:extension base="beans:identifiedType">
<xsd:attribute name="name" type="xsd:string"/>
<xsd:attribute name="age" type="xsd:int"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
Based on this, let's now say I would like the option of mixing and matching my custom schema element with traditional elements and attributes of Spring beans, so I could have the option of doing this:
<Person name="Mike">
<beans:property name="age" value="38"/>
</Person>
How would I go about doing that? Perhaps this is impossible without some major customization, but I'm hoping there is some fairly simple mechanism to achieve this. I thought extending "bean" might be the trick, but that doesn't look to be correct.
First of, if your example is really all you want to do, consider using p-namespace instead and save yourself some major headache:
<beans:bean id="person" class="com.mycompany.Person" p:name="Mike" p:age="38"/>
Yes, it doesn't look as pretty as <Person name= age= /> but there's no custom code to write :-)
If that does not satisfy your requirements, you're looking at implementing your own namespace / bean definition parser. Spring documentation has a chapter dedicated to that which will explain it better then I can. If you hit any issues, please post back specific questions and I'll try to help.

Resources