`
lhx1026
  • 浏览: 312065 次
  • 性别: Icon_minigender_2
  • 来自: 广州
社区版块
存档分类
最新评论

spring security3.0的ACL使用例子

阅读更多

这个例子是参考www.family168.com中的例子来做的,不过使用的是spring security 3.0.4。spring security的acl的默认使用的是用jdbc来对数据做持久化,因此这个例子也是在这个基础上来用的,在这个例子中使用的数据库是mysql。

首先是定义spring security的acl的四个基本表的sql定义:

 

CREATE TABLE `acl_sid` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `principal` tinyint(1) NOT NULL,
  `sid` varchar(100) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_uk_1` (`sid`,`principal`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

CREATE TABLE `acl_class` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `class` varchar(100) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_uk_2` (`class`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

CREATE TABLE `acl_object_identity` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `object_id_class` bigint(20) NOT NULL,
  `object_id_identity` bigint(20) NOT NULL,
  `parent_object` bigint(20) DEFAULT NULL,
  `owner_sid` bigint(20) NOT NULL,
  `entries_inheriting` tinyint(1) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_uk_3` (`object_id_class`,`object_id_identity`),
  KEY `foreign_fk_1` (`parent_object`),
  KEY `foreign_fk_3` (`owner_sid`),
  CONSTRAINT `acl_object_identity_ibfk_1` FOREIGN KEY (`parent_object`) REFERENCES `acl_object_identity` (`id`),
  CONSTRAINT `acl_object_identity_ibfk_2` FOREIGN KEY (`object_id_class`) REFERENCES `acl_class` (`id`),
  CONSTRAINT `acl_object_identity_ibfk_3` FOREIGN KEY (`owner_sid`) REFERENCES `acl_sid` (`id`)

CREATE TABLE `acl_entry` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `acl_object_identity` bigint(20) NOT NULL,
  `ace_order` int(11) NOT NULL,
  `sid` bigint(20) NOT NULL,
  `mask` int(11) NOT NULL,
  `granting` tinyint(1) NOT NULL,
  `audit_success` tinyint(1) NOT NULL,
  `audit_failure` tinyint(1) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `unique_uk_4` (`acl_object_identity`,`ace_order`),
  KEY `foreign_fk_5` (`sid`),
  CONSTRAINT `acl_entry_ibfk_1` FOREIGN KEY (`acl_object_identity`) REFERENCES `acl_object_identity` (`id`),
  CONSTRAINT `acl_entry_ibfk_2` FOREIGN KEY (`sid`) REFERENCES `acl_sid` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

 

这四个表的说明如下:

 

1、ACL_SID让我们定义系统中唯一主体或授权(“SID”意思是“安全标识”——Spring Security Identity),是ACL认证对象。 它包含的列有ID,一个文本类型的SID,以及principal。

    其中,SID是Security ID的简称,表示一个被认证对象。记录一个用户名(USERBASE.NAME)或角色名(ROLES.NAME) 。如果按角色认证,SID就是对应的角色,如果按用户名认证,SID就是对应的用户名。用来表示是否使用文本显示引用的主体名或一个GrantedAuthority。

    而principal是认证规则。1 SID为用户名,0 SID为角色名。因此,对每个唯一的主体或GrantedAuthority都有单独一行。 在使用获得授权的环境下,一个SID通常叫做"recipient"授予者。

 

2、ACL_CLASS 让我们在系统中确定唯一的领域对象类。包含的列有ID和java类名。 因此,对每个我们希望保存ACL权限的类都有单独一行。其中,class是所要操作的域对象类型,它是域对象类型的全限定名。只有在此表中的CLASS,才被准许进行ACL授权及验证。

 

3、ACL_OBJECT_IDENTITY 为系统中每个唯一的领域对象实例保存信息。 列包括ID,指向ACL_CLASS的外键,唯一标识,所以我们知道为哪个ACL_CLASS实例提供信息,parent,一个外键指向ACL_SID 表,展示领域对象实例的拥有者,我们是否允许ACL条目从任何父亲ACL继承。 我们对每个领域对象实例有一个单独的行,来保存ACL权限。

 

4、ACL_ENTRY保存分配给每个授予者单独的权限,表示ACL授予者权限。

    其中,acl_object_identity表示ACL_OBJECT_IDENTITY的外键。ace_order表示用于ACE集合排序 。sid表示recipient(比如一个ACL_SID外键),操作主体。mask表示一个整数位掩码,表示操作权限的掩码。 granting表示真实的权限被授权或被拒绝,1表示权限按MASK,0表示权限无效。  audit_success表示审计预留字段。 ,audit_failure表示审计预留字段。我们对于每个授予者都有单独一行,与领域对象工作获得一个权限。

 

二、配置aclService以及使用aclService

(1)首先是applicationContext-security.xml文件:

 

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
	xmlns:beans="http://www.springframework.org/schema/beans" xmlns:sec="http://www.springframework.org/schema/security"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
                     http://www.springframework.org/schema/security 
                     http://www.springframework.org/schema/security/spring-security-3.0.4.xsd ">
	<http auto-config='true'>
		<intercept-url pattern="/admin.jsp" access="ROLE_ADMIN" />
		<intercept-url pattern="/**" access="ROLE_USER" />
	</http>
	<sec:authentication-manager>
		<sec:authentication-provider>
			<user-service>
				<user name="admin" password="admin" authorities="ROLE_USER, ROLE_ADMIN" />
				<user name="user" password="user" authorities="ROLE_USER" />
			</user-service>
		</sec:authentication-provider>
	</sec:authentication-manager>
	<global-method-security secured-annotations="enabled"
		access-decision-manager-ref="aclAccessDecisionManager" />
</beans:beans>
 

(2)然后我们需要配置aclService,它负责与数据库进行交互:

 a、我们要为acl配置cache,默认使用ehcache,spring security提供了一些默认的实现类。

 

<bean id="aclCache" class="org.springframework.security.acls.domain.EhCacheBasedAclCache">
        <constructor-arg ref="aclEhCache"/>
    </bean>
    <bean id="aclEhCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
        <property name="cacheManager" ref="cacheManager"/>
        <property name="cacheName" value="aclCache"/>
    </bean>

 

b、定义ehance.xml文件,在其中配置对应的aclCache缓存策略:

 

<ehcache>
    <diskStore path="java.io.tmpdir"/>
    <defaultCache
        maxElementsInMemory="1000"
        eternal="false"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        overflowToDisk="true"
    />
    <cache
        name="aclCache"
        maxElementsInMemory="1000"
        eternal="false"
        timeToIdleSeconds="600"
        timeToLiveSeconds="3600"
        overflowToDisk="true"
    />
</ehcache>

 

c、配置lookupStrategy。

    简单来说,lookupStrategy的作用就是从数据库中读取信息,把这些信息提供给aclService使用,所以我们要为它配置一个dataSource,配置中还可以看到一个aclCache,这就是上面我们配置的缓存,它会把资源最大限度的利用起来。

 

   <bean id="lookupStrategy" class="org.springframework.security.acls.jdbc.BasicLookupStrategy">
        <constructor-arg ref="dataSource"/>
        <constructor-arg ref="aclCache"/>
        <constructor-arg>
            <bean class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl">
                <constructor-arg>
                    <list>
                        <ref local="adminRole"/>
                        <ref local="adminRole"/>
                        <ref local="adminRole"/>
                    </list>
                </constructor-arg>
            </bean>
        </constructor-arg>
        <constructor-arg>
            <bean class="org.springframework.security.acls.domain.ConsoleAuditLogger"/>
        </constructor-arg>
    </bean>
    <bean id="adminRole" class="org.springframework.security.core.authority.GrantedAuthorityImpl">
        <constructor-arg value="ROLE_ADMIN"/>
    </bean>

 

中间一部分可能会让人感到困惑,为何一次定义了三个adminRole呢?这是因为一旦acl信息被保存到数据库中,无论是修改它的从属者,还是变 更授权,抑或是修改其他的ace信息,都需要控制操作者的权限,这里配置的三个权限将对应于上述的三种修改操作,我们把它配置成只有ROLE_ADMIN 才能执行这三种修改操作。

d、配置aclService

当我们已经拥有了dataSource, lookupStrategy和aclCache的时候,就可以用它们来组装aclService了,之后所有的acl操作都是基于aclService展开的:

 

    <bean id="aclService" class="org.springframework.security.acls.jdbc.JdbcMutableAclService">
        <constructor-arg ref="dataSource"/>
        <constructor-arg ref="lookupStrategy"/>
        <constructor-arg ref="aclCache"/>
        <property name="classIdentityQuery" value="SELECT @@IDENTITY"/>
		<property name="sidIdentityQuery" value="SELECT @@IDENTITY"/>	
    </bean>

 

这里要注意,如果上面的xml定义中没有:

 <property name="classIdentityQuery" value="SELECT @@IDENTITY"/>  
 <property name="sidIdentityQuery" value="SELECT @@IDENTITY"/>     

 

这一部分的话,运行程序之后就会报以下的错误:

com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: PROCEDURE xxxDB.identity does not exist

这主要是因为数据有区别导致的。在org.springframework.security.acls.jdbc.JdbcMutableAclService这个类中,classIdentityQuerysidIdentityQuery 的默认值都是“call identity() ”。如果在使用mysql时不给这两个属性赋值的话,就会报错。

(3)使用aclService管理acl信息

当我们添加了一条信息,要在acl中记录这条信息的ID,所有者,以及对应的授权信息。下列代码在添加信息后执行,用于添加对应的acl信息:

 

ObjectIdentity oid = new ObjectIdentityImpl(Message.class, message.getId());
MutableAcl acl = mutableAclService.createAcl(oid);
acl.insertAce(0, BasePermission.ADMINISTRATION,
    new PrincipalSid(owner), true);
acl.insertAce(1, BasePermission.DELETE,
    new GrantedAuthoritySid("ROLE_ADMIN"), true);
acl.insertAce(2, BasePermission.READ,
    new GrantedAuthoritySid("ROLE_USER"), true);
mutableAclService.updateAcl(acl);

 

第一步,根据class和id生成object的唯一标示。

第二步,根据object的唯一标示,创建一个acl。

第三步,为acl增加ace,这里我们让对象的所有者拥有对这个对象的“管理”权限,让“ROLE_ADMIN”拥有对这个对象的“删除”权限,让“ROLE_USER”拥有对这个对象的“读取”权限。

最后,更新acl信息。

当我们删除对象时,也要删除对应的acl信息。下列代码在删除信息后执行,用于删除对应的acl信息。

 

ObjectIdentity oid = new ObjectIdentityImpl(Message.class, id);
mutableAclService.deleteAcl(oid, false);
 

使用class和id可以唯一标示一个对象,然后使用deleteAcl()方法将对象对应的acl信息删除。

(4)使用acl控制delete操作

上述代码中,除了对象的拥有者之外,我们还允许“ROLE_ADMIN”也可以删除对象,但是我们不会允许除此之外的其他用户拥有删除对象的权限,为了限制对象的删除操作,我们需要修改Spring Security的默认配置。

首先要增加一个对delete操作起作用的表决器:

 

  <bean id="aclMessageDeleteVoter" class="org.springframework.security.acls.AclEntryVoter">
        <constructor-arg ref="aclService"/>
        <constructor-arg value="ACL_MESSAGE_DELETE"/>
        <constructor-arg>
            <list>
                <util:constant static-field="org.springframework.security.acls.domain.BasePermission.ADMINISTRATION"/>
                <util:constant static-field="org.springframework.security.acls.domain.BasePermission.DELETE"/>
            </list>
        </constructor-arg>
        <property name="processDomainObjectClass" value="net.kentop.acl.object.Message"></property>
    </bean>
 

它只对Message这个类起作用,而且可以限制只有管理和删除权限的用户可以执行删除操作。

然后要将这个表决器添加到AccessDecisionManager中:

 

    <bean id="aclAccessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
        <property name="decisionVoters">
            <list>
                <bean class="org.springframework.security.access.vote.RoleVoter"/>
                <ref local="aclMessageDeleteVoter"/>
            </list>
        </property>
    </bean>

 

现在AccessDecisionManager中有两个表决器了,除了默认的RoleVoter之外,又多了一个我们刚刚添加的aclMessageDeleteVoter。

现在可以把新的AccessDecisionManager赋予全局方法权限管理器了。

	<global-method-security secured-annotations="enabled"
		access-decision-manager-ref="aclAccessDecisionManager" />

 

然后我们就可以在MessageService.java中使用Secured注解,控制删除操作了。

 

    @Transactional
    @Secured("ACL_MESSAGE_DELETE")
    public void remove(Message message) {
        list.remove(message);
        ObjectIdentity oid = new ObjectIdentityImpl(Message.class,
                message.getId());
        mutableAclService.deleteAcl(oid, false);
    }
 

实际上,我们最好不要让没有权限的操作者看到remove这个链接,可以使用taglib隐藏当前用户无权看到的信息。

 

<sec:accesscontrollist domainObject="${item}" hasPermission="8,16">
      |
      <a href="message.do?action=remove&id=${item.id}" mce_href="message.do?
action=remove&id=${item.id}">Remove</a>
</sec:accesscontrollist>

 

8, 16是acl默认使用的掩码,8表示DELETE,16表示ADMINISTRATOR,当用户不具有这些权限的时候,他在页面上就看不到remove链接,也就无法执行操作了。

这比让用户可以执行remove操作,然后跑出异常,警告访问被拒绝要友好得多。

上面第二部分的xml定义全文如下,applicationContext-security-acl.xml:

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:util="http://www.springframework.org/schema/util"
    xmlns:sec="http://www.springframework.org/schema/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/util
    http://www.springframework.org/schema/util/spring-util.xsd
    http://www.springframework.org/schema/security
    http://www.springframework.org/schema/security/spring-security-3.0.4.xsd">
    <bean id="aclCache" class="org.springframework.security.acls.domain.EhCacheBasedAclCache">
        <constructor-arg ref="aclEhCache"/>
    </bean>
    <bean id="aclEhCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
        <property name="cacheManager" ref="cacheManager"/>
        <property name="cacheName" value="aclCache"/>
    </bean>
    <bean id="lookupStrategy" class="org.springframework.security.acls.jdbc.BasicLookupStrategy">
        <constructor-arg ref="dataSource"/>
        <constructor-arg ref="aclCache"/>
        <constructor-arg>
            <bean class="org.springframework.security.acls.domain.AclAuthorizationStrategyImpl">
                <constructor-arg>
                    <list>
                        <ref local="adminRole"/>
                        <ref local="adminRole"/>
                        <ref local="adminRole"/>
                    </list>
                </constructor-arg>
            </bean>
        </constructor-arg>
        <constructor-arg>
            <bean class="org.springframework.security.acls.domain.ConsoleAuditLogger"/>
        </constructor-arg>
    </bean>
    <bean id="adminRole" class="org.springframework.security.core.authority.GrantedAuthorityImpl">
        <constructor-arg value="ROLE_ADMIN"/>
    </bean>
    <bean id="aclService" class="org.springframework.security.acls.jdbc.JdbcMutableAclService">
        <constructor-arg ref="dataSource"/>
        <constructor-arg ref="lookupStrategy"/>
        <constructor-arg ref="aclCache"/>
        <property name="classIdentityQuery" value="SELECT @@IDENTITY"/>
		<property name="sidIdentityQuery" value="SELECT @@IDENTITY"/>	
    </bean>
    <bean id="aclMessageDeleteVoter" class="org.springframework.security.acls.AclEntryVoter">
        <constructor-arg ref="aclService"/>
        <constructor-arg value="ACL_MESSAGE_DELETE"/>
        <constructor-arg>
            <list>
                <util:constant static-field="org.springframework.security.acls.domain.BasePermission.ADMINISTRATION"/>
                <util:constant static-field="org.springframework.security.acls.domain.BasePermission.DELETE"/>
            </list>
        </constructor-arg>
        <property name="processDomainObjectClass" value="net.kentop.acl.object.Message"></property>
    </bean>
    <bean id="aclAccessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
        <property name="decisionVoters">
            <list>
                <bean class="org.springframework.security.access.vote.RoleVoter"/>
                <ref local="aclMessageDeleteVoter"/>
            </list>
        </property>
    </bean>
</beans>

 

三、该例子的项目文件:

(1)要操作的类:Message.java:

 

package net.kentop.acl.object;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class Message implements Serializable {
    private Long id;
    private String message;
    private String owner;
    private Date createDate;
    private Date updateDate;
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public String getOwner() {
        return owner;
    }
    public void setOwner(String owner) {
        this.owner = owner;
    }
    public Date getCreateDate() {
        return createDate;
    }
    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }
    public Date getUpdateDate() {
        return updateDate;
    }
    public void setUpdateDate(Date updateDate) {
        this.updateDate = updateDate;
    }
}

 

