Make DWR pass a null value, rather than converting to false - java

I am working with DWR inside the context of a Spring 3.x Web MVC application, where my dwr-beans.xml file declares a bean like this:
<dwr:configuration>
<dwr:convert type="bean" class="com.mypackage.Customer"/>
</dwr:configuration>
The com.mypackage.Customer class has one attribute of type Boolean (the object wrapper, not a boolean primitive).
This attribute has three different states that are meaningful to the business logic. It can be true or false, obviously... but a null value is meaningful for signaling that a selection hasn't be made yet.
Unfortunately, when a Java object is passed across to JavaScript through a DWR AJAX call... a null value shows up as false on the JavaScript object. I'm losing that third meaningful "neither of the above" state.
Google searching has not been very fruitful, unfortunately. Does anyone know if there is a way to make DWR properly pass across a Java null as a JavaScript null (or undefined)? Or might I be doing something wrong in the first place?

This is a piece of code, that can be found in PrimitiveConverter of DWR source code
if (paramType == Boolean.class)
{
if (trimValue.length() == 0)
{
return null;
}
return (T) Boolean.valueOf(trimValue);
}
Whenever you pass null, asd or anything else you've get null as result. You can try to extend DWR with your own implementation, it could be rather tricky. Or use String instead in your bean with 3 state ("true", "false", "null").

It turns out that DWR does handle null values correctly by default. My issue was further up the stack... not between the browser and the app server, but rather between the app server and the remote web service that it was calling for the data.

Related

xp:checkbox breaks programme

On an XPage I have placed a checkbox group:
<xp:checkBoxGroup
value="#{employeeBean.employee.concern}"
disabled="#{employeeBean.employee.editable eq false}">
<xp:selectItem itemLabel="yes"></xp:selectItem>
<xp:selectItem itemLabel="no"></xp:selectItem>
<xp:selectItem itemLabel="maybe"></xp:selectItem>
</xp:checkBoxGroup>
I have binded the value of the control to field in my Proposal class via a managed bean.
The field concern is of type string and has its out of the box getters and setters.
The problem is whenever I include the data-binding and change values the complete XPage SSJS fails. I do not get an error in the console (server, web client).
Does this have something to do with the type of value the checkbox returns or should I change the type of field in my class?
One thing that springs to mind is the employee object. If this is not set (i.e. there is an instance of the object) then it will fail with a null pointer exception.
In your case it is quite valid the concern field is of type String - obviously you will need a getConcern() and setConcern(String value) method.
Now the real problem is that you cannot see what the server thinks is wrong!
The best way to get to that is to look at the stack traces in the logs. And by far the easiest way to do that is to install the "XPages Log File Reader" application from OpenNTF.org
But my guess is that you haven't created an employee object prior to calling the getEmployee() method to return it ;-)
/John

Add String to Camel Exchange Header from Route

