Jackson and Bean Validation: Deserialize empty String as null - jackson

I've a RESTeasy application using Jackson and Bean Validation. A POJO might loo like this:
public class Foo {
#Size(min = 2)
private String bar;
}
Bar is validated if the client sends the bar property. And es expected: If the client does not send the property nothing will be validated.
If the client sends an empty String I'll get a constraint violation. This may be correct but it's hard to control what the value of an empty input field really is. For instance in my angular application the field will not be present if the user did not enter anything. Once he enters and deletes something I'll have an empty String.
I thought I could configure Jacksons behavior via DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT but as answered here this is only working for POJOs not for Strings. The only ways I see is not using #Size or writing an own deserializer for Strings. Both doesn't seem to be good solutions. Anyone other ideas?

If you want to accept the empty string, you could use the #Pattern constraint matching also the empty string: #Pattern(regexp = "^$|(.){2}") or #Pattern(regexp = "^$|...
The alternative is to write your own custom constraint.

Related

How can I store Enum value as a String with Hibernate to SQL Server?

So I'm having an Enum-property in an Entity bean:
#Entity
#Table(name = "fileAttachment")
public class FileAttachment
// other properties..
#Enumerated(EnumType.STRING)
FileAttachmentType type;
// getters and setters
However, when I persist the bean, the value in that column is shown as a number such as 0 or 1 or 2.
If I println the value of the enum just before persisting the bean with EntityManager, the value prints out as String, such as INVOICE but in the SQL Server table that row has value 2 for example on the fileAttachmentType-column. What else do I need to configure? I thought the EnumType.STRING would do the trick.
Do you create the table in DB by yourself or rely on Hibernate in it?
If first make sure the column type suits for strings storing.
If second try to use annotation like
#Column(columnDefinition = "enum('VALUE1','VALUE2')")
Ok, in this case things worked out when I added the annotation: #Enumerated(EnumType.STRING)
to the getter of that field and NOT to the actual field.
In another project it works when the annotation is on the field and not anywhere else... so, as far as I comprehed, the answer is the good old "for some reason", but it works now.
If someone would comment the reason for this, I'll update the answer.
EDIT: The reason was found. There was already an annotation on a getter in that Entity class. That's why the annotation on a field didn't work. It happens to be so, that you should either have annotations ONLY on fields OR ONLY on getters. Not annotations on both.

How do you serialize and deserialize an enum?

I am trying to create an enum with commands for motor control in VB.NET. I want to set the command on one computer, serialize it, send it to another computer over a TCP connection, deserialize, and interpret the command. I know how to use the TCP connection, but I'm missing conceptual knowledge about the enum. I am using Protobuf-net to serialize and have the following description of commands.
Public Class RemoteControl
<ProtoContract>
Public Class Command
<ProtoContract>
Enum CommandAction
<ProtoMember(2)>
HOME_MOTOR
<ProtoMember(1)>
MOVE_ABS
End Enum
End Class
End Class
My question is, how do I set the instance of a RemoteControl object to the action I want? I know enums use integers, so to send a MOVE_ABS (which has a tag of 1), I tried
Dim myAction As New RemoteControl
myAction.Command.CommandAction = 1
This returned an error saying "CommandAction is a type and cannot be used as an expression".
Also, once I do manage to figure out how to send this command, how would I interpret it on the other computer? Would the deserialized value of something like RemoteControl.Command.CommandAction be equal to 1 if the command sent was MOVE_ABS?
As usual, I spent days on this then figured it out immediately after making this post.
What I ended up doing was:
SERVER SIDE
Dim realProto As New RemoteControl.Command.CommandAction
realProto = RemoteControl.Command.CommandAction.MOVE_ABS
ProtoBuf.Serializer.SerializeWithLengthPrefix(myStream, realProto, ProtoBuf.PrefixStyle.Fixed32)
CLIENT SIDE
Dim readProto As New RemoteControl.Command.CommandAction
readProto = Protobuf.Serializer.DeserializeWithLengthPrefix(Of RemoteControl.Command.CommandAction)(myStream, Protobuf.PrefixStyle.Fixed32)
This then sets readProto as a RemoteControl.Command.CommandAction whose value is an integer corresponding to the action tag, or I can do readProto.ToString to view the name of the action.

