Java Ninja Chronicles By Norris Shelton

Things I learned in the pursuit of code

I had previously made a blog entry to retrieve the Springframework security principal via @AuthenticationPrincipal in a controller method.
Getting the Spring Security Principal in a Spring MVC Controller method.

That is useful if you need the username or the password. What do you do if you need more?

I made a @PersonPrincipal annotation to do more than @AuthenticationPrincipal

package com.cdi.igs.hub.spring;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Annotation that binds a method parameter or method return value to the
 * {@link com.cdi.igs.dao.person.Person}. This is necessary to signal that the
 * argument should be resolved to the current user rather than a user that might
 * be edited on a form.
 *
 * @author norris.shelton
 * @since 3.2
 */
@Target({ ElementType.PARAMETER, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PersonPrincipal {
}

I then made a PersonArgumentResolver that can handle the processing required for the @PersonPrincipal annotation. The resolver first looks in the session to see if the Person object is there. If the Person object still isn’t found, the Authentication object will be retrieved from the security context. The SecurityUtil we be used to retrieve the person by username if necessary.

package com.cdi.igs.hub.spring;

import com.cdi.igs.dao.person.Person;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.lang.annotation.Annotation;


/**
 * Allows resolving the {@link com.cdi.igs.dao.person.Person} using the
 * {@link com.cdi.igs.hub.spring.PersonPrincipal} annotation. For example, the following
 * {@link org.springframework.stereotype.Controller}:
 *
 * <pre>
 * @Controller
 * public class MyController {
 *     @RequestMapping("/user/current/show")
 *     public String show(@PersonPrincipal Person person) {
 *         // do something with Person
 *         return "view";
 *     }
 * </pre>
 *
 * <p>
 * Will resolve the Person argument using
 * {@link com.cdi.igs.dao.person.Person} from the {@link javax.servlet.http.HttpSession} if the person is an
 * attribute, else will use the {@link org.springframework.security.core.context.SecurityContextHolder} to get the
 * information to retrieve the person from the {@link com.cdi.igs.dao.person.PersonRepository}.
 * If the {@link org.springframework.security.core.Authentication} or {@link org.springframework.security.core.Authentication#getPrincipal()} is
 * null, it will return null.
 * </p>
 *
 * @author norris.shelton
 * @since 3.2
 */
@Component
public final class PersonArgumentResolver implements HandlerMethodArgumentResolver {

    @Autowired
    private SecurityUtil SecurityUtil;

    /** (non-Javadoc)
     * @see org.springframework.web.method.support.HandlerMethodArgumentResolver#supportsParameter(org.springframework.core.MethodParameter)
     */
    public boolean supportsParameter(MethodParameter parameter) {
        return findMethodAnnotation(PersonPrincipal.class, parameter) != null;
    }

    /** (non-Javadoc)
     * @see org.springframework.web.method.support.HandlerMethodArgumentResolver#resolveArgument(org.springframework.core.MethodParameter, org.springframework.web.method.support.ModelAndViewContainer, org.springframework.web.context.request.NativeWebRequest, org.springframework.web.bind.support.WebDataBinderFactory)
     */
    public Object resolveArgument(MethodParameter parameter,
                                  ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest,
                                  WebDataBinderFactory binderFactory)
    throws Exception {
        Person person = null;

        // get "person" out of the session
        HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();
        HttpSession session = request.getSession(false);
        if (session != null) {
            person = (Person) session.getAttribute("person");

        }

        // if not found in the session, get by using the authenticated principal
        if (person == null) {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            person = SecurityUtil.getPersonByAuthentication(authentication);

            // if found, store in the session for next time
            if (person != null &amp;&amp; session != null) {
                session.setAttribute("person", person);
            }
        }
        return person;
    }

    /**
     * Obtains the specified {@link java.lang.annotation.Annotation} on the specified {@link org.springframework.core.MethodParameter}.
     *
     * @param annotationClass the class of the {@link java.lang.annotation.Annotation} to find on the {@link org.springframework.core.MethodParameter}
     * @param parameter the {@link org.springframework.core.MethodParameter} to search for an {@link java.lang.annotation.Annotation}
     * @return the {@link java.lang.annotation.Annotation} that was found or null.
     */
    private <T extends Annotation> T findMethodAnnotation(Class<T> annotationClass, MethodParameter parameter) {
        T annotation = parameter.getParameterAnnotation(annotationClass);
        if(annotation != null) {
            return annotation;
        }
        Annotation[] annotationsToSearch = parameter.getParameterAnnotations();
        for(Annotation toSearch : annotationsToSearch) {
            annotation = AnnotationUtils.findAnnotation(toSearch.annotationType(), annotationClass);
            if(annotation != null) {
                return annotation;
            }
        }
        return null;
    }
}

The SecurityUtil is pretty simple. Given an Authentication object, retrieve the username property and use that to retrieve a Person object.

package com.cdi.igs.hub.spring;

import com.cdi.igs.dao.person.Person;
import com.cdi.igs.dao.person.PersonRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Component;

/**
 * Spring security related tools.
 * @author norrisshelton
 */
@Component
public class SecurityUtil {

    @Autowired
    private PersonRepository personRepository;

    /**
     * Retrieves the person object associated with the given authentication.
     * @param authentication Represents the token for an authentication request
     * @return person object, if one could be found
     */
    public Person getPersonByAuthentication(Authentication authentication) {
        Person person = null;
        if (authentication != null) {
            User user = (User) authentication.getPrincipal();

            if (user != null) {
                // get the person from the database and store in the session
                person = personRepository.findByUserName(user.getUsername());
            }

        }
        return person;
    }
}

I then registered the PersonArgumentResolver with the other argument resolvers for the Spring MVC framework.

<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/beans    http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/mvc      http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- Needed for Spring MVC Mockito tests in addition to the production context-->
    <mvc:annotation-driven>
        <mvc:argument-resolvers>
            <bean class="org.springframework.security.web.bind.support.AuthenticationPrincipalArgumentResolver"/>
            <bean class="com.cdi.igs.hub.spring.PersonArgumentResolver"/>
        </mvc:argument-resolvers>
    </mvc:annotation-driven>

</beans>

February 27th, 2014

Posted In: Java, Spring, Spring MVC, Spring Security

5 Comments

How do you mock a Springframework security principal for testing spring MVC controllers?

  1. Create a spring security principal
  2. Create a spring authentication
  3. Add the spring security authentication to the security context

The last step should not be needed because MockMVC has a method to set the principal (line 16). However, we had an annotation that used the security principal to retrieve the username that was then used to retrieve another object. We couldn’t find the value there. We set the spring security authentication manually via the spring security context (line 19).

public class TestActivityController {
    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
    }

    @Test
    public void testInitialDisplay() throws Exception {
        User user = new User("screen011","", AuthorityUtils.createAuthorityList("ROLE_PATRON"));
        TestingAuthenticationToken testingAuthenticationToken = new TestingAuthenticationToken(user,null);
        SecurityContextHolder.getContext().setAuthentication(testingAuthenticationToken);

        mockMvc.perform(post("/activity/initial")
                //.principal(testingAuthenticationToken))
                .andExpect(status().isOk())
                .andDo(print());
    }
}

February 27th, 2014

Posted In: Java, MockMVC, Spring, Spring MVC, Spring Security

Tags: , , , , , , , , , , , , , ,

2 Comments

Springframework MVC 3.2 introduced the ability to test controllers via MockMVC. In this example, we will test a controller that returns JSON via @ResponseBody.

Here are the dependencies that you will need.

            <!-- This is usually included as part of your normal dependencies.  If not, include this way -->
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>javax.servlet-api</artifactId>
                <version>3.1.0</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-test</artifactId>
                <version>${spring.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.mockito</groupId>
                <artifactId>mockito-core</artifactId>
                <version>1.9.5</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>com.jayway.jsonpath</groupId>
                <artifactId>json-path</artifactId>
                <version>${jsonpath.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>com.jayway.jsonpath</groupId>
                <artifactId>json-path-assert</artifactId>
                <version>${jsonpath.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.11</version>
                <scope>test</scope>
            </dependency>

This is an example of the spring context.

<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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans    http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/mvc      http://www.springframework.org/schema/mvc/spring-mvc.xsd
                           http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsd">

    <mvc:annotation-driven/>

    <context:component-scan base-package="com.cdi.igs.core.spring.web"/>

</beans>

The basic test class needs to have the following annotations, properties and setup defined. Please note the static imports. You want to use these from the mock mvc request builders.

import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import static org.hamcrest.Matchers.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;


@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration
public class TestGlobalControllerExceptionHandler {

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
    }
//...
}

This is an example test method that calls a spring controller that returns a string. We are creating an empty model object that we convert to JSON. We tell the method that we are calling that we are sending JSON, because the method that we are calling expects to be sent a JSON object. We get validation errors in this case, that we compare with our expected results. The JSON response that we get back from the call to the controller is “{“fieldErrors”:[{“message”:”may not be null”},{“message”:”may not be null”}]}

    @Test
    public void testMyMethod() throws Exception {
        mockMvc.perform(post("/mymethod")
                        .content(new ObjectMapper().writeValueAsString(new TargetExceptionModel()))
                        .contentType(MediaType.APPLICATION_JSON))
               .andExpect(status().isBadRequest())
        .andExpect(jsonPath("$.fieldErrors", hasSize(2)))
        .andExpect(jsonPath("$.fieldErrors[*].message", contains("may not be null", "may not be null")))
        .andDo(print());
    }

Here is an example of a controller test method that users other types of matchers. Example data is:

{"status":"SUCCESS","message":null,"previousPage":null,"nextPage":"login/privacy_policy","errors":null,"exception":null,"idSetting":"pri","setting":"privacy-Starfish","value":"test","settingText":"lots and lots of text","date":"01-27-2014"}
    @Test
    public void testGetPrivacyByClientSuccess() throws Exception {
        mockMvc.perform(get("/privacy/pri"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.idSetting", containsString("pri")))
                .andExpect(jsonPath("$.setting", containsString("privacy-Starfish")))
                .andExpect(jsonPath("$.settingText", notNullValue()))
                .andExpect(jsonPath("$.value", containsString("test")))
                .andExpect(jsonPath("$.exception", nullValue()))
                .andDo(print());
    }

I needed to write a method that passed an object that contained an exception object back to the calling method. The data being sent back was:

{"status":"ERROR","message":null,"previousPage":null,"nextPage":null,"errors":null,"exception":{"cause":null,"stackTrace":[{"methodName":"copyProperties","fileName":"PropertyUtilsBean.java","lineNumber":276,"className":"org.apache.commons.beanutils.PropertyUtilsBean","nativeMethod":false},{"methodName":"copyProperties","fileName":"PropertyUtils.java","lineNumber":219,"className":"org.apache.commons.beanutils.PropertyUtils","nativeMethod":false},{"methodName":"getPrivacy","fileName":"LoginService.java","lineNumber":193,"className":"com.cdi.igs.core.login.LoginService","nativeMethod":false},{"methodName":"getPrivacyByClient","fileName":"LoginController.java","lineNumber":94,"className":"com.cdi.igs.services.LoginController","nativeMethod":false},{"methodName":"invoke0","fileName":"NativeMethodAccessorImpl.java","lineNumber":-2,"className":"sun.reflect.NativeMethodAccessorImpl","nativeMethod":true},{"methodName":"invoke","fileName":"NativeMethodAccessorImpl.java","lineNumber":57,"className":"sun.reflect.NativeMethodAccessorImpl","nativeMethod":false},{"methodName":"invoke","fileName":"DelegatingMethodAccessorImpl.java","lineNumber":43,"className":"sun.reflect.DelegatingMethodAccessorImpl","nativeMethod":false},{"methodName":"invoke","fileName":"Method.java","lineNumber":606,"className":"java.lang.reflect.Method","nativeMethod":false},{"methodName":"invoke","fileName":"InvocableHandlerMethod.java","lineNumber":214,"className":"org.springframework.web.method.support.InvocableHandlerMethod","nativeMethod":false},{"methodName":"invokeForRequest","fileName":"InvocableHandlerMethod.java","lineNumber":132,"className":"org.springframework.web.method.support.InvocableHandlerMethod","nativeMethod":false},{"methodName":"invokeAndHandle","fileName":"ServletInvocableHandlerMethod.java","lineNumber":104,"className":"org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod","nativeMethod":false},{"methodName":"invokeHandleMethod","fileName":"RequestMappingHandlerAdapter.java","lineNumber":749,"className":"org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter","nativeMethod":false},{"methodName":"handleInternal","fileName":"RequestMappingHandlerAdapter.java","lineNumber":690,"className":"org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter","nativeMethod":false},{"methodName":"handle","fileName":"AbstractHandlerMethodAdapter.java","lineNumber":83,"className":"org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter","nativeMethod":false},{"methodName":"doDispatch","fileName":"DispatcherServlet.java","lineNumber":945,"className":"org.springframework.web.servlet.DispatcherServlet","nativeMethod":false},{"methodName":"doService","fileName":"DispatcherServlet.java","lineNumber":876,"className":"org.springframework.web.servlet.DispatcherServlet","nativeMethod":false},{"methodName":"processRequest","fileName":"FrameworkServlet.java","lineNumber":961,"className":"org.springframework.web.servlet.FrameworkServlet","nativeMethod":false},{"methodName":"doGet","fileName":"FrameworkServlet.java","lineNumber":852,"className":"org.springframework.web.servlet.FrameworkServlet","nativeMethod":false},{"methodName":"service","fileName":"HttpServlet.java","lineNumber":687,"className":"javax.servlet.http.HttpServlet","nativeMethod":false},{"methodName":"service","fileName":"FrameworkServlet.java","lineNumber":837,"className":"org.springframework.web.servlet.FrameworkServlet","nativeMethod":false},{"methodName":"service","fileName":"TestDispatcherServlet.java","lineNumber":64,"className":"org.springframework.test.web.servlet.TestDispatcherServlet","nativeMethod":false},{"methodName":"service","fileName":"HttpServlet.java","lineNumber":790,"className":"javax.servlet.http.HttpServlet","nativeMethod":false},{"methodName":"doFilter","fileName":"MockFilterChain.java","lineNumber":170,"className":"org.springframework.mock.web.MockFilterChain$ServletFilterProxy","nativeMethod":false},{"methodName":"doFilter","fileName":"MockFilterChain.java","lineNumber":137,"className":"org.springframework.mock.web.MockFilterChain","nativeMethod":false},{"methodName":"perform","fileName":"MockMvc.java","lineNumber":141,"className":"org.springframework.test.web.servlet.MockMvc","nativeMethod":false},{"methodName":"testGetPrivacyByClientFail","fileName":"TestLoginController.java","lineNumber":96,"className":"com.cdi.igs.services.TestLoginController","nativeMethod":false},{"methodName":"invoke0","fileName":"NativeMethodAccessorImpl.java","lineNumber":-2,"className":"sun.reflect.NativeMethodAccessorImpl","nativeMethod":true},{"methodName":"invoke","fileName":"NativeMethodAccessorImpl.java","lineNumber":57,"className":"sun.reflect.NativeMethodAccessorImpl","nativeMethod":false},{"methodName":"invoke","fileName":"DelegatingMethodAccessorImpl.java","lineNumber":43,"className":"sun.reflect.DelegatingMethodAccessorImpl","nativeMethod":false},{"methodName":"invoke","fileName":"Method.java","lineNumber":606,"className":"java.lang.reflect.Method","nativeMethod":false},{"methodName":"runReflectiveCall","fileName":"FrameworkMethod.java","lineNumber":47,"className":"org.junit.runners.model.FrameworkMethod$1","nativeMethod":false},{"methodName":"run","fileName":"ReflectiveCallable.java","lineNumber":12,"className":"org.junit.internal.runners.model.ReflectiveCallable","nativeMethod":false},{"methodName":"invokeExplosively","fileName":"FrameworkMethod.java","lineNumber":44,"className":"org.junit.runners.model.FrameworkMethod","nativeMethod":false},{"methodName":"evaluate","fileName":"InvokeMethod.java","lineNumber":17,"className":"org.junit.internal.runners.statements.InvokeMethod","nativeMethod":false},{"methodName":"evaluate","fileName":"RunBefores.java","lineNumber":26,"className":"org.junit.internal.runners.statements.RunBefores","nativeMethod":false},{"methodName":"evaluate","fileName":"RunBeforeTestMethodCallbacks.java","lineNumber":74,"className":"org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks","nativeMethod":false},{"methodName":"evaluate","fileName":"RunAfterTestMethodCallbacks.java","lineNumber":83,"className":"org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks","nativeMethod":false},{"methodName":"evaluate","fileName":"SpringRepeat.java","lineNumber":72,"className":"org.springframework.test.context.junit4.statements.SpringRepeat","nativeMethod":false},{"methodName":"runChild","fileName":"SpringJUnit4ClassRunner.java","lineNumber":232,"className":"org.springframework.test.context.junit4.SpringJUnit4ClassRunner","nativeMethod":false},{"methodName":"runChild","fileName":"SpringJUnit4ClassRunner.java","lineNumber":89,"className":"org.springframework.test.context.junit4.SpringJUnit4ClassRunner","nativeMethod":false},{"methodName":"run","fileName":"ParentRunner.java","lineNumber":238,"className":"org.junit.runners.ParentRunner$3","nativeMethod":false},{"methodName":"schedule","fileName":"ParentRunner.java","lineNumber":63,"className":"org.junit.runners.ParentRunner$1","nativeMethod":false},{"methodName":"runChildren","fileName":"ParentRunner.java","lineNumber":236,"className":"org.junit.runners.ParentRunner","nativeMethod":false},{"methodName":"access$000","fileName":"ParentRunner.java","lineNumber":53,"className":"org.junit.runners.ParentRunner","nativeMethod":false},{"methodName":"evaluate","fileName":"ParentRunner.java","lineNumber":229,"className":"org.junit.runners.ParentRunner$2","nativeMethod":false},{"methodName":"evaluate","fileName":"RunBeforeTestClassCallbacks.java","lineNumber":61,"className":"org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks","nativeMethod":false},{"methodName":"evaluate","fileName":"RunAfterTestClassCallbacks.java","lineNumber":71,"className":"org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks","nativeMethod":false},{"methodName":"run","fileName":"ParentRunner.java","lineNumber":309,"className":"org.junit.runners.ParentRunner","nativeMethod":false},{"methodName":"run","fileName":"SpringJUnit4ClassRunner.java","lineNumber":175,"className":"org.springframework.test.context.junit4.SpringJUnit4ClassRunner","nativeMethod":false},{"methodName":"run","fileName":"JUnitCore.java","lineNumber":160,"className":"org.junit.runner.JUnitCore","nativeMethod":false},{"methodName":"startRunnerWithArgs","fileName":"JUnit4IdeaTestRunner.java","lineNumber":74,"className":"com.intellij.junit4.JUnit4IdeaTestRunner","nativeMethod":false},{"methodName":"prepareStreamsAndStart","fileName":"JUnitStarter.java","lineNumber":211,"className":"com.intellij.rt.execution.junit.JUnitStarter","nativeMethod":false},{"methodName":"main","fileName":"JUnitStarter.java","lineNumber":67,"className":"com.intellij.rt.execution.junit.JUnitStarter","nativeMethod":false},{"methodName":"invoke0","fileName":"NativeMethodAccessorImpl.java","lineNumber":-2,"className":"sun.reflect.NativeMethodAccessorImpl","nativeMethod":true},{"methodName":"invoke","fileName":"NativeMethodAccessorImpl.java","lineNumber":57,"className":"sun.reflect.NativeMethodAccessorImpl","nativeMethod":false},{"methodName":"invoke","fileName":"DelegatingMethodAccessorImpl.java","lineNumber":43,"className":"sun.reflect.DelegatingMethodAccessorImpl","nativeMethod":false},{"methodName":"invoke","fileName":"Method.java","lineNumber":606,"className":"java.lang.reflect.Method","nativeMethod":false},{"methodName":"main","fileName":"AppMain.java","lineNumber":120,"className":"com.intellij.rt.execution.application.AppMain","nativeMethod":false}],"message":"No origin bean specified","localizedMessage":"No origin bean specified","suppressed":[]},"idSetting":"Starfish1","setting":null,"value":null,"settingText":null,"date":null}
    @Test
    public void testGetPrivacyByClientFail() throws Exception {
        mockMvc.perform(get("/privacy/Starfish1"))
               .andExpect(status().isOk())
               .andExpect(jsonPath("$.idSetting", containsString("Starfish1")))
               .andExpect(jsonPath("$.setting", nullValue()))
               .andExpect(jsonPath("$.settingText", nullValue()))
               .andExpect(jsonPath("$.value", nullValue()))
               .andExpect(jsonPath("$.exception.cause", nullValue()))
               .andExpect(jsonPath("$.exception.stackTrace", notNullValue()))
               .andExpect(jsonPath("$.exception.stackTrace[0].methodName", notNullValue()))
               .andDo(print());
    }

To get the content and store it in a variable outside the test, add .andReturn() to the end of the perform and store the result in a MvcResult, then get the content.

        MvcResult result = mockMvc.perform(post("/login")
                                               .content(
                                                   "{"userName":"screen011","password":"Jason3080!"," +
                                                   ""remoteAddress":"0.0" +
                                                   ".0.0"}"
                                                       )
                                               .contentType(MediaType.APPLICATION_JSON))
               .andExpect(status().isOk())
               .andExpect(jsonPath("$.exception", nullValue()))
               .andExpect(jsonPath("$.errors", hasSize(0)))
               .andExpect((jsonPath("$.ssoToken", notNullValue())))
               .andDo(print())
               .andReturn();
        String content = result.getResponse().getContentAsString();

Then if you need to extract a value out of the JSON, you can use JsonPath out of jayway like

        String content = result.getResponse().getContentAsString();

        assertNotNull(content);
        String ssoToken = JsonPath.read(content, "$.ssoToken");
        assertNotNull(ssoToken);

February 27th, 2014

Posted In: Java, MockMVC, Spring, Spring MVC

Tags: , , , , , , ,

2 Comments

The documentation is here
http://velocity.apache.org/engine/releases/velocity-1.7/user-guide.html

An if statement looks like this

    #if( $user.userId )
        ${user.userId}
    #end

An if-elseif-else looks like this

#if( $foo < 10 )
    <strong>Go North</strong>
#elseif( $foo == 10 )
    <strong>Go East</strong>
#elseif( $bar == 6 )
    <strong>Go South</strong>
#else
    <strong>Go West</strong>
#end

A for loop looks like: $velocityCount is a 1-based counter of which element you are on in the loop.

     #foreach( $transaction in $transactionList )
          $!transaction.fullName
          $velocityCount
     #end

Values can be output by ${…} or $… There is a particular case where the ${…} notation should be used, but the case eludes me right now.

     ${data.firstName}
     $data.firstName

If the value of ${data.firstName} does not exist, then ${data.firstName} will be outputted. To get around that, use the $!… notation. Then if it doesn’t exist, nothing will be outputted.

$!transaction.fullName

Setting a variable during the processing of the template is like

#set( $rowCss = "odd")

<tr class="$!rowCss">
</tr>

Setting an array variable is very similar to setting a regular variable.

#set($platformsClasses = ['desktop','mobile bxslider'] )

Iterating over the array variable is the same as it is for any iterable item.

        #set($platformsClasses = ['desktop','mobile bxslider'] )
		#foreach($platformClass in $platformsClasses)
            <ul class="$platformClass">
                /* ... */
            </ul>
		#end

February 20th, 2014

Posted In: java ninja, Javaninja, templating, velocity

Tags:

Leave a Comment

I was loading a java resource via the classloader. I had the need to know where the file was on the file system.

    /**
     * Gets the absolute path of a file loaded via a classloader.
     * @param classpathFile file to be loaded from the classpath.
     * @return absolute file path of the file
     * @throws URISyntaxException
     */
    public static String getAbsoluteFilePath(String classpathFile) throws URISyntaxException {
        String absoluteFilePath = "";
        URL url = CommonUtil.class.getResource(classpathFile);
        if (url != null) {
            Path path = Paths.get(url.toURI());
            if (path != null) {
                absoluteFilePath = path.toString();
            }
        }
        return absoluteFilePath;
    }

February 14th, 2014

Posted In: Java, java ninja, Javaninja

Tags: , , , , , , , , ,

Leave a Comment

How do you get a Joda DateTime out of a localDate with is defaulted to Midnight? This is the common case of I have a date, but I need to have a time on it now and that time would be midnight.

LocalDate localDate = new LocalDate();
localDate.toDateTimeAtStartOfDay();

February 13th, 2014

Posted In: Java, Joda-Time

Leave a Comment

How do you get the active Springframework profiles?
Inject the Environment object

    @Autowired
    private Environment environment;

The Environment object has getActiveProfiles that returns an array of active profiles. To get the first active profile, do…

String profile = environment.getActiveProfiles()[0];

February 11th, 2014

Posted In: Spring, Spring Profile

Tags: , , ,

Leave a Comment

mvn versions:display-dependency-updates

The output is useful, but you still need to interpret it. In this case, there is a beta library that is suggested. Not.

INFO] ------------------------------------------------------------------------
[INFO] Building igs 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- versions-maven-plugin:2.1:display-dependency-updates (default-cli) @ igs ---
[INFO] The following dependencies in Dependency Management have newer versions:
[INFO]   commons-collections:commons-collections ............ 3.2.1 -> 20040616
[INFO]   org.hibernate:hibernate-validator ......... 5.0.1.Final -> 5.1.0.Beta1
[INFO]
[INFO]

In this case, a library with a version number that doesn’t follow the normal version patters is mistakenly noted as a newer version.

[INFO] ------------------------------------------------------------------------
[INFO] Building assets 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- versions-maven-plugin:2.1:display-dependency-updates (default-cli) @ assets ---
[INFO] The following dependencies in Dependency Management have newer versions:
[INFO]   commons-collections:commons-collections ............ 3.2.1 -> 20040616
[INFO]   org.hibernate:hibernate-validator ......... 5.0.1.Final -> 5.1.0.Beta1
[INFO]
[INFO]

February 7th, 2014

Posted In: Maven

Tags: , , , ,

Leave a Comment

A friend of mine had to use this and I thought it was something worth remembering for the Springframework.

    <util:list id="tmDateFormats" >
        <value>yyyy-MM-dd</value>
        <value>dd-MMM-yy</value>
        <value>MM/dd/yyyy</value>
    </util:list>

He injected them with SpEl

    @Resource(name="tmDateFormats")
    private List<String> dateFormats;

February 6th, 2014

Posted In: Java, Spring

Tags: , ,

Leave a Comment

I have a Springframework integrated Junit test. I had seen annotating a Junit test class with @Test(expected = Exception.class) to test for exceptions before. In this case, we needed to test for Exception and the message was made the difference. This can be accomplished by @Rule

    @Rule
    public ExpectedException expectedEx = ExpectedException.none();

    @Test(expected = Exception.class)
    public void testAddNegativeTransaction() throws Exception {
        expectedEx.expect(Exception.class);
        expectedEx.expectMessage("Cannot withdraw more than available balance.");
        transactionService.addNegativeTransaction(new TransactionRequest("1", "acw", 10, 2000.00));
    }

February 5th, 2014

Posted In: Integration Tests, Java, JUnit, Test Driven Development

Tags: , , , , , , , , , ,

Leave a Comment

LinkedIn Auto Publish Powered By : XYZScripts.com