MessageService.java

 

package net.kentop.acl.object;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.springframework.security.access.annotation.Secured;
import org.springframework.security.acls.domain.BasePermission;
import org.springframework.security.acls.domain.GrantedAuthoritySid;
import org.springframework.security.acls.domain.ObjectIdentityImpl;
import org.springframework.security.acls.domain.PrincipalSid;
import org.springframework.security.acls.model.MutableAcl;
import org.springframework.security.acls.model.MutableAclService;
import org.springframework.security.acls.model.ObjectIdentity;
import org.springframework.transaction.annotation.Transactional;
public class MessageService {
    private List<Message> list = new ArrayList<Message>();
    private MutableAclService mutableAclService;
    public void setMutableAclService(MutableAclService mutableAclService) {
        this.mutableAclService = mutableAclService;
    }
    @Secured({"ROLE_USER", "AFTER_ACL_READ"})
    public Message get(Long id) {
        for (Message message : list) {
            if (message.getId().equals(id)) {
                return message;
            }
        }
        return null;
    }
    @Secured({"ROLE_USER", "AFTER_ACL_COLLECTION_READ"})
    public List getAll() {
        return list;
    }
    @Transactional
    @Secured("ROLE_USER")
    public void save(String messageContent, String owner) {
        Message message = new Message();
        message.setId(System.currentTimeMillis());
        message.setMessage(messageContent);
        message.setOwner(owner);
        message.setCreateDate(new Date());
        message.setUpdateDate(new Date());
        list.add(message);
        ObjectIdentity oid = new ObjectIdentityImpl(Message.class,
                message.getId());
        MutableAcl acl = mutableAclService.createAcl(oid);
        acl.insertAce(0, BasePermission.ADMINISTRATION,
            new PrincipalSid(owner), true);
        acl.insertAce(1, BasePermission.DELETE,
            new GrantedAuthoritySid("ROLE_ADMIN"), true);
        acl.insertAce(2, BasePermission.READ,
            new GrantedAuthoritySid("ROLE_USER"), true);
        mutableAclService.updateAcl(acl);
    }
    public void update(Long id, String messageContent) {
        Message message = this.get(id);
        message.setMessage(messageContent);
        message.setUpdateDate(new Date());
    }
    public void removeById(Long id) {
        Message message = this.get(id);
        this.remove(message);
    }
    @Transactional
    @Secured("ACL_MESSAGE_DELETE")
    public void remove(Message message) {
        list.remove(message);
        ObjectIdentity oid = new ObjectIdentityImpl(Message.class,
                message.getId());
        mutableAclService.deleteAcl(oid, false);
    }
}

 MessageServlet.java:

 

