spring-ldap学习(一)

1、搭建ldap服务,我用的系统是Ubuntu14.04,具体可以参考这篇文章:ubuntu14.04搭建ldap服务,按照步骤来没什么问题。

  安装之后访问地址为:http://10.8.12.147/phpldapadmin/ 

                                         name: cn=admin,dc=dianrong,dc=com 

                                         password: 123456

2、安装ldapsoft ldap admin tool,官网下载地址:http://www.ldapsoft.com/download.html

 点击新建连接(New Connection),按照以下配置:



第一次进来,只会有下图的cn=admin



3、利用spring-ldap实现增删改查(没有使用注解)

model类:

/**
 * Created by drjr on 5/17/17.
 */
public class User {

    private String fullName;

    private String lastName;

    private String description;

    private String country;

    private String company;

    private String phone;

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getFullName() {
        return fullName;
    }

    public void setFullName(String fullName) {
        this.fullName = fullName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }
}
定义操作ldap的接口类:

public interface UserDao {
    void create(User user);

    void update(User user);

    void delete(String fullName);

    List<String> getAllUserNames();

    List<User> findAll();

    User findByPrimaryKey(String fullname);
}
接口实现类:
public class UserDaoImpl implements UserDao {

    private LdapTemplate ldapTemplate;

    @Override
    public void create(User user) {
        Name dn = buildDn(user.getFullName()); // 生成条目唯一标识,有点类似mysql的主键ID
        DirContextAdapter context = new DirContextAdapter(dn);  // 根据体用提供的dn构建适配器对象
        mapToContext(user, context);   // 给适配器对象设置属性值
        ldapTemplate.bind(dn, context, null); // 插入数据
    }

    @Override
    public void update(User user) {
        Name dn = buildDn(user.getFullName());
        DirContextAdapter context = (DirContextAdapter) ldapTemplate.lookup(dn);
        mapToContext(user, context);
        ldapTemplate.modifyAttributes(dn, context.getModificationItems());
    }

    @Override
    public void delete(String fullName) {
        ldapTemplate.unbind(buildDn(fullName));
    }

    @Override
    public List<String> getAllUserNames() {
        return ldapTemplate.search(query()
                        .attributes("cn")
                        .where("objectclass").is("person"),
                new AttributesMapper<String>() {
                    @Override
                    public String mapFromAttributes(Attributes attributes) throws NamingException {
                        return attributes.get("cn").get().toString();
                    }
                });
    }

    @Override
    public List<User> findAll() {
        return ldapTemplate.search(query()
                        .where("objectclass").is("person"),
                USER_CONTEXT_MAPPER);
    }

    @Override
    public User findByPrimaryKey(String fullname) {
        LdapName dn = buildDn(fullname);
        return ldapTemplate.lookup(dn, USER_CONTEXT_MAPPER);
    }

    private LdapName buildDn(String fullName) {
        return LdapNameBuilder.newInstance()
                .add("cn", fullName)
                .build();
    }

    private void mapToContext(User user, DirContextAdapter context) {
        context.setAttributeValues("objectclass", new String[] { "top", "person" });
        context.setAttributeValue("cn", user.getFullName());
        context.setAttributeValue("sn", user.getLastName());
        context.setAttributeValue("description", user.getDescription());
        context.setAttributeValue("telephoneNumber", user.getPhone());
    }

    private final static ContextMapper<User> USER_CONTEXT_MAPPER = new AbstractContextMapper<User>() {
        @Override
        public User doMapFromContext(DirContextOperations context) {
            User user = new User();

            user.setFullName(context.getStringAttribute("cn"));
            user.setLastName(context.getStringAttribute("sn"));
            user.setDescription(context.getStringAttribute("description"));
            user.setPhone(context.getStringAttribute("telephoneNumber"));

            return user;
        }
    };

    public void setLdapTemplate(LdapTemplate ldapTemplate) {
        this.ldapTemplate = ldapTemplate;
    }

    public LdapTemplate getLdapTemplate() {
        return ldapTemplate;
    }
}
前端入口controller层:

@Controller
@RequestMapping(value = "users")
public class TestSpringLdapController {

    @Autowired
    private UserDao userDao;


    @RequestMapping("/addUser")
    public String addUser() {
        User user = getUser();

        userDao.create(user);
        return "success";
    }

    @RequestMapping("/showUser")
    @ResponseBody
    public ModelMap showUser(@RequestParam(value = "fullName", required = true) String fullName) {
        User user = userDao.findByPrimaryKey(fullName);
        return new ModelMap("user", user);
    }

