wtorek, 21 listopada 2017

Why Spring returns 404 for my request?

When Spring Web MVC returns 404 in response to our request it means that cannot find handler for request "signature". As a signature we mean request mapping and request parameters.

How Spring resolves handler for a given url address?

The class responsible for matching mappings with requests is org.springframework.web.servlet.DispatcherServlet. The specific handler will be determined by applying handler mappings. Method responsible for that is called getHandler and it takes HTTP servlet request (Good old javax.servlet.http.HttpServletRequest instance). It basically goes through all registered handler mappings and tests each in order. The first match win. As the result, it returns an object of HandlerExecutionChain class.
AbstractHandlerMethodMapping.java

protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {..}

Resolving details

At first, it looks for a direct match. eg /api/logs/3/4 Next, it starts to look for matching patterned paths eg. /api/logs/{parent}/{child}. Takes all matched and is looking for the best match.

niedziela, 12 listopada 2017

package org.maziarz.ldap;

import java.util.Arrays;
import java.util.Hashtable;
import java.util.List;

import javax.naming.Context;
import javax.naming.Name;
import javax.naming.directory.Attributes;
import javax.naming.directory.InitialDirContext;
import javax.naming.spi.DirObjectFactory;

import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.AuthenticationSource;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.core.support.LdapContextSource;

public class LdapTemplateTest {

	private static LdapProperties ldapProperties = new LdapProperties(
			"ldap://:389"
			,"LdapUser"
			,"s3cr3t"
			,"DC=mycompany,DC=local"
	);


	@Autowired
	private LdapTemplate ldapTemplate;

	public static class MyDirObjectFactory implements DirObjectFactory {

		@Override
		public Object getObjectInstance(Object o, Name name, Context context, Hashtable hashtable, Attributes attributes)
				throws Exception {
			return new InitialDirContext(ldapProperties.getContextProperties());
		}

		@Override
		public Object getObjectInstance(Object o, Name name, Context context, Hashtable hashtable) throws Exception {
			return new InitialDirContext(ldapProperties.getContextProperties());
		}
	}


	@Before
	public void before() {

			LdapContextSource ldapContextSource = new LdapContextSource();
			ldapContextSource.setUrl("ldap://"+ldapProperties.getHost()+":"+ldapProperties.getPort());
			ldapContextSource.setBase(ldapProperties.getContext());
			ldapContextSource.setUserDn(ldapProperties.getUsername());
			ldapContextSource.setPassword(ldapProperties.getPassword());

			ldapContextSource.setDirObjectFactory(MyDirObjectFactory.class);

			ldapContextSource.setAuthenticationSource(new AuthenticationSource() {
				@Override
				public String getPrincipal() {
					return ldapProperties.getUsername();
				}

				@Override
				public String getCredentials() {
					return ldapProperties.getPassword();
				}
			});

			ldapContextSource.afterPropertiesSet();

			ldapTemplate =  new LdapTemplate(ldapContextSource);

			ldapTemplate.setDefaultCountLimit(1000);
//			ldapTemplate.setIgnorePartialResultException(true);
	}


	@Test
	public void fetchAllAccounts() {

		List search = ldapTemplate.search(
				"OU=Users,OU=COMPANY", " (objectClass=person)",
				(AttributesMapper) attrs -> {
					if (attrs != null && attrs.get("sAMAccountName") != null) {
						return Arrays.asList(
								attrs.get("sAMAccountName").get()
								,((attrs.get("sn") != null)? attrs.get("sn"):"none")
						);
					}
					return "";
				});

		System.out.println(search);

	}


}