best practice for Spring validation of AJAX JSON data - spring-mvc

I'm using AJAX to send JSON data from web page to back end, and need some validation strategies. I noticed that there're several ways to validate form parameters like SimpleFormController with ValidationUtils class and similar command object binding methods. But is there any suggestion to validate JSON data?
Thanks for even

Avoid the whole controller hierarchy. It is obsolete. Use the new restful style in spring mvc (available in 2.5, improved in 3.0).
There, you can define:
#RequestMapping("/url/foo")
public String handleFooInput(#Valid YourObject obj) { .. }
This will bind the input JSON to the object you specify, and will validate it (if it is annotated with javax.validation annotations). Three preconditions to that:
have jackson and jackson-mapper on your classpath, so that an object is created based on the JSON input
have a javax.validation provider (hibernate-validator for example) on the classpath
put <mvc:annotation-driven /> in your dispatcher-servlet.xml

Related

How can I transform posted XML to a POCO in an MVC action?

I have the following method signature for an action on an MVC controller:
public ActionResult DoSomething(int id, string anotherParameter, IEnumerable<StronglyTypedThing> data)
{
}
This method is called by an AJAX Request (in this instance I'm using ExtJS, but that should have little/no bearing on this I imagine!) which passes up, for example:
id: 1,
anotherParameter: 'cake',
data: '<stronglyTypedThings>
<stronglyTypedThing>
<id>1</id>
<anotherProperty>Smith, John></anotherProperty>
</stronglyTypedThing>
<stronglyTypedThing>
<id>2</id>
<anotherProperty>Doe, Jane></anotherProperty>
</stronglyTypedThing>
</stronglyTypedThings>'
Currently the method signature I've shown above is not what I have, instead the final parameter is defined as string data and I have what is effectively boilerplate code which transforms the XML string into an IEnumerable<StronglyTypedThing>.
Is there a way to have (either by virtue of something baked into MVC, or by extending it) MVC deal with the grunt-work for me so I don't have the boilerplate code present in my action method?
You can create a custom model binder.
This link will have an example of custom xml binder: http://lostechies.com/jimmybogard/2011/06/24/model-binding-xml-in-asp-net-mvc-3/
You might want to look into a custom ValueProviderFactory.
A custom XmlValueProviderFactory will parse the incoming xml string and construct an intermediate dictionary. (which MVC uses to model bind)
Based on your need, you could parse the whole XML/or a part of it, to construct the dictionary equivalent of your Model object. Once there, MVC will take care of creating the Model for you using Model Binding. Also, value providers have the additional benefit of input validation which custom model binders don't have.
Please see following help links to see a JSON & XML Value Provider factory.
i think the JSON Value provider is now in built, but not the XML one. not sure.
http://haacked.com/archive/2010/04/15/sending-json-to-an-asp-net-mvc-action-method-argument.aspx/
http://www.nogginbox.co.uk/Media/files/XmlValueProviderFactory.txt

How do I start supporting a custom handler method response type in Spring MVC?

I oftentimes want to return an Object as response body which is not supported by spring. So Instead I do:
public HttpEntity<?> doStuff() {
MyClass myObject = ... ;
return SomeHelper.toHttpEntity(myObject);
}
While this works, it is uncool, because it makes my code less testable and adds the same call over and over to various handler methods. Thus I wonder if I could add support for an additional type in spring.
I couldn't find anything on Google, but reading through the source code I found the interface HandlerMethodReturnValueHandler whose implementors do the conversion. So I'd implement that interface for my custom type, but how do I register it (using XML) in spring?
I don't think that you need your own HandlerMethodReturnValueHandler, but just in case:
<mvc:annotation-driven>
<mvc:return-value-handlers>
<bean class="my.own.Handler" />
</mvc:return-value-handlers>
If mvc is your default namepsace you omit the qualifier, of course.

Formatting uri template string values in ASP.NET WebApi

I have an ASP.NET WebApi application that has some controller methods that expect certain strings to be passed in as method parameters (declared as part of the route template).
On all the methods, the strings passed in are base64-encoded -- which means each controller method must base64-decode them before doing anything with them. While I can obviously have each method do this easily enough, I was wondering if there was a way to perform the decoding before the string actually gets passed to the controller method. I presume this is something along the lines of an action filter or custom formatter, but I'm not familiar enough with asp.net web api to know where to start on that?
Summary:
I've got route templates like : {controller}/{encodedString}/whatever
where {encodedString} is always a base64-encoded string.
and controllers with methods like
GetWhatever(string encodedString)
{
Base64Decode(encodedString);
// do other stuff...
}
I would like to use some part of the asp.net webapi pipeline to decode {encodedString} before the controller method is actually called. What path should I start down in order to do this?
You can create a custom model binder and attach it to the parameters using the ModelBinderAttribute. In the model binder you then do the base64 decoding.
For a reference on parameter binding in Web API check:
How WebAPI does Parameter Binding

About JAXB Databinding in JAX-WS

I have developed webservices using CXF framework. We are exposing all our Database operation(Service Layer) methods as a web service methods. We are using Hibernate for persistence.
For example consider I have one Java POJO class(for hibernate mapping)
named CountryEntity.java with the following
properties(ID,Name,ModifiedDate).
Inside my service layer i have two methods called
#WebMethod
public CountryEntity createCountryEntity(CountryEntity countryEntity);
#WebMethod
public CountryEntity getCountryEntityById(long id);
Based on JAX-WS documentation i understand that it is using JAXB to do
the databinding. When user calling my webservice for creating the new
Country record i dont want the user to send the Id value and Modified
Date value . So what i done is i annotated the propeties(id,modified
date) inside the CountryEntity.java with #XmlTransistent annotation.
So that operation is working fine.
But when i call getCountryEntityById web service method its returning
CountryEntity object but that object dont have the values for ID and
Modified Date property. I understand because of XMLTransistent
annotation the values not getting Marshalling.
Can i change my method createCountryEntity taking parameters like
(String countryName) , so that i no need to include XMLTransistent
annotation in my entity classes.? or Anyother solution for this?
Please help me . Thanks in advance
Since no answer i go with parameters instead of sending an object as parameter. Thank you.

How to implement custom JSON serialization from ASP.NET web service?

What options are there for serialization when returning instances of custom classes from a WebService?
We have some classes with a number of child collection class properties as well as other properties that may or may not be set depending on usage. These objects are returned from an ASP.NET .asmx WebService decorated with the ScriptService attribute, so are serialized via JSON serialization when returned by the various WebMethods.
The problem is that the out of the box serialization returns all public properties, regardless of whether or not they are used, as well as returning class name and other information in a more verbose manner than would be desired if you wanted to limit the amount of traffic.
Currently, for the classes being returned we have added custom javascript converters that handle the JSON serializtion, and added them to the web.config as below:
<system.web.extensions>
<scripting>
<webServices>
<jsonSerialization>
<converters>
<add name="CustomClassConverter" type="Namespace.CustomClassConverter" />
</converters>
</jsonSerialization>
</webServices>
</scripting>
</system.web.extensions>
But this requires a custom converter for each class. Is there any other way to change the out of the box JSON serialization, either through extending the service, creating a custom serializer or the like?
Follow Up
#marxidad:
We are using the DataContractJsonSerializer class in other applications, however I have been unable to figure out how to apply it to these services. Here's an example of how the services are set-up:
[ScriptService]
public class MyService : System.Web.Services.WebService
{
[WebMethod]
public CustomClass GetCustomClassMethod
{
return new customClass();
}
}
The WebMethods are called by javascript and return data serialized in JSON. The only method we have been able to change the serialization is to use the javascript converters as referenced above?
Is there a way to tell the WebService to use a custom DataContractJsonSerializer? Whether it be by web.config configuration, decorating the service with attributes, etc.?
Update
Well, we couldn't find any way to switch the out of the box JavaScriptSerializer except for creating individual JavaScriptConverters as above.
What we did on that end to prevent having to create a separate converter was create a generic JavaScriptConverter. We added an empty interface to the classes we wanted handled and the SupportedTypes which is called on web-service start-up uses reflection to find any types that implement the interface kind of like this:
public override IEnumerable<Type> SupportedTypes
{
get
{
foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
{
AssemblyBuilder dynamicAssemblyCheck = assembly as AssemblyBuilder;
if (dynamicAssemblyCheck == null)
{
foreach (Type type in assembly.GetExportedTypes())
{
if (typeof(ICustomClass).IsAssignableFrom(type))
{
yield return type;
}
}
}
}
}
}
The actual implementation is a bit different so that the type are cached, and we will likely refactor it to use custom attributes rather than an empty interface.
However with this, we ran into a slightly different problem when dealing with custom collections. These typically just extend a generic list, but the custom classes are used instead of the List<> itself because there is generally custom logic, sorting etc. in the collection classes.
The problem is that the Serialize method for a JavaScriptConverter returns a dictionary which is serialized into JSON as name value pairs with the associated type, whereas a list is returned as an array. So the collection classes could not be easily serialized using the converter. The solution for this was to just not include those types in the converter's SupportedTypes and they serialize perfectly as lists.
So, serialization works, but when you try to pass these objects the other way as a parameter for a web service call, the deserialization breaks, because they can't be the input is treated as a list of string/object dictionaries, which can't be converted to a list of whatever custom class the collection contains. The only way we could find to deal with this is to create a generic class that is a list of string/object dictionaries which then converts the list to the appropriate custom collection class, and then changing any web service parameters to use the generic class instead.
I'm sure there are tons of issues and violations of "best practices" here, but it gets the job done for us without creating a ton of custom converter classes.
If you don't use code-generated classes, you can decorate your properties with the ScriptIgnoreAttribute to tell the serializer to ignore certain properties. Xml serialization has a similar attribute.
Of course, you cannot use this approach if you want to return some properties of a class on one service method call and different properties of the same class on a different service method call. If you want to do that, return an anonymous type in the service method.
[WebMethod]
[ScriptMethod]
public object GimmieData()
{
var dalEntity = dal.GimmieEntity(); //However yours works...
return new
{
id = dalEntity.Id,
description = dalEntity.Desc
};
}
The serializer could care less about the type of the object you send to it, since it just turns it into text anyway.
I also believe that you could implement ISerializable on your data entity (as a partial class if you have code-gen'd data entities) to gain fine-grained control over the serialization process, but I haven't tried it.
I know this thread has been quiet for a while, but I thought I'd offer that if you override the SupportedTypes property of JavaScriptConverter in you custom converter, you can add the types that should use the converter. This could go into a config file if necessary. That way you wouldn't need a custom converter for each class.
I tried to create a generic converter but couldn't figure out how to identify it in the web.config. Would love to find out if anyone else has managed it.
I got the idea when trying to solve the above issue and stumbled on Nick Berardi's "Creating a more accurate JSON .NET Serializer" (google it).
Worked for me:)
Thanks to all.
If you're using .NET 3.x (or can), a WCF service is going to be your best bet.
You can selectively control which properties are serialized to the client with the [DataMember] attribute. WCF also allows more fine-grained control over the JSON serialization and deserialization, if you desire it.
This is a good example to get started: http://blogs.msdn.com/kaevans/archive/2007/09/04/using-wcf-json-linq-and-ajax-passing-complex-types-to-wcf-services-with-json-encoding.aspx
You can use the System.Runtime.Serialization.Json.DataContractJsonSerializer class in the System.ServiceModel.Web.dll assembly.
Don't quote me on this working for certain, but I believe this is what you are looking for.
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public XmlDocument GetXmlDocument()
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(_xmlString);
return xmlDoc;
}

Resources