`
dmh920
  • 浏览: 18766 次
  • 性别: Icon_minigender_1
  • 来自: 湖南
社区版块
存档分类
最新评论

浅析Digester

    博客分类:
  • JAVA
阅读更多

         最近在看tomcat源代码,发现tomcat的xml文件都是通过Digester解析自动生成了对象,于是对Digester研究了下,为了防止自己忘记便记录下来。首先通过一个小程序来了解Digester,解析下面的school.xml文件:

<?xml version="1.0" encoding="UTF-8"?>  
<school name="xx大学" address="xx省xx市">  
    <department description="计算机系">  
        <student name="小明" sex="男"/>  
        <student name="小红" sex="女"/>  
        <student name="小王" sex="男"/>  
    </department>  
    <department description="数学系">  
        <student name="小李" sex="男"/>  
        <student name="小新" sex="男"/>  
        <student name="小赵" sex="女"/>  
    </department>  
</school>
public class DigesterForSchool {  
    public static void main(String[] args) throws Exception{  
        String path = System.getProperty("user.dir") + File.separator + "etc";  
        Digester digester = new Digester();  
        digester.addObjectCreate("school", "com.test.digester.School");  
        digester.addSetProperties("school");  
        digester.addObjectCreate("school/department", "com.test.digester.Department");  
        digester.addSetProperties("school/department");  
        digester.addSetNext("school/department", "addDepartment");  
        digester.addObjectCreate("school/department/student",  
                "com.test.digester.Student");  
        digester.addSetNext("school/department/student", "addStudent");  
        digester.addSetProperties("school/department/student");  
        School school = (School)digester.parse(new File(path, "school.xml"));  
        System.out.println(school);  
    }  
}

输出结果如下:

school name: xx大学, address: xx省xx市

departments: [

department description: 计算机系

students: [

student name: 小明 sex: 男, 

student name: 小红 sex: 女, 

student name: 小王 sex: 男], 

department description: 数学系

students: [

student name: 小李 sex: 男, 

student name: 小新 sex: 男, 

student name: 小赵 sex: 女]]

        可以发现Digester将school.xml文件的内容,转换为了相对应的对象。那Digester到底是怎样工作的呢?查看Digester源代码我们发现:

import org.xml.sax.XMLReader;  
public class Digester extends DefaultHandler

        原来Digester是SAX解析器事件处理类DefaultHandler的子类,我们知道SAX是基于事件驱动解析xml文件,当SAX扫描到文档(document)开始、元素(element)开始与结束、文档(document)结束等地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。所以Digester在事件处理函数中做了相应的处理,让其能按照自己的规则生成对象数据。现在来看看Digester在事件处理函数中做了哪些处理:

public void startElement( String namespaceURI, String localName, String qName, Attributes list ) throws SAXException {
	...
	List<Rule> rules = getRules().match( namespaceURI, match, localName, list );
        matches.push( rules );
	...
	for ( int i = 0; i < rules.size(); i++ ) {
		...
		Rule rule = rules.get(i);
                rule.begin( namespaceURI, name, list );
		...	
	}
}
public void characters( char buffer[], int start, int length ) throws SAXException {
	...
	bodyText.append( buffer, start, length );
}
public void endElement( String namespaceURI, String localName, String qName ) throws SAXException {
	...
	List<Rule> rules = matches.pop();
	...
        for ( int i = 0; i < rules.size(); i++ ) {
                ....
                Rule rule = rules.get( i );
                ....
                rule.body( namespaceURI, name, bodyText );
        }
        ...
        for ( int i = 0; i < rules.size(); i++ ) {
                ....
                Rule rule = rules.get( i );
                ....
                rule.end( namespaceURI, name, bodyText );
        }
        ....
}

         在执行startElement()方法和endElement()方法的时候都用到Rule类的相关方法,现在再看看api中对Rule类的描述:Concrete implementations of this class implement actions to be taken when a corresponding nested pattern of XML elements has been matched. 当匹配到xml某个模式时,Rule的具体实现类的动作将被执行。在解析xml文档时,当Digester实例匹配到某个模式的元素开始标签时,调用相对应的Rule对象的begin方法(见startElement()方法),当匹配到相应元素的结束标签时,调用Rule对象的body()和end()方法(见endElement()方法)。当Digester类可以包含0个或多个Rule对象。在Digester实例中,这些规则和其相关联的模式都存储在Rules接口表示的一类集合中。每当把一条规则添加到Digester实例中时,Rule对象也都会被添加到Rules对象中。当调用addObjectCreate()、addCallMethod()方法、addSetNext()方法或其他方法时,都会间接调用Digester类的addRule()方法。该方法会将一个Rule对象和它所匹配的模式添加到Digester对象的Rules集合中。 

public void addObjectCreate( String pattern, String className ) {   
        addRule( pattern, new ObjectCreateRule( className ) );  
}  
public void addRule( String pattern, Rule rule ) {  
        rule.setDigester( this );  
        getRules().add( pattern, rule );  
}  
public Rules getRules() {  
        if ( this.rules == null ) {  
            this.rules = new RulesBase();  
            this.rules.setDigester( this );  
        }  
        return ( this.rules );  
}

      Digester已经预定义了一些规则,可以直接使用这些规则,如果这些规则仍然不满足需求,可以实现自己的规则,常用的预定义规则如下:

1.创建对象:

        ObjectCreateRule:利用指定类的默认构造函数。创建该类的一个对象,并把对象压入栈,当元素处理结束时,对象被弹出。
        FactoryCreateRule:利用指定的工厂类创建一个对象,用于处理没有提供默认构造函数的类。注意的是用于该规则的工厂类必须实现org.apache.commons.digester.ObjectCreationFactory接口。
2.设置属性:
        SetPropertiesRule:利用指定名称的XML元素属性值,设置顶层Bean的属性。
        BeanPropertySetterRule:把顶层Bean的指定名称的属性设置成当前XML元素包含的字符数据。(通常用来处理<element>10</element>之类的结构)。
        SetPropertyRule:设置顶层Bean的一个属性。无论是Bean属性的名称,还是赋予该属性的值,都在当前XML元素中以属性的形式指定,例如:<student key="age" value="10" />。
3.对象之间关系:
        SetNextRule:peek出栈顶对象和栈顶下一个对象,将栈顶对象作为参数传递给栈顶下一个元素。
        SetTopRule:把栈顶下一个对象传递给顶层对象。
        SetRootRule:调用栈底对象的一个方法,并把栈顶的对象作为参数传入。
4.调用方法:
        CallMethodRule:调用顶层Bean的指定名称的方法。被调用的方法可以有任意多个参数,参数的值通过后继的CallParamRule给出。
        CallParamRule:表示方法调用的参数。参数的值或者取自指定名称的XML元素的属性,或者是当前元素包含的原始字符数据。这个规则要求用一个整数指定它在参数列表中的位置。

      Digester实例内部维护着一个用于临时存储创建对象的栈和一个临时存储参数的栈(这个栈主要是用于CallMethodRule和CallParamRule使用,可以自行查阅源代码),如果实现自己的Rule时使用到了Digester中的栈,在begin()方法中,将一个Object push进去,一定要记得在end()方法中pop出来。Rule的api也说道:If a rule wishes to manipulate a digester stack (the default object stack, a named stack, or the parameter stack) then it should only ever push objects in the rule's begin method and always pop exactly the same number of objects off the stack during the rule's end method. Of course peeking at the objects on the stacks can be done from anywhere. 那现在我们来实现一个自定义规则,将上面的xml文件的student元素修改下命名为school2.xml:

<?xml version="1.0" encoding="UTF-8"?>  
<school name="xx大学" address="xx省xx市">  
    <department id="1" description="计算机系">  
        <student name="小明" sex="男" birthday="1990-01-01 00:00:00"/>  
        <student name="小红" sex="女" birthday="1991-01-01 00:00:00"/>  
        <student name="小王" sex="男" birthday="1992-01-01 00:00:00"/>  
    </department>  
    <department id="2" description="数学系">  
        <student name="小李" sex="男" birthday="1990-01-02 00:00:00"/>  
        <student name="小新" sex="男" birthday="1991-01-02 00:00:00"/>  
        <student name="小赵" sex="女" birthday="1992-01-02 00:00:00"/>  
    </department>  
</school>

        student元素新增了一个属性"birthday",在Student类中新增了一个成员变量Date型的birthday,这时在给birthday属性赋值时就不能直接调用addSetProperties()方法了,因为从xml解析到的birthday是string类型的数据,如果直接调用addSetProperties()方法会抛出类型转换异常,所以写了一个新的设置属性规则和一个将字符串日期类型转换为Date型数据的规则,代码如下:

public class SetAllPropertiesRule extends Rule {
	protected Map<String,String> excludes = new HashMap<String,String>();
    
	public SetAllPropertiesRule() {}

	/**
	 * 构造一个SetAllPropertiesRule
	 * @param exclude 不需要设置属性值的属性名数组
	 */
	public SetAllPropertiesRule(String[] exclude) {
             for (int i=0; i<exclude.length; i++ ) {
        	if (exclude[i]!=null) { 
        		this.excludes.put(exclude[i],exclude[i]);
        	}
             }
        }
	
	@Override
	public void begin(String namespace, String name, Attributes attributes)
			throws Exception {
		Map<String, String> values = new HashMap<String, String>();
		for (int i = 0; i < attributes.getLength(); i++) {
			String attributeName = attributes.getLocalName(i);
                        if ("".equals(attributeName)) {
                            attributeName = attributes.getQName(i);
                        }
                        String value = attributes.getValue(i);
                        if (!excludes.containsKey(attributeName)){
            	            values.put(attributeName, value );
                        }
		}
		populate(getDigester().peek(), values);
	}
}
public class ConvertStringToDateRule extends Rule {
	private SimpleDateFormat format = null;;
	
	private String attributeName = null;
	
	/**
	 * 构造一个ConvertStringToDateRule
	 * @param pattern 需要转换的字符串日期格式
	 */
	public ConvertStringToDateRule(String pattern) {
		this(pattern, null);
	}
	
	/**
	 * 构造一个ConvertStringToDateRule
	 * @param pattern 需要转换的字符串日期格式
	 * @param attributeName 需要转换的元素属性名,如果为null则将元素间的字符串转换,
         * 如:</element>2012-01-01 00:00:00</element>
	 */
	public ConvertStringToDateRule(String pattern, String attributeName) {
		this.attributeName = attributeName;
		format = new SimpleDateFormat(pattern);
	}
	
	@Override
	public void begin(String namespace, String name, Attributes attributes)
			throws Exception {
		if(attributeName == null) {
			return;
		}
		String str = attributes.getValue(attributeName);
		Date date = format.parse(str); 
		getDigester().push(date);
	}
	
	@Override
	public void body(String namespace, String name, String text)
			throws Exception {
		if(attributeName == null) {
			Date date = format.parse(text);
			getDigester().push(date);
		}
	}
	
	@Override
	public void end(String namespace, String name) throws Exception {
		getDigester().pop();
	}
}
public class DigesterForSchool2 {
	public static void main(String[] args) throws Exception {
		String path = System.getProperty("user.dir") + File.separator + "etc";
		Digester digester = new Digester();
		digester.addObjectCreate("school", "com.test.digester.school2.School");
		digester.addSetProperties("school");
		digester.addObjectCreate("school/department",
				"com.test.digester.school2.Department");
		digester.addSetProperties("school/department");
		digester.addSetNext("school/department", "addDepartment");
		digester.addObjectCreate("school/department/student",
				"com.test.digester.school2.Student");
		digester.addSetNext("school/department/student", "addStudent");
		digester.addRule("school/department/student", new SetAllPropertiesRule(
				new String[] { "birthday" }));
		digester.addRule("school/department/student",
				new ConvertStringToDateRule("yyyy-MM-dd hh:mm:ss", "birthday"));
		digester.addSetNext("school/department/student", "setBirthday");
		School school = (School) digester.parse(new File(path, "school2.xml"));
		System.out.println(school);
	}
} 

输出结果如下:

school name: xx大学 address: xx省xx市

departments: [

department id: 1 description: 计算机系

students: [

student name: 小明 sex: 男 birthday: Mon Jan 01 00:00:00 CST 1990, 

student name: 小红 sex: 女 birthday: Tue Jan 01 00:00:00 CST 1991, 

student name: 小王 sex: 男 birthday: Wed Jan 01 00:00:00 CST 1992], 

department id: 2 description: 数学系

students: [

student name: 小李 sex: 男 birthday: Tue Jan 02 00:00:00 CST 1990, 

student name: 小新 sex: 男 birthday: Wed Jan 02 00:00:00 CST 1991, 

student name: 小赵 sex: 女 birthday: Thu Jan 02 00:00:00 CST 1992]]

 

 

分享到:
评论

相关推荐

    基于vue的菜谱网站,前端采用vue,后端采用express,数据库采用mysql。.zip-毕设&课设&实训&大作业&竞赛&项目

    项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行,功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用

    数据分析全流程指南:从基础知识到实战项目的Python&R生态应用

    内容概要:本文档提供了关于数据分析全面的知识介绍与实战资源链接。首先,在数据分析的基础教程部分讲述了使用Python以及R两种语言来进行实际的数据分析工作所需具备的各项基本技能。其次,进阶教程涵盖从机器学习到深度学习的概念及其Python具体应用场景。接着,在工具有效利用层面介绍了多种热门库与平台的作用特点。在项目实践中,列举了四个实战案例:Titanic幸存者预测、房价预测、社交媒体情感倾向分析以及市场顾客购买模式研究,每个项目都有详细的技术流程指引。另外列出多个外部网站资源供进一步提升学习。 适用人群:本文主要面向有志于从事数据挖掘工作的学生和技术爱好者,同时也可辅助在职人士自我能力进阶。无论是在学术科研还是实际业务需求环境中都值得研读。 使用场景及目标:学习者将能够获取到系统的理论知识体系,熟悉业界主流软件包的功能优势,掌握具体业务问题解决方案路径,提高自身的综合技术素质,从而为个人职业规划增添竞争力。 其他说明:文档里推荐了不少高质量参考资料和实用线上学习社区,能有效补充专业知识空白并促进社交协作交流。

    从埃安泰国工厂竣工看中国车企加快海外建厂步伐.pptx

    从埃安泰国工厂竣工看中国车企加快海外建厂步伐.pptx

    复现改进的L-SHADE差分进化算法求解最优化问题详解:附MATLAB源码与测试函数集,复现改进的L-SHADE差分进化算法求解最优化问题详解:MATLAB源码与测试集全攻略,复现改进的L-SHADE

    复现改进的L-SHADE差分进化算法求解最优化问题详解:附MATLAB源码与测试函数集,复现改进的L-SHADE差分进化算法求解最优化问题详解:MATLAB源码与测试集全攻略,复现改进的L-SHADE差分进化算法求最优化问题 对配套文献所提出的改进的L-SHADE差分进化算法求解最优化问题的的复现,提供完整MATLAB源代码和测试函数集,到手可运行,运行效果如图2所示。 代码所用测试函数集与文献相同:对CEC2014最优化测试函数集中的全部30个函数进行了测试验证,运行结果与文献一致。 ,复现; 改进的L-SHADE差分进化算法; 最优化问题求解; MATLAB源代码; 测试函数集; CEC2014最优化测试函数集,复现改进L-SHADE算法:最优化问题的MATLAB求解与验证

    DCDC 电阻分压计算器

    可选择参考电压与输出电压 可选择电阻精度以及输出电压误差值

    西门子博途三部十层电梯程序案例解析:基于Wincc RT Professional V14及更高版本的应用探索,西门子博途三部十层电梯程序案例解析:基于Wincc RT Professional画面与

    西门子博途三部十层电梯程序案例解析:基于Wincc RT Professional V14及更高版本的应用探索,西门子博途三部十层电梯程序案例解析:基于Wincc RT Professional画面与V14及以上版本技术参考,西门子1200博途三部十层电梯程序案例,加Wincc RT Professional画面三部十层电梯程序,版本V14及以上。 程序仅限于参考资料使用。 ,西门子;1200博途;三部十层电梯程序案例;Wincc RT Professional;V14以上程序版本。,西门子V14+博途三部十层电梯程序案例:Wincc RT Pro专业画面技术解析

    2023政务大数据解决方案.pptx

    2023政务大数据解决方案.pptx

    基于SSM设计的校园二手物品交易网站

    项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行;功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用

    基于java的学业跟踪评价系统设计的详细项目实例(含完整的程序,GUI设计和代码详解)

    内容概要:本文介绍了基于Java的学业跟踪评价系统的详细设计与实现,涵盖系统的多维度数据整合与评价、智能化学习建议、数据可视化和实时反馈等方面。系统通过收集课堂表现、作业成绩、考试成绩等多源数据,对学生的学业表现进行全面跟踪和评价,提供可视化反馈以及个性化的学习建议,促进家校互动,助力学生全面素质提升和发展。 适合人群:具备一定Java编程经验的研究者和开发者,特别是从事教育信息化领域的从业人员和技术爱好者。 使用场景及目标:该系统主要用于K12教育阶段、高等教育以及其他涉及教育培训的场景。其目的是提高教育管理效率、推进教育数字化转型和个人化教育实施。 其他说明:该文档详细介绍了系统的设计思路、功能模块和技术细节,并提供了完整的程序代码以及GUI设计说明。对于希望深入了解或实际部署学业跟踪评价系统的机构非常有参考价值。文中强调技术创新与实践经验相结合,突出了实用性和前瞻性特点。

    基于vue实现的WebAPP.zip

    项目工程资源经过严格测试运行并且功能上ok,可实现复现复刻,拿到资料包后可实现复现出一样的项目,本人系统开发经验充足(全栈全领域),有任何使用问题欢迎随时与我联系,我会抽时间努力为您解惑,提供帮助 【资源内容】:包含源码+工程文件+说明等。答辩评审平均分达到96分,放心下载使用!可实现复现;设计报告也可借鉴此项目;该资源内项目代码都经过测试运行;功能ok 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 【提供帮助】:有任何使用上的问题欢迎随时与我联系,抽时间努力解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 下载后请首先打开说明文件(如有);整理时不同项目所包含资源内容不同;项目工程可实现复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用

    rabbmit相关安装包

    erlang安装包,rabbmit安装环境

    linux 下的oracle数据库的开机启动脚本

    linux 下的oracle数据库的开机启动脚本,将里面的/home/oracle/app/oracle/product/11.2.0/dbhome_1 都改成你的oracle数据库的路径。在root用户下chmod +x 添加执行权限,然后./oracle_setup.sh 执行即可。

    基于目标级联分析法的多微网主动配电系统自治优化经济调度算法实现与初级应用,基于目标级联分析法的多微网主动配电系统自治优化经济调度算法实践:初级拉格朗日算法应用,GAMS代码:基于目标级联分析法的多微网

    基于目标级联分析法的多微网主动配电系统自治优化经济调度算法实现与初级应用,基于目标级联分析法的多微网主动配电系统自治优化经济调度算法实践:初级拉格朗日算法应用,GAMS代码:基于目标级联分析法的多微网主动配电系统自治优化经济调度 该代码并非完全复现该文献,而是参照文献 《基于目标级联分析法的多微网主动配电系统自治优化经济调度》 的目标级联分析法(ATC)的算法部分,采用初级的拉格朗日算法,主网与配网部分模型较为简化。 代码结构完整,注释详细,可读性较强,可以在此基础上进行修改或者移植。 适用于初学者学习ATC模型 ,GAMS代码;目标级联分析法(ATC);微网主动配电系统;自治优化经济调度;拉格朗日算法;主网与配网模型简化;代码结构完整;注释详细;可读性强;初学者学习ATC模型。,基于ATC算法的GAMS多微网经济调度优化代码:简化版学习指南

    基于ISODATA改进算法的负荷场景曲线聚类-适用于风光场景生成的高效算法创新,基于ISODATA改进算法的负荷场景曲线聚类(适用于风光场景生成,包含K-means等多种聚类方法与效果评价),基于I

    基于ISODATA改进算法的负荷场景曲线聚类——适用于风光场景生成的高效算法创新,基于ISODATA改进算法的负荷场景曲线聚类(适用于风光场景生成,包含K-means等多种聚类方法与效果评价),基于ISODATA改进算法的负荷场景曲线聚类(适用于风光场景生成) 摘要:代码主要做的是一种基于改进ISODATA算法的负荷场景曲线聚类,代码中,主要做了四种聚类算法,包括基础的K-means算法、ISODATA算法、L-ISODATA算法以及K-L-ISODATA算法,并且包含了对聚类场景以及聚类效果的评价,通过DBI的计算值综合对比评价不同方法的聚类效果,程序实现效果非常好,适合对于算法创新有需求的人,且也包含基础的k-means算法,用来学习也非常棒 另外,此代码同样适用于风光场景生成,自己准备好风光场景数据即可 代码非常精品,有部分注释; ,核心关键词: 1. 基于ISODATA改进算法 2. 负荷场景曲线聚类 3. K-means算法 4. 聚类场景评价 5. 聚类效果评价 6. DBI计算值 7. 算法创新需求 8. 风光场景生成 以上关键词用分号分隔为: 1. 基于ISO

    xpack-qemu-arm-8.2.2-1-win32-x64.zip

    xPack qemu arm 是一款高性能且跨平台的 ARM 架构虚拟机

    莫理莉+AI+为新型能源系统赋能-技术与建筑建筑供配电论坛琶洲.pptx

    莫理莉+AI+为新型能源系统赋能-技术与建筑建筑供配电论坛琶洲.pptx

    学生毕业离校系统(源码+数据库+论文+ppt)java开发springboot框架javaweb,可做计算机毕业设计或课程设计

    学生毕业离校系统(源码+数据库+论文+ppt)java开发springboot框架javaweb,可做计算机毕业设计或课程设计 【功能需求】 本系统分为学生、教师、管理员3个角色 (1)学生功能需求 学生进入系统可以查看首页、个人中心、离校流程、网站公告、费用结算管理、论文审核管理、我的收藏管理等操作。 (2)教师功能需求 教师进入系统可以查看首页、学生管理、离校流程管理、费用结算管理、论文审核管理等操作。 (2)管理员功能需求 管理员登陆后,主要功能模块包括首页、个人中心、学生管理、教师管理、离校信息管理、费用结算管理、论文审核管理、管理员管理、留言板管理、系统管理等功能。 【环境需要】 1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境:IDEA,Eclipse,Myeclipse都可以。 3.tomcat环境:Tomcat 7.x,8.x,9.x版本均可 4.数据库:MySql 5.7/8.0等版本均可; 【购买须知】 本源码项目经过严格的调试,项目已确保无误,可直接用于课程实训或毕业设计提交。里面都有配套的运行环境软件,讲解视频,部署视频教程,一应俱全,可以自己按照教程导入运行。附有论文参考,使学习者能够快速掌握系统设计和实现的核心技术。

    揭秘 OpenAI 在 2027 年前创建 AGI 的计划.pptx

    揭秘 OpenAI 在 2027 年前创建 AGI 的计划.pptx

    单极双极调制下,线路阻抗不匹配时两台单相逆变器并联的离散仿真模型研究,单极双极调制下,线路阻抗不匹配时单相逆变器Simulink并联仿真模型研究,单相逆变器Simulink并联离散仿真模型,输入电压4

    单极双极调制下,线路阻抗不匹配时两台单相逆变器并联的离散仿真模型研究,单极双极调制下,线路阻抗不匹配时单相逆变器Simulink并联仿真模型研究,单相逆变器Simulink并联离散仿真模型,输入电压400V,单台逆变器功率为2000W,使用下垂控制方案,在线路阻抗不匹配的情况下,实现两台逆变器并联。 可以选调制方案为单极性调制或者双极性调制。 离散模型,功率均分效果,两台逆变器输出电压和电流波形如下图。 ,核心关键词:单相逆变器; Simulink; 并联离散仿真模型; 输入电压400V; 单台功率2000W; 下垂控制方案; 线路阻抗不匹配; 调制方案; 单极性调制; 双极性调制; 功率均分效果。,离散仿真模型下,单相逆变器并联研究——400V输入、2000W功率均分实现

Global site tag (gtag.js) - Google Analytics