I'm working on adding some functionality to an existing Camel route for a colleague. The route utilizes a call to an adapter that will do everything I need done already, with one exception, the method being used by Camel has the following signature.
public void logCustomEvent(MyForm form,
#Header("myHeader") String myHeader,
#Header("myBoolean") boolean myBoolean) { ... }
I want to handle a scenario in this route, where nothing needs to be done. So we just jump straight into the logCustomerEvent adapter method, but that also means that the myHeader String value will not have been populated in the header yet.
I found the .setHeader(String, Expression), so I'm curious if there is an easy way using MVEL or Simple or anything else to create an Expression in the route that will essentially insert a null String into my header with the name I provide it.
Anyone know of a way to do this?

Passing JSON object from Java to Javascript through JSP tag

I have a service A in the java server side of my application that returns a JSON object, and I need to consume that object in javascript side to call another service B.
The platform is a bit complex, having two applications based on Stripes and Spring packed under the same war and sharing a lot of code.
The solution I have so far is creating a JSP tag that access the JSON object and puts it in a variable:
#Override
public int doStartTag() throws JspException {
pageContext.setAttribute(var, SERVICE_A_JSONOBJECT, scope);
return SKIP_BODY;
}
This works well, but the jstl variable is converted to String, so in the javascript call I have to use JSON.parse.
Is there any way to improve this by passing the JSON object to javascript without being converted and then parsed?
NOTE: Since they are two apps, I would like to avoid using the session, because then I would need to duplicate the code

Play 2.0/Java - Is there a way to get the validation done post request data binding?

In play 2.0 you can get the request binding with validation done (via annotations) by :
ABCForm abcForm=(ABCForm)form(ABCForm.class).bindFromRequest().get();
The problem I have is , I want to get the validation done after trimming the form values.
So is there a way to either defer or call the validation stuff post binding in play 2.0 ?
Binding and validation are combined. So validation after the binding is not possible, as far as I know. However you can create a validate() method, in which you trim your values before validating them. For example:
public class User {
public String name;
public String validate() {
name.trim
if(name == "") {
return "Name is required";
}
return null;
}
}
The validate() method will be invoked when you bind a form. So you can make sure your data is valid, but errors won't be automatically added to the Form.Field objects. So it is certainly a nice solution.
There are also pretty much discussions about Form validation in Play's Google Group, so if you want to know more about the binding/validation problems I recommend reading them: https://groups.google.com/forum/#!searchin/play-framework/%5B2.0%5D$20validation.
If you need to modify your values before validation. You can create a setter for your field and do your trims there.

HttpServletRequest.getRemoteUser() vs HttpServletRequest.getUserPrincipal().getName()

These two seem to be doing the same things. Can anyone explain the main difference between the two? When would you use one vs the other?
HttpServletRequest.getRemoteUser()
HttpServletRequest.getUserPrincipal().getName()
A Principal represents someone who could potentially authenticate with your application. The Principal's name depends on the authentication method used:
a username such as "fred" (in the case of HTTP Basic authentication)
a Distinguished Name such as "CN=bob,O=myorg" (in the case of X.509 client certificates - in which case a X500Principal may be returned)
getRemoteUser() returns "the login of the user" which, in the case of HTTP Basic authentication, will also be the username; it doesn't map cleanly in the X.509 client certificate case though, since the user doesn't enter a "login" as such - in the example above, we could use the Distinguished Name or simply the CN, "bob".
The Javadocs state that "whether the user name is sent with each subsequent request depends on the browser and type of authentication", suggesting that getRemoteUser() was originally meant to provide data only for requests in which a username was entered. This, however, would result in it returning null for the majority of requests when cookie-based auth is in use - not too helpful!
In reality, getRemoteUser() often just calls getUserPrincipal().getName(); verified in Tomcat 6 and Jetty 6/7.
The getUserPrincipal() method returns an object of some class derived from the Principal interface, which is an abstraction of the entity that is the "user" responsible for the request. From it you get an actual object that, depending on the implementing class, you can use to get all sorts of information about that user/identity. One of those properties is the string-representation of the name of the user/identity, which you obtain by calling getName().
getRemoteUser() is really just a shortcut to getting that string-representation. You don't have access to any other methods implemented by the implementing class, not do you have access to the object itself, just the string-representation of the name.
For most use-cases that I am familiar with, that string-representation is what you want; I believe this is why getRemoteUser() exists - it's a common case so there's an easy/quick way to get access to it without actually getting a reference to an implementing class object.
A bit related issue:
People converting older IBM Portlet API code to JSR168 one had to change PortletRequest to HttpServletRequest in some method parameters, but then from WPS6.1 and up they can't cast that to PortletRequest (it doesn't implement the respective interface anymore as it seems) and if they call "getRemoteUser" directly on the HttpServletRequest they get back null (some say a workarround is to enable application security option in WAS [WebSphere Application Server], others say more security-related markup is needed in web.xml)
A workarround seems to be to use PUMA, but of course that is IBM WebSphere specific. Probably at other Portlet Containers there are other vendor-specific workarrounds if one finds that getRemoteUser always returns null (judging from other replies then getUserPrincipal().getName() also returns null if getRemoteUser is implemented as just a shortcut to that one).
BTW, the PUMA code I mention above is here, since it's a bit hard to find what works in WPS6.1+:
import com.ibm.portal.portlet.service.PortletServiceHome;
import com.ibm.portal.um.*;
import com.ibm.portal.um.exceptions.PumaException;
import com.ibm.portal.puma.User;
//...
public String getCurrentUser(){
try {
Context ctx = new InitialContext();
Name myjndiname = new CompositeName(PumaHome.JNDI_NAME);
PumaHome myHome = (PumaHome) ctx.lookup(myjndiname);
if (myHome!=null) {
PumaProfile pumaProfile = myHome.getProfile();
com.ibm.portal.um.User user = (com.ibm.portal.um.User)pumaProfile.getCurrentUser();
List attributes = new ArrayList();
attributes.add("uid");
Map userAttributes = pumaProfile.getAttributes(user,attributes);
return (String) userAttributes.get("uid");
}
}

Categories

Resources