Is it possible to override the vb.net Resource Manager GetString function?

In the auto-generated resource designer file, there are properties for each resource. The property calls "GetString" which returns the string value. I would like to override this getstring function so I can do logic to see if I need to retrieve this value or a different value. I can't figure out how to do this because the designer file is auto-generated.
Public ReadOnly Property General() As String
Get
Return ResourceManager.GetString("General", resourceCulture)
End Get
End Property
For example, in my version of the GetString function, I would check the key passed in ("General") and see if there is a custom value for this key in a database. If the custom value exists, I would use that value. If the custom value does not exist, I would call the base GetString function to get the Resource value. I'd like to use the built in Resource class for this because then in my code I can just use "#Resources.General" and take advantage of the auto-complete functionality that already exists.
Refer to ASP.NET Resourcemanager to read local .resx. It's in C# but you can just convert it over. It isn't 100% of what you are looking for but shows a way of overriding in which you may be able to adjust to work with your needs.

How can I encode URL parameters?

I used this method in class library and calling the method from controller. But the value i passed is not encoding. I cant trace the reason behind it.
Class Library
using System.Web;
public static class CommonLogic
{
public static string UrlEncode(string value)
{
return HttpUtility.UrlEncode(value);
}
}
Controller
var test = CommonLogic.UrlEncode("2")
test value is "2" and it not encoded.
Update:
I just realized the reason from comments below. What i really need is not encoding but encryption and decryption. I don't want the Url parameters to be exposed as plain text, instead i want that to be encrypted value and later in controller i will decrypt it again before processing that value. Any Ideas on this?
"2" doesn't need to be UrlEncoded. It's not a reserved symbol in Urls. Try testing a string such as "<".
The purpose of the UrlEncode method is to convert a string to a format that can be used in an URL. "2" is already can be used in an URL so this is a null-conversion it will result in the same value of "2".
Section 2 of RFC 3986 outlines what characters have to be encoded to become part of an URL.
Character "2" is part of the "unreserved" set as defined in RFC3986 https://www.rfc-editor.org/rfc/rfc3986#section-2.3
The "unreserved" do not need to be percent-encoded.
Regarding your comment about exposing it in the URL: encoding is not encryption. If you don't want to expose the integer user id in the URL you may need to have another unique identifier for the user that is OK to expose. For example, a random string that is unique in the user table (similar to how say youtube.com identifies videos) or a GUID.
Example of how to do simple symmetric encryption in C# using RijndaelManaged:
Simple insecure two-way data "obfuscation"?
Make sure you keep the encryption key secret.

How to transfer objects through the header in WCF

I'm trying to transfer some user information in the header of the message through message inspectors.
I have created a behavior which adds the inspector to the service (both client and server).
But when I try to communicate with the service I get the following error:
XmlException:
Name cannot begin with the '<' character, hexadecimal value 0x3C.
I have also get exception telling me that DataContracts where unexpected.
Type
'System.DelegateSerializationHolder+DelegateEntry'
with data contract name
'DelegateSerializationHolder.DelegateEntry:http://schemas.datacontract.org/2004/07/System'
is not expected. Consider using a
DataContractResolver or add any types
not known statically to the list of
known types - for example, by using
the KnownTypeAttribute attribute or by
adding them to the list of known types
passed to DataContractSerializer.
The thing is that my object contains other objects which are marked as DataContract and I'm not interested adding the KnownType attribute for those types.
Another problem might be that my object to serialize is very restricted in form of internal class and internal properties etc.
Can anyone guide me in the right direction. What I'm I doing wrong?
Some code:
public virtual object BeforeSendRequest(ref Message request, IClientChannel channel)
{
var header = MessageHeader.CreateHeader("<name>", "<namespace>", object);
request.Headers.Add(header);
return Guid.NewGuid();
}
Don't put the angle brackets into the actual strings. Remember, the serialization format may not even be text based, all you're doing is specifying the name of the element and the namespace. So your code should look more like this:
var header = MessageHeader.CreateHeader("name", "urn:myNamespace", object);
request.Headers.Add(header);
To close this question, I never solved the exception. Instead I implementated ISerializable which worked great for me.