package net.kentop.servlet;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.kentop.acl.object.Message;
import net.kentop.acl.object.MessageService;
import org.springframework.context.ApplicationContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.web.context.support.WebApplicationContextUtils;
public class MessageServlet extends HttpServlet {
    private MessageService messageService;
    private MessageService getMessageService() {
        if (messageService == null) {
            ApplicationContext ctx = WebApplicationContextUtils
                .getWebApplicationContext(this.getServletContext());
            messageService = (MessageService) ctx.getBean("messageService");
        }
        return messageService;
    }
    public void doGet(HttpServletRequest request,
        HttpServletResponse response) throws IOException, ServletException {
        try {
            process(request, response);
        } catch (Exception ex) {
            throw new ServletException(ex);
        }
    }
    public void doPost(HttpServletRequest request,
        HttpServletResponse response) throws IOException, ServletException {
        try {
            process(request, response);
        } catch (Exception ex) {
            throw new ServletException(ex);
        }
    }
    public void process(HttpServletRequest request,
        HttpServletResponse response) throws Exception {
        String action = request.getParameter("action");
        if ("view".equals(action)) {
            this.view(request, response);
        } else if ("list".equals(action)) {
            this.list(request, response);
        } else if ("save".equals(action)) {
            this.save(request, response);
        } else if ("update".equals(action)) {
            this.update(request, response);
        } else if ("remove".equals(action)) {
            this.remove(request, response);
        } else if ("create".equals(action)) {
            this.create(request, response);
        } else if ("edit".equals(action)) {
            this.edit(request, response);
        } else {
            System.out.println("Unkown Action: " + action);
        }
    }
    public void view(HttpServletRequest request,
        HttpServletResponse response) throws Exception {
        Long id = Long.valueOf(request.getParameter("id"));
        Message message = getMessageService().get(id);
        request.setAttribute("message", message);
        request.getRequestDispatcher("/message-view.jsp")
               .forward(request, response);
    }
    public void list(HttpServletRequest request,
        HttpServletResponse response) throws Exception {
        List<Message> list = getMessageService().getAll();
        request.setAttribute("list", list);
        request.getRequestDispatcher("/message-list.jsp")
               .forward(request, response);
    }
    public void save(HttpServletRequest request,
        HttpServletResponse response) throws Exception {
        String message = request.getParameter("message");
        UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext()
                                                                     .getAuthentication()
                                                                     .getPrincipal();
        String username = userDetails.getUsername();
        getMessageService().save(message, username);
        response.sendRedirect("message.do?action=list");
    }
    public void update(HttpServletRequest request,
        HttpServletResponse response) throws Exception {
        Long id = Long.valueOf(request.getParameter("id"));
        String message = request.getParameter("message");
        getMessageService().update(id, message);
        response.sendRedirect("message.do?action=list");
    }
    public void remove(HttpServletRequest request,
        HttpServletResponse response) throws Exception {
        Long id = Long.valueOf(request.getParameter("id"));
        getMessageService().removeById(id);
        response.sendRedirect("message.do?action=list");
    }
    public void create(HttpServletRequest request,
        HttpServletResponse response) throws Exception {
        request.getRequestDispatcher("/message-edit.jsp")
               .forward(request, response);
    }
    public void edit(HttpServletRequest request,
        HttpServletResponse response) throws Exception {
        Long id = Long.valueOf(request.getParameter("id"));
        Message message = getMessageService().get(id);
        request.setAttribute("message", message);
        request.getRequestDispatcher("/message-edit.jsp")
               .forward(request, response);
    }
}
 

