ML Schema 是基于 XML 的 DTD 替代者。
XML Schema 可描述 XML 文檔的結構。
XML Schema 語言也可作為 XSD(XML Schema Definition)來引用。
您應當具備的基礎知識
在繼續學習之前,您需要對下面的知識有基本的了解:
HTML / XHTML
XML 以及 XML 命名空間
對 DTD 的基本了解
如果您希望首先學習這些項目,請在 首頁 訪問這些教程。
什么是 XML Schema?
XML Schema 的作用是定義 XML 文檔的合法構建模塊,類似 DTD。
XML Schema:
定義可出現在文檔中的元素
定義可出現在文檔中的屬性
定義哪個元素是子元素
定義子元素的次序
定義子元素的數目
定義元素是否為空,或者是否可包含文本
定義元素和屬性的數據類型
定義元素和屬性的默認值以及固定值
XML Schema 是 DTD 的繼任者
我們認為 XML Schema 很快會在大部分網絡應用程序中取代 DTD。
理由如下:
XML Schema 可針對未來的需求進行擴展
XML Schema 更完善,功能更強大
XML Schema 基于 XML 編寫
XML Schema 支持數據類型
XML Schema 支持命名空間
XML Schema 是 W3C 標準
XML Schema 在 2001 年 5 月 2 日成為 W3C 標準。
本人總是愛忘記這個約束,說實話不是太難,因此想寫這篇文章詳細記錄下,希望對有同樣需要的小伙伴能夠提供幫助。
Xml約束主要有兩種:
dtd約束比較簡單,小伙伴們可以自行查詢,我主要介紹一下schema約束。
為什么會有schema約束了,對于dtd約束,它只是對標簽中的數據類型進行了一個約束,并不能對標簽的數據內容進行一個約束。因此才有了scheme約束。
dtd約束文件都以.dtd結尾,scheme約束文件都以.xsd結尾。
先來看一下student.xsd文件。
<?xml version="1.0"?>
# xmlns這樣寫就是要給你的下面targetNamespace取別名比如xmlns:a,我這里什么都沒寫表示不取別名
# 這個后面如何根據Schema約束寫xml可以能清晰的理解下
<xsd:schema xmlns="http://www.JHLoveCoding.cn/xml"
# 自定義schema也需要導入一個約束,這個約束的命名空間就是URL,取了一個別名叫xsd,所以可以看
# 到所有下面標簽都寫了xsd前綴
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
# targetNamespace自定義一個命名空間,規定該schema下所有的標簽都屬于這個這個命名空間下
# elementFormDefault="qualified" 表示要引用這個命名空間必須加前綴
targetNamespace="http://www.JHLoveCoding.cn/xml" elementFormDefault="qualified">
# 這里type="studentsType"相當于自定義了一個類型,需要在下邊聲明下
<xsd:element name="students" type="studentsType"/>
# 這里聲明了 studentsType 聲明一個類型用的是xsd:complexType如果你需要經常寫xml約束可以具體了解
# 一下,不經常寫知道這么個東西就行了
<xsd:complexType name="studentsType">
# sequence 表示在寫xml內容時,里面標簽的內容必須與其在xsd這里面聲明的<xsd:element/>順序要一致
# 我這只寫了一個student,可以寫多個,要是要多個,注意在寫xml時,注意與這里保持一致,可以往下看
# 你就明白了
<xsd:sequence>
# 這里又自定義一個studentType類型,下面會有聲明,其中 minOccurs="0"表示至少出現0次,
# maxOccurs="unbounded"這種寫法表示最多無上限的
<xsd:element name="student" type="studentType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
# 聲明的 studentsType類型結束,下面聲明過程一樣的。
</xsd:complexType>
<xsd:complexType name="studentType">
<xsd:sequence>
# 這里可以看到自帶的支持類型都是type="xsd:string"像這樣聲明的
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="age" type="ageType" />
<xsd:element name="sex" type="sexType" />
</xsd:sequence>
# 相當于給studentType添加一個自定義的屬性,比如像name這樣的就是屬性
<xsd:attribute name="number" type="numberType" use="required"/>
</xsd:complexType>
# xsd:simpleType 定義一個簡單類型, xml約束如果你只是為了能看懂,這些足夠了。創作不易,喜歡的小伙伴麻煩記得點下關注+點贊+轉發!用來規定和約束具有純文本內容的元素(不含子元素即為具有純文
# 本內容的元素)或屬性的值,不懂沒關系,如果你需要經常寫xml約束可以具體了解一下,不經常寫知道這
# 么個東西就行了
<xsd:simpleType name="sexType">
# 對sexType內容取值做一個限制,其必須是一個字符串類型
<xsd:restriction base="xsd:string">
# 進一步約束,除了滿足字符串之外還得滿足枚舉類型。
<xsd:enumeration value="male"/>
<xsd:enumeration value="female"/>
</xsd:restriction>
# 聲明一個簡單類型結束標志
</xsd:simpleType>
<xsd:simpleType name="ageType">
# 聲明ageType必須是一個整型
<xsd:restriction base="xsd:integer">
# 除了滿足整型之外還需要滿足最大值為256,最小值是0
<xsd:minInclusive value="0"/>
<xsd:maxInclusive value="256"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="numberType">
<xsd:restriction base="xsd:string">
# 除了滿足是上面要求的字符串意外還要滿足JH_4個數字的要求
<xsd:pattern value="JH_\d{4}"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
根據這個約束我們就可以根據這些約束來寫一個scheme要求xml約束。
<!--
1.填寫xml文檔的根元素 這里就是<students> </students>
2.引入xsi前綴. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 這個是通用的做法,有很多不同的URL命名可見可供選擇,xsi就是取的別名
3.引入xsd文件命名空間. xsi:schemaLocation="http://www.JHLoveCoding.cn/xml student.xsd",教你讀這句話,意思就是在xsi這個命名空間下去找schemaLocation這個屬性(肯定是屬性,因為它寫在了標簽上),對這個屬性進行賦值,賦值的內容就是后面的URL
4.為每一個xsd約束聲明一個前綴,作為標識 xmlns="http://www.JHLoveCoding.cn/xml" ,首先為什么要有這個前綴的,因為比如我們下面的xml中有兩個<student><student/>標簽,而我們又引入了多個schema的約束,碰巧引入的這些Schema約束中都有對<student>標簽做出說明,這個時候就需要引入加上命名空間了,告訴這個標簽屬于哪一個命名空間的約束了。由于我們這里就是一約束,故可以省略,要是多個約束為了防止沖突最好寫上。
-->
<students xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.JHLoveCoding.cn/xml"
# 這里http://www.itcast.cn/xml就是xsd文件中的targetNamespace,student.xsd就是上面的約束 # 文件的名字
xsi:schemaLocation="http://www.JHLoveCoding.cn/xml student.xsd"
>
<student number="JH_0001">
<name>tom</name>
<age>18</age>
<sex>male</sex>
</student >
</students>
看下邊這個例子也許你會更明白一些。這里引入了三個依賴
<?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.xsd">
從下邊的標簽也可以看出來,該標簽屬于哪個命名空間就會有前綴作為標識。
<context:annotation-config />
<context:component-scan base-package="cn.cisol.mvcdemo">
<context:include-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
<mvc:annotation-driven />
<mvc:resources mapping="/resources/**" location="/resources/" />
<bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="1" />
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
<entry key="htm" value="text/html" />
</map>
</property>
<property name="defaultViews">
<list>
<bean
class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
</bean>
</list>
</property>
<property name="ignoreAcceptHeader" value="true" />
</bean>
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsps/" />
<property name="suffix" value=".jsp" />
</bean>
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="209715200" />
<property name="defaultEncoding" value="UTF-8" />
<property name="resolveLazily" value="true" />
</bean>
</beans>
xml約束如果你只是為了能看懂,這些足夠了。創作不易,喜歡的小伙伴麻煩記得點下關注+點贊+轉發!
這可能是全網Java學習路線最完整,最詳細的版本了,沒有之一
Spring的出現是為了解決企業應用程序開發的復雜性 它是一個分層的、JavaSE/EE一站式、輕量級開源框架。
Spring框架是一個分層架構,它包含一系列的功能要素并被分為大約20個模塊。這些模塊分為Core Container、Data Access/Integration、Web、AOP(Aspect Oriented Programming)、Instrumentation和測試部分。
spring的兩個核心是 ioc 和 aop;
IoC(Inversion of Control 控制反轉):將對象創建的權利交給spring工廠來控制。
AOP(Aspect Oriented Programming 面向切面編程),基于動態代理的功能增強方式。
本章主要學習下ioc的內容;
第一步 : 創建工程導入jar 包。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>springTest</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.5.RELEASE</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
123456789101112131415161718192021222324252627282930313233343536373839
spring 有4個核心容器的jar 包 分別是Beans、Core、Context、SpEL這里我們只要引入spring-context依賴就足夠了。
添加log4j.properties文件放置到src/reources下。
log4j.rootLogger=INFO,A1
log4j.logger.org.apache=INFO
log4j.appender.A1.Target=System.err
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%c]-[%p] %m%n
1234567
ps:這里的日志等級可以改為debug的級別,這里為了簡便設置為info的級別,有需要可以自行更改。
接下來就是寫下的偽登錄業務;
快速寫下dao層和service層業務
package com.spring.quickTest;
public interface userDao {
public void queryUser();
}
12345678
package com.spring.quickTest;
public class UserDaoImpl implements userDao {
@Override
public void queryUser() {
System.out.println("用戶登錄了");
}
}
1234567891011
package com.spring.quickTest;
public interface UserService {
void login();
}
123456789
package com.spring.quickTest;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserServiceImpl implements UserService {
private userDao userDao;
public void setUserDao(com.spring.quickTest.userDao userDao) {
this.userDao=userDao;
}
@Override
public void login() {
System.out.println("準備登錄中");
// 1.傳統方法
// userDao userDao=new UserDaoImpl();
// userDao.queryUser();
// 2.自定義工廠
// userDao user=(userDao) new UserdaoFactory().getBean();
// user.queryUser();
// 3spring 工廠
// ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
// userDao userDao=(com.spring.quickTest.userDao) context.getBean("userDao");
userDao.queryUser();
}
}
12345678910111213141516171819202122232425262728293031
傳統方法下的代碼過于耦合;
例如:UserDao userDao=new UserDaoImpl();
如果要更換實現類,或者實現類換一個名字,此時代碼會報錯,必須要修改原來的業務代碼。
我們也可以通過反射的方法自定義一個bean工廠來實現代碼的解耦;
package com.spring.quickTest;
public class UserdaoFactory {
public Object getBean() {
try {
return Class.forName("com.spring.quickTest.UserDaoImpl").newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null ;
}
}
1234567891011121314151617181920
我們就可以通過自定義的工廠進行實例化,然后調用dao層的方法,避免了耦合。
接下來也可以通過spring的工廠來實現解耦;
寫好spring核心文件的配置文件applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<bean name="userDao" class="com.spring.quickTest.UserDaoImpl"/>
<bean name="UserService" class="com.spring.quickTest.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
</beans>
123456789101112
我們將dao層交給spring 工廠后發現還是不夠方便,就將service層也交給spring工廠來控制 ,將bean標簽下的 property進行依賴注入這樣我們只要聲明下成員變量后并進行set方法賦值就可以直接引用了,不需要在創建spring工廠了。
ps:
標簽說明: bean: spring工廠創建的一個對象(反射機制)
id/name:對象的名字,可以用來引用或者獲取對象, 一般為類名或接口名稱的首字母小寫
class:要創建的對象類型的類字符串,類名全路徑
注入對象
property 根據類中的setter方法進行屬性注入
name:setter方法的后綴小寫,比如setXxx 對應的name為xxx
ref:引用哪一個bean(對象),值為bean的id/name
import com.spring.quickTest.UserServiceImpl;
import com.spring.quickTest.UserService;
import com.spring.quickTest.UserdaoFactory;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class userTest {
@Test
public void test(){
// UserService service=new UserServiceImpl();
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
UserService service=(UserService) context.getBean("UserService");
service.login();
}
}
1234567891011121314151617
創建完測試類后運行成功。。。
感謝閱讀,三連是最大的支持!
*請認真填寫需求信息,我們會在24小時內與您取得聯系。