    @RequestMapping("/updatePhoneNumber")
    public String updatePhoneNumber(@RequestParam(value = "fullName", required = true) String fullName) {
        User user = userDao.findByPrimaryKey(fullName);
        user.setPhone(StringUtils.join(new String[] { user.getPhone(), "0" }));

        userDao.update(user);
        return "success";
    }

    @RequestMapping("/removeUser")
    public String removePerson(@RequestParam(value = "fullName", required = true) String fullName) {
        userDao.delete(fullName);
        return "success";
    }

    @RequestMapping("/getAll")
    @ResponseBody
    public String getAll() throws IOException {
        ObjectMapper mapper = getDefaultObjectMapper();
        List<User> users = userDao.findAll();

        return mapper.writeValueAsString(users);
    }

    @RequestMapping("/getAllName")
    @ResponseBody
    public String getAllName() throws IOException {
        ObjectMapper mapper = getDefaultObjectMapper();
        List<String> userNames = userDao.getAllUserNames();
        return mapper.writeValueAsString(userNames);
    }

    private User getUser() {
        User user = new User();
        user.setFullName("curry");
        user.setLastName("stephone");
        user.setCompany("company1");
        user.setCountry("Sweden");
        user.setDescription("Test user");
        return user;
    }

    public static ObjectMapper getDefaultObjectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_EMPTY);
        //设置将MAP转换为JSON时候只转换值不等于NULL的
        mapper.configure(SerializationConfig.Feature.WRITE_NULL_MAP_VALUES, false);
        //mapper.configure(JsonGenerator.Feature.ESCAPE_NON_ASCII, true);
        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        //设置有属性不能映射成PO时不报错
        mapper.disable(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES);
        return mapper;
    }
}
用的是gradle构建,所以build.gradle配置如下:

group 'dianrongDenghb'
version '1.0-SNAPSHOT'

apply plugin: 'java'
apply plugin: 'war'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

repositories {
    jcenter()
    maven {
        url 'https://repo.spring.io/libs-milestone'
    }
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    compile group: 'org.springframework.ldap', name: 'spring-ldap-core', version: '2.1.0.RELEASE'
    compile group: 'org.springframework.ldap', name: 'spring-ldap-test', version: '2.1.0.RELEASE'
    compile group: 'org.springframework', name: 'spring-context', version: '4.2.4.RELEASE'
    compile group: 'org.springframework', name: 'spring-webmvc', version: '4.2.4.RELEASE'
    compile group: 'org.springframework', name: 'spring-web', version: '4.2.4.RELEASE'
    compile group: 'org.springframework', name: 'spring-beans', version: '4.2.4.RELEASE'
    compile 'org.springframework:spring-core:4.2.4.RELEASE'
    compile group: 'org.springframework.data', name: 'spring-data-commons', version: '1.11.4.RELEASE'
    compile group: 'javax.servlet', name: 'jstl', version: '1.2'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.4.3'
    compile group: 'org.codehaus.jackson', name: 'jackson-mapper-asl', version: '1.9.13'
    compile group: 'org.codehaus.jackson', name: 'jackson-core-asl', version: '1.9.13'
    providedCompile group: 'javax.servlet', name: 'javax.servlet-api', version: '3.1.0'
}

数据源的相关配置放在:ldap.properties

sample.ldap.url=ldap://10.8.12.147:389
sample.ldap.userDn=cn=admin,dc=dianrong,dc=com
sample.ldap.password=123456
sample.ldap.base=dc=dianrong,dc=com
sample.ldap.clean=true

在applicationContext.xml读取数据源配置文件,生成ldapTemplate

<?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:context="http://www.springframework.org/schema/context"
       xmlns:ldap="http://www.springframework.org/schema/ldap"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/ldap http://www.springframework.org/schema/ldap/spring-ldap.xsd">
    <context:property-placeholder location="classpath:/ldap.properties" />
    <ldap:context-source id="contextSource"
                         password="${sample.ldap.password}"
                         url="${sample.ldap.url}"
                         username="${sample.ldap.userDn}"
                         base="${sample.ldap.base}" />

    <ldap:ldap-template id="ldapTemplate" context-source-ref="contextSource"/>
    <bean id="personDao" class="ldap.dao.odm.PersonDaoImpl">
        <property name="ldapTemplate" ref="ldapTemplate" />
    </bean>

    <bean id="userDao" class="ldap.dao.UserDaoImpl">
        <property name="ldapTemplate" ref="ldapTemplate" />
    </bean>