(2)web.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<!--
  - Tutorial web application
  -
  -->
<web-app 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>acltest</display-name>
  
   <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext-*.xml</param-value>
    </context-param>
    <filter>
        <filter-name>springSecurityFilterChain</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>springSecurityFilterChain</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <servlet>
        <servlet-name>MessageServlet</servlet-name>
        <servlet-class>net.kentop.servlet.MessageServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>MessageServlet</servlet-name>
        <url-pattern>/message.do</url-pattern>
    </servlet-mapping>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>
 

(3)jsp文件:

message_list.jsp:

 

<%@page contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<c:set var="ctx" value="${pageContext.request.contextPath}" />
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<title>list</title>
</head>
<body>
<table width="100%">
	<tr>
		<td><a href="message.do?action=create" mce_href="message.do?action=create">Create Message</a></td>
		<td align="right">username: <sec:authentication property="name" />
		| <a href="j_spring_security_logout" mce_href="j_spring_security_logout">logout</a></td>
	</tr>
</table>
<hr>
<table border="1" width="100%">
	<tr>
		<th>ID</th>
		<th>Message</th>
		<th>Owner</th>
		<th>Create Date</th>
		<th>Update Date</th>
		<th>Operation</th>
	</tr>
	<c:forEach var="item" items="${list}">
		<tr>
			<td>${item.id} </td>
			<td>${item.message} </td>
			<td>${item.owner} </td>
			<td><fmt:formatDate pattern="yyyy-MM-dd HH:mm:ss"
				value="${item.createDate}" /> </td>
			<td><fmt:formatDate pattern="yyyy-MM-dd HH:mm:ss"
				value="${item.updateDate}" /> </td>
			<td><a href="message.do?action=view&id=${item.id}" mce_href="message.do?action=view&id=${item.id}">View</a> | <a
				href="message.do?action=edit&id=${item.id}">Update</a> <sec:accesscontrollist
				domainObject="${item}" hasPermission="8,16">
          |
          <a href="message.do?action=remove&id=${item.id}" mce_href="message.do?action=remove&id=${item.id}">Remove</a>
			</sec:accesscontrollist></td>
		</tr>
	</c:forEach>
