There're few ways one can manipulate the message in Spring Integration. One way is calling a bean's method inside <int:enricher> that will return an object and assign it to the given name, e.g:
<!-- calls getKey method of IdGenerator bean which returns String with some value -->
<int:enricher input-channel="a.channel" output-channel="b.channel" id="preTranslator">
<int:header name="Key" expression="#IdGenerator.getId(payload)"/>
</int:enricher>
Same can be utilized in filtering:
int:filter discard-channel="d.channel" input-channel="b.channel" output-channel="c.channel"
expression="#Cache.hasKey(headers.Key) == false"/>
On the other hand I can call the <int:service-activator> on a class implementing MessageProcessor interface. It would take the original message and return a copy with a new header field. That requires my class's method to always build a new message with MessageBuilder though.
Currently I use the first way for simple field enrichment and service-activator for requesting data from DB/external services. What's the right way of picking the correct approach?
First of all, the <filter> doesn't change message at all. The given name should be read as header, looking to your case.
The <service-activator> always return a new message. Yes, you can populate new headers there as well and right you have to use MessageBuilder.
It is fully unclear what is your problem. If you can achieve the solution with expressions in the config, so be that. But if you do something with the message in the code and would like to add/edit/remove headers you use MessageBuilder.
That's really fine. I think you should just read more documentations and right more code in your application.
Eventually you will find the most convenient style for yourself. Fro example I end up once with expressions and Groovy scripts. No Java code at all. But right now I prefer Spring Integration Java DSL, because it is much faster, cleaner, fluent and lets get rid of any other configs like XML or Groovy. Everything is Java now and that MessageBuilder is still on the horse!
Related
In my application I need to use dynamic localization, so I cannot use Constants interface. I did use Constants for a while, but now I need texts to be changed without compiling so I had to find some other way.
So I am using Dictionary now. The thing is, when I now want to use text in UiBinder, I can only use methods without arguments. So I created class "StringIdentifiers" where I have the same methods I previously had in MyConstants, but I have to specify a body here for every method to return the specified String.
So for example I have:
Dictionary locale = Dictionary.getDictionary("myJsObjectWithStrings");
//and then the methods for returning the actual strings from the JS object
String loading(){
return locale.get("loading");
}
I would like the method to only be
String loading();
since the rest is always the same with the name of the method appearing as String parameter in the get() method. Possibly even returning some default value when the String is missing in the JS object. But I do not know how to do that. I checked the Constants interface, but I do not really understand the code there. Can someone please give me an example how to implement such a thing?
There is no standard feature in GWT to do this, but you could create one yourself. It's a bit of a stretch, but it should work by using the GWT generator mechanisch. In global terms it should work as follows:
Create an interface (say MyMessages) with a the method names.
To use it use MyMessages message = GWT.create(MyMessages.class). Where you need the text message.loading().
Create a generator that generates an class implementing the interface. This class will created at compile time and should contain the implementation of the interface methods, like in your example.
Add a generate-with tag in your gwt.xml file to make it work.
This is a bit of a brief explanation, but I hope it helps. For more background information about generators see: What is the use GWT generator? or http://blog.arcbees.com/2015/05/26/how-to-write-gwt-generators-efficiently/
You could even reuse some of GWT's annotation's of the i18n to add for example default texts. Add the annotation to your interface and in the generator scan the annotation and use it in the code generation part.
The scenario is simple:
UI call RESTful API to get an object tree, then UI change some data and call RESTful API to update it.
But for security or performance reason..., my RESTful API can NOT bring the whole object tree to the UI.
We have two choose for this purpose: creating an individual Java Bean for RESTful API or extend existing business Java Bean plus #JsonIgnore.
The second looks smarter because we re-use business class.
But Now we have a trouble: I need to merge the object from UI with the object from DB, otherwise I will lose some data.
But how do I know which piece of data will come from UI?
I know I can hard code to copy fields one by one.
But this way is dangerous.
I am asking for generic way to avoid hard code to copy fields.
I tried org.apache.commons.beanutils.BeanUtils, but it can't meet the requirement because it always overwrite target fields.
So I am thinking this way:
If the field in UI bean is not Null, then overwrite the value of the same name field in destination bean. but how do I handle if the field is some kind of primitive type like int which have default value 0?
I don't know if the field really carry an UI value 0 or just not comes back from UI.
I tried to convert primitive type to object type, but it still have troubles on boolean type, many java tools don’t support “ Boolean isValid(){…}” like BeanUtils. And this kind converting is dangerous on existing code.
I tried those code:
JacksonAnnotationIntrospector ai = new JacksonAnnotationIntrospector();
AnnotatedClass ac = AnnotatedClass.construct(MyClassDTO.class, ai, null);
String[] ignoredList = ai.findPropertiesToIgnore(ac);
for(String one: ignoredList){
System.out.println(one);
}
but ignoredList is always null. I am using Jackson 1.9.2
You could consider using JsonPatch. We use it and it works quite well. Of course it means you apply patches at the JSON level and not in the bean directly so if you need to support more than just JSON, it might be a problem.
Here's an implementation: https://github.com/fge/json-patch
I found the solution on Jackson:
MyBean defaults = objectMapper.readValue(defaultJson, MyBean.class);
ObjectReader updater = objectMapper.readerForUpdating(defaults);
MyBean merged = updater.readValue(overridesJson);
it comes from :
readerForUpdating
merging on Jackson
Just another Java problem (I'm a noob, I know): is it possible to use dynamic property binding in a Custom Control with a dynamic property getter in a Java bean?
I'll explain. I use this feature extensively in my Custom Controls:
<xp:inputTextarea id="DF_TiersM">
<xp:this.value><![CDATA[#{compositeData.dataSource[compositeData.fieldName]}]]></xp:this.value>
This is used in a control where both datasource and the name of the field are passed as parameters. This works, so far so good.
Now, in some cases, the datasource is a managed bean. When the above lines are interpreted, apparently code is generated to get or set the value of ... something. But what exactly?
I get this error: Error getting property 'SomeField' from bean of type com.sjef.AnyRecord which I guess is correct for there is no public getSomeField() in my bean. All properties are defined dynamically in the bean.
So how can I make XPages read the properties? Is there a universal getter (and setter) that allows me to use the name of a property as a parameter instead of the inclusion in a fixed method name? If XPages doesn't find getSomeField(), will it try something else instead, e.g. just get(String name) or so?
As always: I really appreciate your help and answers!
The way the binding works depends on whether or not your Java object implements a supported interface. If it doesn't (if it's just some random Java object), then any properties are treated as "bean-style" names, so that, if you want to call ".getSomeField()", then the binding would be like "#{obj.someField}" (or "#{obj['someField']}", or so forth).
If you want it to fall back to a common method, that's a job for either the DataObject or Map interfaces - Map is larger to implement, but is more standard (and you could inherit from AbstractMap if applicable), while DataObject is basically an XPages-ism but one I'm a big fan of (for reference, document data sources are DataObjects). Be warned, though: if you implement one of those, EL will only bind to the get or getValue method and will ignore normal setters and getters. If you want to use those when present, you'll have to write reflection code to do that (I recommend using Apache BeanUtils).
I have a post describing this in more detail on my blog: https://frostillic.us/f.nsf/posts/expanding-your-use-of-el-%28part-1%29
On Camel 2.10.1, the following worked:
<camel:bean ref="profilingBean" method="addProfilingContext('TEST')"/>
The method in question takes a String parameter
Migrating to 2.10.6 , this does not work anymore, it tries to call TEST as another class. I have tried wrapping with ${} , trying to use exotic combinations of "& quot;" etc...
The only solution I found was to put the value in a header using constant language then call the header using simple. Obviously, this isn't very clean...
Do you have any ideas how to do this?
Cheers
The behavior/bug still exists in Camel 2.16 and also in latest 2.18.2.
For every string constant that is passed to a bean via Spring DSL a java.lang.ClassNotFoundException is thrown.
It gets more visible by setting logger for org.apache.camel.util.ObjectHelper to TRACE.
This camel behavior also has serious negative performance impact because ClassLoader method (java.lang.ClassLoader.loadClass) is synchronized for a given parameter name.
I wrote a little demo to show this: https://github.com/groundhog2k/camel-dsl-bean-bug
Your solution with the header is fine. The bug you talk about should be fixed in 2.10.7, or 2.11.1 etc.
I'm currently using RestEasy(2.3.6) with Jackson(1.9.9) and needing to prefix my JSON arrays with '{} &&' in order to prevent JSON hijacking.
I'm new to Jackson and am having a really hard time understanding where to insert anything like this. I'm not even sure where to insert something like this to make it happen all the time, and I would like to take it one step further and be able to specify to only prefix return values that contain JSON arrays and not regular objects.
I imagine there is a class somewhere I need to subclass and override a method, and then register that class somehow. Has anyone ever done anything like this?
Jukka, the question you linked to led me to a solution. I extended JacksonJsonProvider, and overrode the writeTo() method. There are a few conditions in there and I was able to add jg.writeRaw("{}&&"); before each place it writes the value. Also, since I'm using Spring, I had to annotate my class with #Component in order for it to be found.
Also another gotcha with creating your own JsonProvider subclass is your rest methods must have #Produces('application/json') (you should always be explicit with these anyway) or else the default JsonProvider will be used.