Tuesday, October 25, 2011

Using Spring WF's FlowExecutionExceptionHandler

This powerful feature allows webflow states to intercept exceptions and redirect accordingly.

To use the handler simple use the global transitions in flow:
(I choose a global or parent one so my concerned flows can inherit it)

<global-transitions>
<transition
on-exception="org.springframework.ws.soap.client.SoapFaultClientException"
to="soapFaultClientException" />
</global-transitions>

This will then allow the inherited by other flows or you can dump it into the flow you need

<flow parent="global"...

Within the (child) flow or any flow that the global transition apply to, handle the transition
<subflow-state id="soapFaultClientException" subflow="exception/soap">
<transition on="end" to="search" />
</subflow-state>

The controller or view will have access to the exception details via the root cause object
<on-start>
<evaluate expression="controller.prepareErrorMessage(rootCauseException)" />
</on-start>

which is of type
public void prepareErrorMessage(SoapFaultClientException ex){
...
}

Finally the JSF can access the error or exception within the controller

Monday, October 24, 2011

Google Map API Callback + CORS

Combining CORS and Google Maps API

function createCORSRequest(method, url) {
var xhr = null;
if (typeof XDomainRequest != "undefined") {
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
var xhr = new XMLHttpRequest();
xhr.open(method, url, true);
xhr.setRequestHeader('accept', "application/json");
}
return xhr;
}

function listenMarker(infowindow, model, map) {

google.maps.event.addListener(model, 'click',
function() {
var request = createCORSRequest("get", host + "url"
+ model.ID);
if (request) {
request.onload = function() {
var response = $j.parseJSON(request.responseText);
processLocationClickResponse(infowindow, model, map,
response);
};
request.send();
}
});
}

function processLocationClickResponse(infowindow, model, map, response) {
var contentString = '<div id="content"><h1 id="firstHeading" class="firstHeading">'
+ response.w
+ '</h1><div id="bodyContent" style="align : left;"><img src="nodeIcons[response.x]" />'
+ '<p>Label: '
+ response.y
+ '</p><p>Label:'
+ response.z + '</p>' + '</div>';
infowindow.setContent(contentString);
infowindow.open(map, marker);
}

Thursday, October 20, 2011

Spring MVC @ResponseBody and manage headers

To use @ResponseBody and manipulate the response header us the following:

@RequestMapping(value = "/url", method = RequestMethod.GET, headers = { "Accept=application/json" })
public @ResponseBody
List handle(HttpServletResponse response,
@RequestHeader("headerID") String headerString) {
response.setHeader("responseHeaderProperty", String);
return service.doSomething();
}

Wednesday, October 19, 2011

Spring Webflow MVC JSF (Richfaces 4) Servlet

This allows the seperation of servlet config to the servlet decleration:

<servlet>
<servlet-name>Spring MVC Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

Configuration:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

<!-- DispatcherServlet Context: defines this servlet's request-processing
infrastructure -->

<!-- Enables the Spring MVC @Controller programming model -->
<mvc:annotation-driven />

<!-- Maps request paths to flows in the flowRegistry -->
<bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
<property name="order" value="-2" />
<property name="flowRegistry" ref="flowRegistry" />
</bean>

<!-- Resolves views selected for rendering by @Controllers to .xhtml resources
in the /WEB-INF/views directory -->
<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
<property name="viewClass" value="org.springframework.faces.mvc.JsfView" />
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".xhtml" />
</bean>

<!-- Dispatches requests mapped to flows to FlowHandler implementations -->
<bean class="org.springframework.faces.webflow.JsfFlowHandlerAdapter">
<property name="flowExecutor" ref="flowExecutor" />
</bean>

<bean name="jsfResourceHandler"
class="org.springframework.faces.webflow.JsfResourceRequestHandler" />

<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="order" value="0" />
<property name="mappings">
<value>/javax.faces.resource/**=jsfResourceHandler
/rfRes/**=jsfResourceHandler
</value>
</property>
</bean>

<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter" />

<bean
class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />

<flow-executor id="flowExecutor">
<flow-execution-listeners>
<listener ref="facesContextListener" />
</flow-execution-listeners>
</flow-executor>

<!-- The registry of executable flow definitions -->
<flow-registry id="flowRegistry" flow-builder-services="facesFlowBuilderServices"
base-path="/WEB-INF/flows">
<flow-location-pattern value="/**/flow.xml" />
</flow-registry>

<faces:flow-builder-services id="facesFlowBuilderServices" development="true" />

<bean id="facesContextListener"
class="org.springframework.faces.webflow.FlowFacesContextLifecycleListener" />

</beans>

Spring REST Controller example

@Controller
@RequestMapping("/urlpattern")
public class ClassName {

@RequestMapping(method=RequestMethod.GET, headers={"Accept=application/json"})
public @ResponseBody responseClass method(Model model){

}

JSON in Spring 3.0

In the web.xml, declare a new servlet

<servlet>
<servlet-name>rest</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>

in the rest-servlet, configure the marshaller for the json stuff:

<bean
class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
<list>
<ref bean="jsonConverter" />
<!-- ref bean="marshallingConverter" />
<ref bean="atomConverter" / -->
</list>
</property>
</bean>

<bean id="jsonConverter"
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
<property name="supportedMediaTypes" value="application/json" />
</bean>