</table>
</body>
</html>
 

message_edit.jsp:

 

<%@page contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
    <title>edit</title>
  </head>
  <body>
    <table width="100%">
      <tr>
        <td><a href="message.do?action=list" mce_href="message.do?action=list">Back</a></td>
        <td align="right">
          username: <sec:authentication property="name"/>
          |
          <a href="j_spring_security_logout" mce_href="j_spring_security_logout">logout</a>
        </td>
      </tr>
    </table>
    <hr>
    <fieldset>
      <legend>Message Info</legend>
      <form method="post" action="message.do?action=${param.action == 'create' ? 'save' : 'update'}">
        <input type="hidden" name="id" value="${message.id}">
        <table>
          <tr>
            <td>Message:</td>
            <td><input type="text" name="message" value="${message.message}"></td>
          </tr>
          <tr>
            <td colspan="2">
              <input type="submit">
              <input type="reset">
            </td>
          </tr>
        </table>
      </form>
    </fieldset>
  </body>
</html>

 

message_view.jsp:

 

<%@page contentType="text/html;charset=UTF-8"%>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<c:set var="ctx" value="${pageContext.request.contextPath}"/>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
    <title>view</title>
  </head>
  <body>
    <table width="100%">
      <tr>
        <td><a href="message.do?action=list" mce_href="message.do?action=list">Back</a></td>
        <td align="right">
          username: <sec:authentication property="name"/>
          |
          <a href="j_spring_security_logout" mce_href="j_spring_security_logout">logout</a>
        </td>
      </tr>
    </table>
    <hr>
    <fieldset>
      <legend>Message Info</legend>
      <table>
        <tr>
          <td>ID:</td>
          <td>${message.id}</td>
        </tr>
        <tr>
          <td>Message:</td>
          <td>${message.message}</td>
        </tr>
        <tr>
          <td>Owner:</td>
          <td>${message.owner}</td>
        </tr>
        <tr>
          <td>Create Date:</td>
          <td><fmt:formatDate pattern="yyyy-MM-dd HH:mm:ss" value="${message.createDate}"/></td>
        </tr>
        <tr>
          <td>Update Date:</td>
          <td><fmt:formatDate pattern="yyyy-MM-dd HH:mm:ss" value="${message.updateDate}"/></td>
        </tr>
      </table>
    </fieldset>
  </body>
</html>
 

四、整个项目的下载地址如下:

http://download.csdn.net/source/2851702

分享到:
评论
6 楼 zhcheng 2013-01-10  
我就是按照你这个配置的,别的地方都没有问题,只有在使用标签的时候总是报错。
java.lang.NullPointerException
org.springframework.security.taglibs.authz.AccessControlListTag.doStartTag(AccessControlListTag.java:92)

<sec:accesscontrollist domainObject="${item }" hasPermission="8">

版本是3.1.3
这是怎么个情况啊。
5 楼 bhdweb 2012-09-16  
项目中的角色名是死的?直接用户注解写在方法上? 
4 楼 孙露威 2011-07-30  
学习了 支持楼主
3 楼 zhuchao_ko 2011-02-11  
哥们 用到哪些JAR能说下吗 。。。
2 楼 zhuchao_ko 2011-02-11  
整理了下脚本:

select * from acl_sid
drop table acl_sid

