Version 2



    As part of the Gamefication Extension development, we needed a way to replace the status level data in the Browse People page:




    When you first visit the browse people page, the page is rendered by a normal soy action so we had no problem modifying the response using a regular struts interceptor (see How To: Add Struts Interceptors at Runtime).


    However, if you want to toggle the display between "card" and "list" view:


    Screen Shot 2012-04-11 at 10.04.23 AM.png


    The data is retrieved from a web service and then re-rendered on the page.



    We wanted a way to modify the response from the web service without resorting to an overlay or having to modify the internals of any of the classes responsible for generating the response.




    CXF Interceptors to the rescue.  By adding a CXF interceptor to the web service in question, we could modify the response before it was sent to the user.  Here is how we did it


    Create an Interceptor


    public class UserServiceInterceptor extends AbstractPhaseInterceptor<Message> {
        public UserServiceInterceptor() {
        public void handleMessage(Message message) throws Fault {
            if (isInvokingGetUsers(message) && viewingAllPeople(message)) {


    Add the Interceptor to the web service definition.


    For this, we have to resort to using a spring BeanFactoryPostProcessor (See Modifying Prototype Spring Beans) to inject the interceptor in to the outInterceptors property of the web service definition we want (in our case, the internalRestServer defined in spring-wsInternalContext.xml):


    This is necessary because Spring doesn't give us a chance to modify the <jaxrs:server/> definition for internalRestServer in any other meaningful way.


    public class UserServiceInterceptorConfigurator implements BeanFactoryPostProcessor {
        private UserServiceInterceptor interceptor;
        public void setInterceptor(UserServiceInterceptor interceptor) {
            this.interceptor = interceptor;
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
            BeanDefinition definition = beanFactory.getBeanDefinition("internalRestServer");
            MutablePropertyValues properties = definition.getPropertyValues();
            PropertyValue outInterceptorsProperty = properties.getPropertyValue("outInterceptors");
            if (outInterceptorsProperty == null) {
                properties.addPropertyValue("outInterceptors", Arrays.asList(interceptor));
            } else {
                List<Object> propertyValue = (List<Object>) outInterceptorsProperty.getValue();


    This is then defined in your spring config:


    <bean class="xxx.UserServiceInterceptorConfigurator">
        <property name="interceptor">







    (someone reset the points on my the PS instance, grrr )




    You'll notice that the Interceptor has two methods, isInvokingGetUsers and viewingAllPeople.  These are necessary to ensure that the interceptor runs on the right service and method.  You'll notice that we added the interceptor to the internalRestServer service which is actually a number of different services all under the /__services/v2/rest base path.  Below is the code used to ensure that we're running in the right spot:


    protected boolean isInvokingGetUsers(Message message) {
        return "UserServiceImpl#getUsers".equals(message.getExchange().get(""));
    protected boolean viewingAllPeople(Message message) {
        Message inMessage = message.getExchange().getInMessage();
        // The list of arguments that the method was invoked with.
        List<?> list = inMessage.getContent(List.class);
        if (list != null && list.size() > 3) {
            return "people".equals(list.get(3));
        return false;


    The decorateResponse method pulls the response object from the CXF message and modifies it accordingly:


    protected void decorateResponse(Message message) {
        ItemsViewBean<UserItemBean> view = getResponseObjectFrom(message);
        // Do something with view
    protected ItemsViewBean<UserItemBean> getResponseObjectFrom(Message message) {
        List<?> list = message.getContent(List.class);
        if (list != null && list.size() == 1) {
            Object o = list.get(0);
            if (o instanceof ItemsViewBean) {
                return (ItemsViewBean<UserItemBean>) o;
        return null;


    Thanks to Kevin Conaway for the great write-up!