Convert strings to Java objects automatically - java

I want to convert user input that comes as Map<String, String[]> to objects in Java. More specically I want to convert the params of a HttpServletRequest to the fields of an arbitrary domain object.
I'd like to have something like this:
Domain d = Converter.convert(params, new Domain());
If there is more than one element in the string array, which is the value of a map entry, it should be converted to a list or array. Maybe the locale should be considered for date and currency conversion. And a list of conversion errors would be nice.
Is there a library with such a converter?
Would you call it "converter"? I think it is often called "data binding", but that is the wrong term in my opionion, since it is related to binding model values to GUI elements, what is a slightly different thing - isn't it?

If your web framework does not support this functionality have a look at
http://commons.apache.org/beanutils/ ,espeically the beanutils package which has classes with similar purposes (maybe exactly the same) that you want.
You may also consider switching to a more mature framework ;-)

Don't use this plain code as it is only an example. You should add some pretty exception handling and a loop through a map. But generally the idea is like this:
void putValue(String name, String value, Object object) throws Exception {
String setterName = "set"+name.substring(0,1).toUpperCase()+name.substring(1);
Method m = object.getClass().getMethod(setterName, String.class);
if (m!=null) {
m.invoke(object, value);
}
}
This code, given a parameter name 'name' will try to find a method setName(String name) and call it with the given value.

Related

Specify which function was used on string within a map

I have a map of strings that all need to be modified by one of several functions based on some conditions.
My problem is that once I return the map, I need someway to identify which function was used on that specific string. My current idea is to add an identfier at the end of each string so I can check.
Ex. In the case the function "HPV" was used : mystring = mystring + "HPV"
Then on the return end, I can check the end of the string and know which function was used.
Is this an appropriate solution or is there a more efficient way that does not involve checking and modifying every single string?
You should probably use an object that can return both the actual String and the identifier of the function that did the work on it.
If the functions that will do the work are all known at compile-time, they can be identified by an enum, otherwise just another String that holds their ID.
Here is a simple suggestion on how to do that:
enum StringModifier {
HPV, OTHER
}
record ModifiedString(
String string,
StringModifier modifier
) {}
main(String[] args) {
Map<String, String> originalMap = ...
Map<String, ModifiedString> modifications = transform(originalMap, ...)
}
This avoids allocating new Strings and "dirty-ing" them, which can give you trouble later to clean them up as you probably want to make sure you know what the actual result String should look like.

4 Key Value HashMap? Array? Best Approach?