</beans>
springmvc配置文件
<?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:context="http://www.springframework.org/schema/context"
	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/context http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd">

	<mvc:annotation-driven />
	<context:component-scan base-package="ldap.web" />

	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">

		<property name="prefix" value="/WEB-INF/jsp/" />
		<property name="suffix" value=".jsp" />
	</bean>
</beans>
web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="Tiink-preview" xmlns="http://java.sun.com/xml/ns/j2ee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
	version="2.4">

	<display-name>Spring LDAP Basic Example</display-name>
	<listener>
		<listener-class>
			org.springframework.web.context.ContextLoaderListener
		</listener-class>
	</listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:/applicationContext.xml</param-value>
    </context-param>

    <servlet>
		<servlet-name>basic</servlet-name>
		<servlet-class>
			org.springframework.web.servlet.DispatcherServlet
		</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/basic-servlet.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>basic</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
</web-app>

到此结束,下面介绍通过注解的方式,实现对象和目录映射功能,简化代码。

model类这样写:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import org.springframework.ldap.odm.annotations.*;

import javax.naming.Name;

/**
 * Created by drjr on 5/16/17.
 */
@Entry(objectClasses = {"person", "top"})
@JsonIgnoreProperties(value = {"dn"})
public class Person {
    @Id
    private Name dn;

    @Attribute(name = "cn")
    @DnAttribute(value = "cn", index = 0)
    private String fullName;

    @Attribute(name = "sn")
    private String lastName;

    @Attribute(name = "description")
    private String description;

    @Transient
    private String country;

    @Transient
    private String company;

    @Attribute(name = "telephoneNumber")
    private String phone;

    public Name getDn() {
        return dn;
    }

    public void setDn(Name dn) {
        this.dn = dn;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getFullName() {
        return fullName;
    }

    public void setFullName(String fullName) {
        this.fullName = fullName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }
}

@JsonIgnoreProperties此注解是类注解,作用是json序列化时将java bean中的一些属性忽略掉,序列化和反序列化都受影响。不用此注解,会报json转换的异常。

@Id表明实体类DN ,这个属性必须是javax.naming.Name类型,有点类似数据库表中的主键意思

@Attribute表示目录属性映射到对象类字段,表示这是objectClass的一个属性

@Dnattribute标注的属性都是属于自动构建DN时的一部分

@Entry注解表明这是一个ldap的实体映射类

接口实现类(增删改查和上面的实现类对比省掉一些代码,更加简洁,不需要手动去映射字段了):

import ldap.dao.PersonDao;
import ldap.domain.Person;
import org.springframework.ldap.core.AttributesMapper;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.support.LdapNameBuilder;

import javax.naming.NamingException;
import javax.naming.directory.Attributes;
import javax.naming.ldap.LdapName;
import java.util.List;

import static org.springframework.ldap.query.LdapQueryBuilder.query;

/**
 * Created by drjr on 5/16/17.
 */
public class PersonDaoImpl implements PersonDao {

    private LdapTemplate ldapTemplate;

    @Override
    public void create(Person person) {
        ldapTemplate.create(person);
    }

    @Override
    public void update(Person person) {
        ldapTemplate.update(person);
    }

    @Override
    public void delete(Person person) {
        ldapTemplate.delete(ldapTemplate.findByDn(buildDn(person.getFullName()), Person.class));
    }

    @Override
    public List<String> getAllPersonNames() {
        return ldapTemplate.search(query()
                        .attributes("cn")
                        .where("objectclass").is("person"),
                new AttributesMapper<String>() {
                    public String mapFromAttributes(Attributes attrs) throws NamingException {
                        return attrs.get("cn").get().toString();
                    }
                });
    }

    @Override
    public List<Person> findAll() {
        return ldapTemplate.findAll(Person.class);
    }

    @Override
    public Person findByPrimaryKey(String fullname) {
        LdapName dn = buildDn(fullname);
        Person person = ldapTemplate.findByDn(dn, Person.class);

        return person;
    }

    private LdapName buildDn(String fullName) {
        return LdapNameBuilder.newInstance()
                .add("cn", fullName)
                .build();
    }

    public void setLdapTemplate(LdapTemplate ldapTemplate) {
        this.ldapTemplate = ldapTemplate;
    }

}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值