CREATE TABLE acl_sid (
  id bigint(20) NOT NULL AUTO_INCREMENT,
  principal tinyint(1) NOT NULL,
  sid varchar(100) NOT NULL,
  PRIMARY KEY (id),
  UNIQUE KEY unique_uk_1 (sid,principal)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

select * from acl_class
drop table acl_class
CREATE TABLE acl_class (
  id bigint(20) NOT NULL AUTO_INCREMENT,
  class varchar(100) NOT NULL,
  PRIMARY KEY (id),
  UNIQUE KEY unique_uk_2 (class)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;


select * from acl_object_identity
drop table acl_object_identity
CREATE TABLE acl_object_identity (
  id bigint(20) NOT NULL AUTO_INCREMENT,
  object_id_class bigint(20) NOT NULL,
  object_id_identity bigint(20) NOT NULL,
  parent_object bigint(20) DEFAULT NULL,
  owner_sid bigint(20) NOT NULL,
  entries_inheriting tinyint(1) NOT NULL,
  PRIMARY KEY (id),
  UNIQUE KEY unique_uk_3 (object_id_class,object_id_identity),
  KEY foreign_fk_1 (parent_object),
  KEY foreign_fk_3 (owner_sid),
  CONSTRAINT acl_object_identity_ibfk_1 FOREIGN KEY (parent_object) REFERENCES acl_object_identity (id),
  CONSTRAINT acl_object_identity_ibfk_2 FOREIGN KEY (object_id_class) REFERENCES acl_class (id),
  CONSTRAINT acl_object_identity_ibfk_3 FOREIGN KEY (owner_sid) REFERENCES acl_sid (id)
)

CREATE TABLE acl_entry (
  id bigint(20) NOT NULL AUTO_INCREMENT,
  acl_object_identity bigint(20) NOT NULL,
  ace_order int(11) NOT NULL,
  sid bigint(20) NOT NULL,
  mask int(11) NOT NULL,
  granting tinyint(1) NOT NULL,
  audit_success tinyint(1) NOT NULL,
  audit_failure tinyint(1) NOT NULL,
  PRIMARY KEY (id),
  UNIQUE KEY unique_uk_4 (acl_object_identity,ace_order),
  KEY foreign_fk_5 (sid),
  CONSTRAINT acl_entry_ibfk_1 FOREIGN KEY (acl_object_identity) REFERENCES acl_object_identity (id),
  CONSTRAINT acl_entry_ibfk_2 FOREIGN KEY (sid) REFERENCES acl_sid (id)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
1 楼 bingki 2011-01-28  
严重: Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'aclCache' defined in file [G:\apache-tomcat-6.0.18\webapps\acltest\WEB-INF\classes\applicationContext-security-acl.xml]: Cannot resolve reference to bean 'aclEhCache' while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'aclEhCache' defined in file [G:\apache-tomcat-6.0.18\webapps\acltest\WEB-INF\classes\applicationContext-security-acl.xml]: Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: net/sf/ehcache/Ehcache

相关推荐

    Spring_Security-3.0.1_中文自学教程.pdf

    Spring Security 3.0.1 是基于 Spring Security 3.0 的一个 bug fix 版本,主要修复了 3.0 中已知的问题,并对文档中的一些拼写错误进行了修正。 ##### 1.4 如何获取 Spring Security - **项目模块**:Spring ...

    Spring Security 3.0.1 pdf 中文参考文档

    - **ACL (spring-security-acl.jar):** 访问控制列表支持。 - **CAS (spring-security-cas-client.jar):** 集成 CAS 单点登录系统的客户端。 - **OpenID (spring-security-openid.jar):** 支持 OpenID 身份...

    工业自动化中基于威纶通触摸屏的水箱液位PID控制仿真程序设计与实现

    内容概要:本文详细介绍了如何利用威纶通触摸屏及其配套软件EasyBuilder Pro构建一个水箱液位控制的PID仿真程序。主要内容涵盖触摸屏界面设计、PID算法实现、通信配置以及仿真模型搭建等方面。文中不仅提供了具体的代码示例,还分享了许多调试经验和优化技巧,如抗积分饱和处理、通信同步设置等。此外,作者还强调了实际应用中的注意事项,例如参数范围限制、突发情况模拟等。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是对PID控制器有一定了解并希望深入掌握其实际应用的人群。 使用场景及目标:适用于需要进行水箱液位控制系统设计、调试和优化的工作环境。主要目标是帮助读者理解和掌握PID控制的基本原理及其在实际工程项目中的具体实现方法。 其他说明:附带完整的工程文件可供下载,便于读者快速上手实践。文中提到的所有代码片段均经过实际验证,确保可靠性和实用性。

    2024年中国城市低空经济发展指数报告

    内容概要:《2024年中国城市低空经济发展指数报告》由36氪研究院发布,指出低空经济作为新质生产力的代表,已成为中国经济新的增长点。报告从发展环境、资金投入、创新能力、基础支撑和发展成效五个维度构建了综合指数评价体系,评估了全国重点城市的低空经济发展状况。北京和深圳在总指数中名列前茅,分别以91.26和84.53的得分领先,展现出强大的资金投入、创新能力和基础支撑。低空经济主要涉及无人机、eVTOL(电动垂直起降飞行器)和直升机等产品,广泛应用于农业、物流、交通、应急救援等领域。政策支持、市场需求和技术进步共同推动了低空经济的快速发展,预计到2026年市场规模将突破万亿元。 适用人群:对低空经济发展感兴趣的政策制定者、投资者、企业和研究人员。 使用场景及目标:①了解低空经济的定义、分类和发展驱动力;②掌握低空经济的主要应用场景和市场规模预测;③评估各城市在低空经济发展中的表现和潜力;④为政策制定、投资决策和企业发展提供参考依据。 其他说明:报告强调了政策监管、产业生态建设和区域融合错位的重要性,提出了加强法律法规建设、人才储备和基础设施建设等建议。低空经济正加速向网络化、智能化、规模化和集聚化方向发展,各地应找准自身比较优势,实现差异化发展。

    多智能体协同编队控制:无人机编队背后的Python实现与关键技术解析

    内容概要:本文详细介绍了多智能体协同编队控制的技术原理及其Python实现。首先通过生动形象的例子解释了编队控制的核心概念,如一致性算法、虚拟结构法、预测补偿等。接着深入探讨了编队形状的设计方法,包括如何利用虚拟结构法生成特定编队形状,并讨论了通信质量和参数调试的重要性。此外,还涉及了避障策略、动态权重分配以及故障检测等实际应用中的挑战和解决方案。最后,通过具体实例展示了如何将理论应用于实际项目中,如无人机编队表演、自动驾驶车队等。 适用人群:对多智能体系统、编队控制感兴趣的科研人员、工程师及高校师生。 使用场景及目标:适用于研究和开发多智能体协同编队控制系统的场景,旨在帮助读者理解并掌握相关技术和实现方法,提高系统的稳定性和可靠性。 其他说明:文中不仅提供了详细的代码示例,还分享了许多实践经验和技术细节,有助于读者更好地理解和应用这些技术。同时强调了参数调试、通信质量、预测补偿等方面的关键因素对于系统性能的影响。

    四旋翼飞行器模型预测控制(MPC)的Matlab实现及其设定点收敛保证

    内容概要:本文详细介绍了名为'MPC_ACC_2020-master'的四旋翼飞行器模型预测跟踪控制器(Matlab实现)。四旋翼飞行器由于其高度非线性和强耦合特性,在复杂环境中难以实现精准控制。模型预测控制(MPC)通过预测未来状态并在每一步进行在线优化,解决了这一难题。文中展示了关键代码片段,解释了系统参数定义、初始化、预测模型构建、成本函数构建、优化求解及控制输入的应用。此外,还探讨了MPC_ACC_2020-master如何通过精心设计的成本函数和优化算法确保四旋翼飞行器状态收敛到设定点。 适合人群:从事飞行器控制领域的研究人员和技术爱好者,尤其是对模型预测控制感兴趣的开发者。 使用场景及目标:适用于四旋翼飞行器的轨迹跟踪任务,旨在提高飞行器在复杂环境下的稳定性与准确性。具体应用场景包括但不限于无人机竞速、自动巡航、物流配送等。 其他说明:尽管该项目主要用于科研目的,但其简洁高效的代码结构也为实际工程应用提供了良好借鉴。同时,项目中存在一些待改进之处,如状态估计部分未考虑真实情况下的噪声干扰,后续版本计划移植到C++并集成进ROS系统。

    基于MATLAB2020b的CNN-LSTM与GTO算法优化的电力负荷预测研究

    内容概要:本文探讨了基于MATLAB2020b平台,采用CNN-LSTM模型结合人工大猩猩部队(GTO)算法进行电力负荷预测的方法。首先介绍了CNN-LSTM模型的基本结构及其在处理多变量输入(如历史负荷和气象数据)方面的优势。随后详细解释了如何通过GTO算法优化超参数选择,提高模型预测精度。文中展示了具体的MATLAB代码示例,包括数据预处理、网络层搭建、训练选项设定等方面的内容,并分享了一些实践经验和技术细节。此外,还讨论了模型的实际应用效果,特别是在某省级电网数据上的测试结果。 适合人群:从事电力系统数据分析的研究人员、工程师,以及对深度学习应用于时间序列预测感兴趣的开发者。 使用场景及目标:适用于需要精确预测未来电力负荷的情况,旨在帮助电力公司更好地规划发电计划,优化资源配置,保障电网安全稳定运行。通过本研究可以学习到如何构建高效的CNN-LSTM模型,并掌握利用GTO算法进行超参数优化的具体步骤。 其他说明:文中提到的一些技巧和注意事项有助于避免常见错误,提高模型性能。例如,合理的数据预处理方式、适当的超参数范围设定等都能显著改善最终的预测效果。

    机器学习(深度学习):用于脑肿瘤的带有边界框的磁共振成像

    数据集一个高质量的医学图像数据集,专门用于脑肿瘤的检测和分类研究以下是关于这个数据集的详细介绍:该数据集包含5249张脑部MRI图像,分为训练集和验证集。每张图像都标注了边界框(Bounding Boxes),并按照脑肿瘤的类型分为四个类别:胶质瘤(Glioma)、脑膜瘤(Meningioma)、无肿瘤(No Tumor)和垂体瘤(Pituitary)。这些图像涵盖了不同的MRI扫描角度,包括矢状面、轴面和冠状面,能够全面覆盖脑部解剖结构,为模型训练提供了丰富多样的数据基础。高质量标注:边界框是通过LabelImg工具手动标注的,标注过程严谨,确保了标注的准确性和可靠性。多角度覆盖:图像从不同的MRI扫描角度拍摄,包括矢状面、轴面和冠状面,能够全面覆盖脑部解剖结构。数据清洗与筛选:数据集在创建过程中经过了彻底的清洗,去除了噪声、错误标注和质量不佳的图像,保证了数据的高质量。该数据集非常适合用于训练和验证深度学习模型,以实现脑肿瘤的检测和分类。它为开发医学图像处理中的计算机视觉应用提供了坚实的基础,能够帮助研究人员和开发人员构建更准确、更可靠的脑肿瘤诊断系统。这个数据集为脑肿瘤检测和分类的研究提供了宝贵的资源,能够帮助研究人员开发出更准确、更高效的诊断工具,从而为脑肿瘤患者的早期诊断和治疗规划提供支持。

    STM32F103 CAN通讯与IAP升级Bootloader源码解析及硬件设计

    内容概要:本文详细介绍了STM32F103的CAN通讯和IAP升级Bootloader的源码实现及其硬件设计。首先,针对CAN通讯部分,文章深入探讨了CAN外设的初始化配置,包括波特率、位时间、过滤器等重要参数的设置方法,并提供了一段完整的初始化代码示例。接着,对于IAP升级Bootloader,文中讲解了通过CAN总线接收HEX文件并写入Flash的具体实现步骤,以及如何安全地从Bootloader跳转到应用程序。此外,文章还附上了原理图和PCB文件,有助于理解和优化硬件设计。最后,作者分享了一些实用的调试技巧和注意事项,如终端电阻的正确使用、CRC校验的应用等。 适合人群:嵌入式系统开发者、硬件工程师、从事STM32开发的技术人员。 使用场景及目标:适用于正在开发STM32相关项目的工程师,尤其是那些需要实现CAN通讯和固件在线升级功能的人群。通过学习本文提供的源码和技术要点,可以帮助他们快速掌握相关技能,提高开发效率。 其他说明:本文不仅提供了详细的代码示例,还包含了丰富的实践经验分享,能够帮助读者更好地理解和解决实际开发中遇到的问题。

    全能屏幕录像工具,支持语音、监控、摄像头、画笔等多功能源码

    工具集语音、监控、摄像头、画笔等功能于一体!清晰语音录入,确保声画同步;监控级画面录制,操作细节无遗漏;摄像头多视角呈现,让内容更生动。录制时,画笔可标注重点,快速传递关键信息。自带视频播放,无需第三方;快捷键操作便捷,录制高效。强大解码器兼容多格式,不同设备随心播放。无论是教学、办公还是创作

    西门子S7-1500 PLC在制药厂洁净空调BMS系统中的温湿度精准控制与优化

    内容概要:本文详细介绍了西门子S7-1500 PLC在制药厂洁净空调建筑管理系统(BMS)中的应用案例。重点讨论了硬件配置(1500 CPU + ET200SP分布式IO)、温湿度控制策略(串级PID、分程调节)、以及具体的编程实现(SCL语言)。文中分享了多个技术细节,如PT100温度采集、PID控制算法优化、报警管理和HMI界面设计等。此外,作者还提到了一些调试过程中遇到的问题及其解决方案,如PID_Compact块的手动模式设定值跳变问题、博图V15.1的兼容性问题等。 适合人群:从事工业自动化领域的工程师和技术人员,特别是那些对PLC编程、温湿度控制和洁净空调系统感兴趣的读者。 使用场景及目标:适用于制药厂或其他对温湿度控制要求严格的行业。主要目标是确保洁净空调系统的高效运行,将温湿度波动控制在极小范围内,保障生产环境的安全性和稳定性。 其他说明:本文不仅提供了详细的编程代码和硬件配置指南,还分享了许多实践经验,帮助读者更好地理解和应用相关技术。同时,强调了在实际项目中需要注意的关键点和潜在问题。

    2025年6G近场技术白皮书2.0.pdf

    2025年6G近场技术白皮书2.0.pdf

    少儿编程scratch项目源代码文件案例素材-Frogeon.zip

    少儿编程scratch项目源代码文件案例素材-Frogeon.zip

    2025年感知技术十大趋势深度分析报告.pdf

    2025年感知技术十大趋势深度分析报告.pdf

    Matlab实现车间调度问题遗传算法(JSPGA):源码解析与应用

    内容概要:本文详细介绍了一种用于解决车间调度问题的遗传算法(Matlab实现),即JSPGA。文章首先介绍了遗传算法的基本概念及其在车间调度问题中的应用场景。接着,作者展示了完整的Matlab源码,包括参数设置、种群初始化、选择、交叉、变异、适应度计算以及结果输出等模块。文中还特别强调了适应度计算方法的选择,采用了最大完工时间的倒数作为适应度值,并通过三维甘特图和迭代曲线直观展示算法性能。此外,文章提供了多个调参技巧和改进方向,帮助读者更好地理解和应用该算法。 适合人群:对遗传算法感兴趣的研究人员、工程师以及希望深入理解车间调度问题求解方法的技术爱好者。 使用场景及目标:适用于需要优化多台机器、多个工件加工顺序与分配的实际工业生产环境。主要目标是通过遗传算法找到最优或近似最优的调度方案,从而减少最大完工时间,提高生产效率。 其他说明:文章不仅提供了详细的理论解释和技术细节,还包括了大量实用的代码片段和图表,使读者能够轻松复现实验结果。同时,作者还分享了一些个人经验和建议,为后续研究提供了有价值的参考。

    永磁同步电机MTPA控制算法及其Simulink仿真模型设计与实现

    内容概要:本文深入探讨了永磁同步电机(PMSM)的最大转矩电流比(MTPA)控制算法,并详细介绍了基于Simulink的仿真模型设计。首先,文章阐述了PMSM的数学模型,包括电压方程和磁链方程,这是理解控制算法的基础。接着,解释了矢量控制原理,通过将定子电流分解为励磁电流和转矩电流分量,实现对电机的有效控制。随后,重点讨论了MTPA控制的目标和方法,即在限定电流条件下最大化转矩输出。此外,文章还涉及了前馈补偿、弱磁控制和SVPWM调制等关键技术,提供了具体的实现代码和仿真思路。最后,通过一系列实验验证了各控制策略的效果。 适合人群:从事电机控制系统设计的研究人员和技术人员,尤其是对永磁同步电机和Simulink仿真感兴趣的工程师。 使用场景及目标:适用于希望深入了解PMSM控制算法并在Simulink环境中进行仿真的技术人员。主要目标是掌握MTPA控制的核心原理,学会构建高效的仿真模型,优化电机性能。 其他说明:文中不仅提供了详细的理论推导,还有丰富的代码示例和实践经验,有助于读者快速理解和应用相关技术。同时,强调了实际工程中常见的问题及解决方案,如负载扰动、弱磁控制和SVPWM调制等。

    基于Matlab的三机并联风光储混合系统仿真及关键技术解析

    内容概要:本文详细介绍了三机并联的风光储混合系统在Matlab中的仿真方法及其关键技术。首先,针对光伏阵列模型,讨论了其核心二极管方程以及MPPT(最大功率点跟踪)算法的应用,强调了环境参数对输出特性的影响。接着,探讨了永磁同步风机的矢量控制,尤其是转速追踪和MPPT控制策略。对于混合储能系统,则深入讲解了超级电容和蓄电池的充放电策略,以及它们之间的协调机制。此外,还涉及了PQ控制的具体实现,包括双闭环结构的设计和锁相环的优化。最后,提供了仿真过程中常见的问题及解决方案,如求解器选择、参数敏感性和系统稳定性等。 适合人群:从事电力电子、新能源系统设计与仿真的工程师和技术人员,以及相关专业的研究生。 使用场景及目标:适用于希望深入了解风光储混合系统工作原理的研究人员,旨在帮助他们掌握Matlab仿真技巧,提高系统设计和优化的能力。 其他说明:文中不仅提供了详细的理论推导和代码示例,还分享了许多实践经验,有助于读者更好地理解和应用所学知识。

    亚洲电子商务发展案例研究

    本书由国际发展研究中心(IDRC)和东南亚研究院(ISEAS)联合出版,旨在探讨亚洲背景下电子商务的发展与实践。IDRC自1970年起,致力于通过科学技术解决发展中国家的社会、经济和环境问题。书中详细介绍了IDRC的ICT4D项目,以及如何通过项目如Acacia、泛亚网络和泛美项目,在非洲、亚洲和拉丁美洲推动信息通信技术(ICTs)的影响力。特别强调了IDRC在弥合数字鸿沟方面所作出的贡献,如美洲连通性研究所和非洲连通性项目。ISEAS作为东南亚区域研究中心,专注于研究该地区的发展趋势,其出版物广泛传播东南亚的研究成果。本书还收录了电子商务在亚洲不同国家的具体案例研究,包括小型工匠和开发组织的电子商务行动研究、通过互联网直接营销手工艺品、电子营销人员的创新方法以及越南电子商务发展的政策影响。

    2025工业5G终端设备发展报告.pdf

    2025工业5G终端设备发展报告.pdf

    Java经典面试笔试题及答案

    内容概要:本文档《Java经典面试笔试题及答案.docx》涵盖了广泛的Java基础知识和技术要点,通过一系列面试题的形式,深入浅出地讲解了Java的核心概念。文档内容包括但不限于:变量的声明与定义、对象序列化、值传递与引用传递、接口与抽象类的区别、继承的意义、方法重载的优势、集合框架的结构、异常处理机制、线程同步、泛型的应用、多态的概念、输入输出流的使用、JVM的工作原理等。此外,还涉及了诸如线程、GUI事件处理、类与接口的设计原则等高级主题。文档不仅解释了各个知识点的基本概念,还提供了实际应用场景中的注意事项和最佳实践。 适合人群:具备一定Java编程基础的学习者或开发者,特别是准备参加Java相关岗位面试的求职者。 使用场景及目标:①帮助读者巩固Java基础知识,提升对Java核心技术的理解;②为面试做准备,提供常见面试题及其详细解答;③指导开发者在实际项目中应用Java的最佳实践,优化代码质量和性能。 其他说明:文档内容详实,涵盖了Java开发中的多个方面,从基础语法到高级特性均有涉及。建议读者在学习过程中结合实际编程练习,加深对各个知识点的理解和掌握。同时,对于复杂的概念和技术,可以通过查阅官方文档或参考书籍进一步学习。

Global site tag (gtag.js) - Google Analytics