I've got loads of the following to implement.
validateParameter(field_name, field_type, field_validationMessage, visibleBoolean);
Instead of having 50-60 of these in a row, is there some form of nested hashmap/4d array I can use to build it up and loop through them?
Whats the best approach for doing something like that?
Thanks!
EDIT: Was 4 items.
What you could do is create a new Class that holds three values. (The type, the boolean, and name, or the fourth value (you didn't list it)). Then, when creating the HashMap, all you have to do is call the method to get your three values. It may seem like more work, but all you would have to do is create a simple loop to go through all of the values you need. Since I don't know exactly what it is that you're trying to do, all I can do is provide an example of what I'm trying to do. Hope it applies to your problem.
Anyways, creating the Class to hold the three(or four) values you need.
For example,
Class Fields{
String field_name;
Integer field_type;
Boolean validationMessageVisible;
Fields(String name, Integer type, Boolean mv) {
// this.field_name = name;
this.field_type = type;
this.validationMessageVisible = mv;
}
Then put them in a HashMap somewhat like this:
HashMap map = new HashMap<String, Triple>();
map.put(LOCAL STRING FOR NAME OF FIELD, new Field(new Integer(YOUR INTEGER),new Boolean(YOUR BOOLEAN)));
NOTE: This is only going to work as long as these three or four values can all be stored together. For example if you need all of the values to be stored separately for whatever reason it may be, then this won't work. Only if they can be grouped together without it affecting the function of the program, that this will work.
This was a quick brainstorm. Not sure if it will work, but think along these lines and I believe it should work out for you.
You may have to make a few edits, but this should get you in the right direction
P.S. Sorry for it being so wordy, just tried to get as many details out as possible.
The other answer is close but you don't need a key in this case.
Just define a class to contain your three fields. Create a List or array of that class. Loop over the list or array calling the method for each combination.
The approach I'd use is to create a POJO (or some POJOs) to store the values as attributes and validate attribute by attribute.
Since many times you're going to have the same validation per attribute type (e.g. dates and numbers can be validated by range, strings can be validated to ensure they´re not null or empty, etc), you could just iterate on these attributes using reflection (or even better, using annotations).
If you need to validate on the POJO level, you can still reuse these attribute-level validators via composition, while you add more specific validations are you´re going up in the abstraction level (going up means basic attributes -> pojos -> pojos that contain other pojos -> etc).
Passing several basic types as parameters of the same method is not good because the parameters themselves don't tell much and you can easily exchange two parameters of the same type by accident in the method call.

how to remove nested entry in a nested map using dot notation

I have a nested map, something like this:
map.get("employee").get("address").remove("city")
Is there a way to remove the city entry using a key like "employee.address.city"? So I am looking for something like MapUtil.remove(map,"employee.address.city")
Java 8 library Dynamics can do this, it wraps a nested map/collection (amongst other types) structure and allows null-safe reasoning without static typing.
Dynamic.from(map).get("employee").get("address").asMap().remove("city");
We wrap the map to obtain our Dynamic instance, #get now returns other Dynamic instances representing the child, or absence of that child. As such this is null-safe.
For convenience we can also use #dget to split a get into many, and perhaps #maybe to handle the cases where the employee or address don't exist without exception:
Dynamic.from(map).dget("employee.address")
.maybe().asMap()
.ifPresent(address -> address.remove("city"));
See more examples https://github.com/alexheretic/dynamics
Not natively, no, though you could write yourself a method to parse your extended map key using String.split("\\."), like this:
public void nestedRemove(Map map, String keyToRemove)
{
String string = "employee.address.city";
String[] keys = string.split("\\.");
Map subMap = null;
for(int i = 0; i < keys.length -1; i++)
{
subMap = subMap.get(keys[i]);
}
subMap.remove(keys[i]);
}
You could write your own method to do this, although you'd be likely to have to resort to a fair amount of casting. You'd probably just split on dots, then keep calling get (and remembering the result for the next step) until you got to the last part, at which point you'd call remove instead... remembering to check for a null return from get at every step.
I don't know of anything built into a third party library to do this - which isn't to say it's nowhere, of course.

Java: Processor costs of converting from object to other data types

I'm working on a Java project where I handle a list of items, where each item has an id of type int and a value of type String. Then I have another type called ItemCollection which internally has the list and exposes methods to add, remove, get items, etc.
The application is a Financial Transaction Gateway, so we're very focused on performance, since the application will receive many transactions per second. My question is:
The cost of converting an String to another type, like Integer, Char, Date, etc. is the same of converting an Object containing an Integer, Char, Date, etc.?
To clarify, currently the value of the Item is handled in String format. The item has a method called getValue() that returns the item's value in String. But sometimes this value has to be converted to another type, for example int. So what I'm planning to do is change the root type of the value to Object and expose methods like getString(), getInt(), getDate(), getChar(), etc., where the value will be converted from Object to the specific data type. Of course, if the value can't be converted will return null/zero/etc.
In your experience, what would be the best approach?
Is the same to convert from Object to int than String to int?
If you need great performance than I cat suggest that it will be much better to use lower level language like C++. Maybe it is appropriate to use functional language like Erlang. If you want to work with Java then you should avoid taged types and use type system provided by the language. Taged classes are not much faster then actual java classes. Tagged classes are outdated programming style in Java. If you need to convert String to Date, for examle, then this operation will be much slower then cast performed by instanceof operator. Also in Java there is Stop the world GC pause, which can be deadly for real time applications.
Based on the level of detail you've provided, my suggestion is: don't do it!.
Find a way to model your data using Java's type system. Avoid type conversions (e.g. String to Integer), and avoid type casting (e.g. (String)someObject).
If you have a question about a specific operation (such as Integer's toString function), then I suggest consulting the documentation or the source code.
Who is producing these objects? Are they not coming in to you in some format such as JSON or XML that you can actually marshal the data to their real types?
For example, if you receive a JSON message of something like:
date: 2012-12-25
acct: 12345
amount: 123.50
then it's at that point where you should be putting them in to the correct types.
It seems like you want to dispatch messages or perform actions on items based on their type, and you're trying to convert them using the type. I hate not to answer your question, but how do you hope to accomplish this? Do you first try to see if the item is a Date? and then if not, try to see if it is a number? What takes precedence?
If you have an Item that needs processing.. and you can (as I said before, by marshalling the input data in to different types, not Strings) get a StringItem and a DateItem, for example, you can use the Visitor pattern.
This depends on what you mean by 'convert'. That is not a precise term of art in Java.
If you mean 'cast', then the answer is that casting is fast. Your ItemCollection class might have a method like this:
public int getInt(int index) {
Object value = getObject(index);
return (Integer)value;
}
The cast will add a few machine instructions.
If you mean something more like 'parse', then the answer is that parsing is hundreds or thousands of times slower than casting, but still fast compared to I/O. If you were parsing, your code might look like:
public int getInt(int index) {
String value = getString(index);
return Integer.parseInt(value);
}
So, what exactly do you mean by 'convert'?

How do you represent all of the parameters (names & values) contained in a HttpServletRequest object as a single string?

Is there some way to get all of the parameters contained in a HttpServletRequest object into a single String?
request.getQueryString(); // To get into a single string
request.getParameterMap(); // to get into a map of key-value pairs
There are a lot of frameworks that will do this sort of thing for you. It depends a lot on what technologies you are employing. Personally I prefer Spring for the simple reasons that it emcompasses pretty much everything I've needed to do. The only downside is that there's a lot to learn :-)
This at first sight simple problem is complicated by the fact that getParameterMap() returns a Map<java.lang.String,java.lang.String[]>, so attempts to toString() the return value don't give the desired result.
In case you would need the parameters as a JSON string anyways, or don't mind an extra dependency, this is a very simple solution using Jackson:
String asJson = new ObjectMapper().writeValueAsString(request.getParameterMap());
for
parm1=abc&parm=cde&parm3=fgh&parm3=ijk
it produces
{"parm1":["abc"],"parm":["cde"],"parm3":["fgh","ijk"]}

Categories

Resources