JavaWeb-06
JavaWeb-Dom4j技术及Schema 约束、Tomcat与Web程序结构
DOM4J及Schema
一、Dom4j解析(掌握)
DOM4J解析XML文档
a. Dom4j是一个简单、灵活的开放源代码的库。Dom4j是由早期开发JDOM的人分离出来而后独立开发的。与JDOM不同的是,dom4j使用接口和抽象基类,虽然Dom4j的API相对要复杂一些,但它提供了比JDOM更好的灵活性。
b. Dom4j是一个非常优秀的Java XML API,具有性能优异、功能强大和极易使用的特点。现在很多软件采用的Dom4j,例如Hibernate,包括sun公司自己的JAXM也用了Dom4j。
c. 使用Dom4j开发,需下载dom4j相应的jar文件。
document的方法:
elements() : 拿到节点的所有子节点
elements(String) : 拿到指定名字的所有的子节点
element(String) : 拿到指定名字的子节点
Element节点的方法:
setText() : 设置标签节点的内容
getTest() : 获得标签节点的内容
addAttibute(String name ,String value ) : 添加标签的属性
removeAttribute(String name) : 删除某个属性
book.xml
<?xml version="1.0" encoding="UTF-8"?>
<书架>
<书 ISBN="程序员">
<书名>葵花宝典</书名>
<作者>陈冠希</作者>
<售价>100</售价>
<批发价>60</批发价>
</书>
<书>
<书名>金瓶梅</书名>
<作者>阿娇</作者>
<售价>80</售价>
</书>
</书架>
Dom4j_parsexml.java
import java.io.FileOutputStream;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
//演示用Dom4j解析XML文件
public class Dom4j_parsexml {
public static void main(String[] args) throws Exception {
//创建dom4j解析器
SAXReader reader = new SAXReader() ;
//加载文档
Document document = reader.read("src/book.xml") ;
// test1(document) ;
// test2(document) ;
// test3(document) ;
// test4(document) ;
// test5(document) ;
// test6(document) ;
test7(document) ;
}
// 1、得到某个具体的节点内容 eg:获得金瓶梅的售价
public static void test1(Document document){
//获得根节点
Element root = document.getRootElement() ;
//拿到书的集合
List<Element> bookList = root.elements("书") ;
//获取金瓶梅的售价节点
Element el = bookList.get(1).element("售价") ;
//拿到售价节点的主体内容
System.out.println(el.getText());
}
// 2、遍历所有元素节点
public static void test2(Document document) {
treeWalk( document.getRootElement() );
}
public static void treeWalk(Element element) {
for ( int i = 0, size = element.nodeCount(); i < size; i++ ) {
Node node = element.node(i);
if ( node instanceof Element ) {
System.out.println(node.getName());
treeWalk( (Element) node );
}
}
}
// 3、修改某个元素节点的主体内容 eg:修改金瓶梅的价格为80
public static void test3(Document document) throws Exception{
//获得根节点
Element root = document.getRootElement() ;
//拿到书的集合
List<Element> bookList = root.elements("书") ;
//获取金瓶梅的售价节点
Element el = bookList.get(1).element("售价") ;
//修改主体内容
el.setText("80") ;
//将结果写回到硬盘
XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml")) ;
writer.write(document) ;
writer.close() ;
}
//
// 4、向指定元素节点中增加子元素节点 eg: 给葵花宝典的售价增加一个子节点: 会员价:50
public static void test4(Document document) throws Exception{
//获得根节点
Element root = document.getRootElement() ;
//拿到书的集合
List<Element> bookList = root.elements("书") ;
//获取葵花宝典的售价节点
Element el = bookList.get(0).element("售价") ;
//创建一个新的标签节点: 会员价
el.addElement("会员价").setText("50") ;
//将结果写回到硬盘
XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),OutputFormat.createPrettyPrint()) ;
writer.write(document) ;
writer.close() ;
}
5、向指定元素节点上增加同级元素节点 eg: 给葵花宝典的售价增加一个兄弟节点: 批发价:60
public static void test5(Document document) throws Exception{
//获得根节点
Element root = document.getRootElement() ;
//拿到书的集合
List<Element> bookList = root.elements("书") ;
//创建一个新的标签节点: 会员价
bookList.get(0).addElement("批发价").setText("50") ;
//将结果写回到硬盘
XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),OutputFormat.createPrettyPrint()) ;
writer.write(document) ;
writer.close() ;
}
6、删除指定元素节点 eg:删除会员价节点
public static void test6(Document document) throws Exception{
//获得根节点
Element root = document.getRootElement() ;
//拿到书的集合
List<Element> bookList = root.elements("书") ;
//获取葵花宝典的售价节点
Element el = bookList.get(0).element("售价") ;
//拿到会员价节点
Element hel = el.element("会员价") ;
//删除会员价
el.remove(hel) ;
//将结果写回到硬盘
XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),OutputFormat.createPrettyPrint()) ;
writer.write(document) ;
writer.close() ;
}
7、操作XML文件属性 eg: 给葵花宝典的书节点增加属性: ISBN ="黑马程序员"
public static void test7(Document document) throws Exception{
//获得根节点
Element root = document.getRootElement() ;
//拿到书的集合
List<Element> bookList = root.elements("书") ;
bookList.get(0).addAttribute("ISBN", "黑马程序员") ;
//将结果写回到硬盘
XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),OutputFormat.createPrettyPrint()) ;
writer.write(document) ;
writer.close() ;
}
}
XPath: 主要作用是获取某个节点的路径 。
基本的XPath语法类似于在一个文件系统中定位文件,如果路径以斜线 / 开始, 那么该路径就表示到一个元素的绝对路径
/AAA
选择根元素AAA
<AAA>
<BBB/>
<CCC/>
<BBB/>
<BBB/>
<DDD>
<BBB/>
</DDD>
<CCC/>
</AAA>
/AAA/CCC
选择AAA的所有CCC子元素
<AAA>
<BBB/>
<CCC/>
<BBB/>
<BBB/>
<DDD>
<BBB/>
</DDD>
<CCC/>
</AAA>
/AAA/DDD/BBB
选择AAA的子元素DDD的所有子元素
<AAA>
<BBB/>
<CCC/>
<BBB/>
<BBB/>
<DDD>
<BBB/>
</DDD>
<CCC/>
</AAA>
如果路径以双斜线 // 开头, 则表示选择文档中所有满足双斜线//之后规则的元素(无论层级关系)
//BBB
选择所有BBB元素
<AAA>
<BBB/>
<CCC/>
<BBB/>
<DDD>
<BBB/>
</DDD>
<CCC>
<DDD>
<BBB/>
<BBB/>
</DDD>
</CCC>
</AAA>
//DDD/BBB
选择所有父元素是DDD的BBB元素
<AAA>
<BBB/>
<CCC/>
<BBB/>
<DDD>
<BBB/>
</DDD>
<CCC>
<DDD>
<BBB/>
<BBB/>
</DDD>
</CCC>
</AAA>
星号 * 表示选择所有由星号之前的路径所定位的元素
/AAA/CCC/DDD/*
选择所有路径依附于/AAA/CCC/DDD的元素
<AAA>
<XXX>
<DDD>
<BBB/>
<BBB/>
<EEE/>
<FFF/>
</DDD>
</XXX>
<CCC>
<DDD>
<BBB/>
<BBB/>
<EEE/>
<FFF/>
</DDD>
</CCC>
<CCC>
<BBB>
<BBB>
<BBB/>
</BBB>
</BBB>
</CCC>
</AAA>
///*/BBB
选择所有的有3个祖先元素的BBB元素
<AAA>
<XXX>
<DDD>
<BBB/>
<BBB/>
<EEE/>
<FFF/>
</DDD>
</XXX>
<CCC>
<DDD>
<BBB/>
<BBB/>
<EEE/>
<FFF/>
</DDD>
</CCC>
<CCC>
<BBB>
<BBB>
<BBB/>
</BBB>
</BBB>
</CCC>
</AAA>
//*
选择所有元素
<AAA>
<XXX>
<DDD>
<BBB/>
<BBB/>
<EEE/>
<FFF/>
</DDD>
</XXX>
<CCC>
<DDD>
<BBB/>
<BBB/>
<EEE/>
<FFF/>
</DDD>
</CCC>
<CCC>
<BBB>
<BBB>
<BBB/>
</BBB>
</BBB>
</CCC>
</AAA>
方块号里的表达式可以进一步的指定元素, 其中数字表示元素在选择集里的位置, 而last()函数则表示选择集中的最后一个元素.
/AAA/BBB[1]
选择AAA的第一个BBB子元素
<AAA>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
</AAA>
/AAA/BBB[last()]
选择AAA的最后一个BBB子元素
<AAA>
<BBB/>
<BBB/>
<BBB/>
<BBB/>
</AAA>
//@id
选择所有的id属性
<AAA>
<BBB id = "b1"/>
<BBB id = "b2"/>
<BBB name = "bbb"/>
<BBB/>
</AAA>
//BBB[@id]
选择有id属性的BBB元素
<AAA>
<BBB id = "b1"/>
<BBB id = "b2"/>
<BBB name = "bbb"/>
<BBB/>
</AAA>
//BBB[@name]
选择有name属性的BBB元素
<AAA>
<BBB id = "b1"/>
<BBB id = "b2"/>
<BBB name = "bbb"/>
<BBB/>
</AAA>
//BBB[@*]
选择有任意属性的BBB元素
<AAA>
<BBB id = "b1"/>
<BBB id = "b2"/>
<BBB name = "bbb"/>
<BBB/>
</AAA>
//BBB[not(@*)]
选择没有属性的BBB元素
<AAA>
<BBB id = "b1"/>
<BBB id = "b2"/>
<BBB name = "bbb"/>
<BBB/>
</AAA>
属性的值可以被用来作为选择的准则, normalize-space函数删除了前部和尾部的空格, 并且把连续的空格串替换为一个单一的空格
//BBB[@id='b1']
选择含有属性id且其值为'b1'的BBB元素
<AAA>
<BBB id = "b1"/>
<BBB name = " bbb "/>
<BBB name = "bbb"/>
</AAA>
//BBB[@name='bbb']
选择含有属性name且其值为'bbb'的BBB元素
<AAA>
<BBB id = "b1"/>
<BBB name = " bbb "/>
<BBB name = "bbb"/>
</AAA>
//BBB[normalize-space(@name)='bbb']
选择含有属性name且其值(在用normalize-space函数去掉前后空格后)为'bbb'的BBB元素
<AAA>
<BBB id = "b1"/>
<BBB name = " bbb "/>
<BBB name = "bbb"/>
</AAA>
count()函数可以计数所选元素的个数
//*[count(BBB)=2]
选择含有2个BBB子元素的元素
<AAA>
<CCC>
<BBB/>
<BBB/>
<BBB/>
</CCC>
<DDD>
<BBB/>
<BBB/>
</DDD>
<EEE>
<CCC/>
<DDD/>
</EEE>
</AAA>
//[count()=2]
选择含有2个子元素的元素
<AAA>
<CCC>
<BBB/>
<BBB/>
<BBB/>
</CCC>
<DDD>
<BBB/>
<BBB/>
</DDD>
<EEE>
<CCC/>
<DDD/>
</EEE>
</AAA>
//[count()=3]
选择含有3个子元素的元素
<AAA>
<CCC>
<BBB/>
<BBB/>
<BBB/>
</CCC>
<DDD>
<BBB/>
<BBB/>
</DDD>
<EEE>
<CCC/>
<DDD/>
</EEE>
</AAA>
Dom4j_parseByXpathxml.java
import java.io.FileOutputStream;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
//演示用Dom4j解析XML文件
public class Dom4j_parseByXpathxml {
public static void main(String[] args) throws Exception {
//创建dom4j解析器
SAXReader reader = new SAXReader() ;
//加载文档
Document document = reader.read("src/book.xml") ;
// test1(document) ;
// test2(document) ;
// test3(document) ;
// test4(document) ;
// test5(document) ;
// test6(document) ;
test7(document) ;
}
// 1、得到某个具体的节点内容 eg:获得金瓶梅的售价
public static void test1(Document document){
//拿到金瓶梅的售价节点
Node node = document.selectSingleNode("/书架/书[2]/售价") ;
//拿到主体内容
System.out.println(node.getText()) ;
}
// 2、遍历所有元素节点
public static void test2(Document document) {
treeWalk( document.getRootElement() );
}
public static void treeWalk(Element element) {
for ( int i = 0, size = element.nodeCount(); i < size; i++ ) {
Node node = element.node(i);
if ( node instanceof Element ) {
System.out.println(node.getName());
treeWalk( (Element) node );
}
}
}
// 3、修改某个元素节点的主体内容 eg:修改金瓶梅的价格为80
public static void test3(Document document) throws Exception{
//获得金瓶梅的售价节点
Node node = document.selectSingleNode("/书架/书[2]/售价") ;
//修改主体内容
node.setText("80") ;
//将结果写回到硬盘
XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml")) ;
writer.write(document) ;
writer.close() ;
}
//
// 4、向指定元素节点中增加子元素节点 eg: 给葵花宝典的售价增加一个子节点: 会员价:50
public static void test4(Document document) throws Exception{
//拿到葵花宝典的书节点
Node node = document.selectSingleNode("//售价[1]") ;
//增加子节点
((Element)node).addElement("会员价").setText("50") ;
//将结果写回到硬盘
XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),OutputFormat.createPrettyPrint()) ;
writer.write(document) ;
writer.close() ;
}
// 5、向指定元素节点上增加同级元素节点 eg: 给葵花宝典的售价增加一个兄弟节点: 批发价:60
public static void test5(Document document) throws Exception{
//拿到葵花宝典的书节点
Node node = document.selectSingleNode("//书[1]") ;
((Element)node).addElement("批发价").setText("60") ;
//将结果写回到硬盘
XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),OutputFormat.createPrettyPrint()) ;
writer.write(document) ;
writer.close() ;
}
6、删除指定元素节点 eg:删除会员价节点
public static void test6(Document document) throws Exception{
//获得会员价节点
Node node = document.selectSingleNode("//会员价") ;
//父亲干掉儿子
node.getParent().remove(node) ;
//将结果写回到硬盘
XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),OutputFormat.createPrettyPrint()) ;
writer.write(document) ;
writer.close() ;
}
7、操作XML文件属性 eg: 给葵花宝典的书节点增加属性: ISBN ="黑马程序员"
public static void test7(Document document) throws Exception{
//获得葵花宝典书节点
Node node = document.selectSingleNode("//书[1]") ;
//增加属性
((Element)node).addAttribute("ISBN", "黑马程序员") ;
//将结果写回到硬盘
XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),OutputFormat.createPrettyPrint()) ;
writer.write(document) ;
writer.close() ;
}
}
之前DOM解析的练习Exam改造成DOM4J的版本:
exam.xml
<?xml version="1.0" encoding="UTF-8"?>
<exam>
<student examid="222" idcard="111">
<name>张三</name>
<location>沈阳</location>
<grade>89</grade>
</student>
<student examid="444" idcard="333">
<name>李四</name>
<location>大连</location>
<grade>97</grade>
</student>
</exam>
Student.java
public class Student {
private String name ;
private String location ;
private int grade ;
private String examid ;
private String idcard ;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public int getGrade() {
return grade;
}
public void setGrade(int grade) {
this.grade = grade;
}
public String getExamid() {
return examid;
}
public void setExamid(String examid) {
this.examid = examid;
}
public String getIdcard() {
return idcard;
}
public void setIdcard(String idcard) {
this.idcard = idcard;
}
@Override
public String toString() {
return "Student [name=" + name + ", location=" + location + ", grade="
+ grade + ", examid=" + examid + ", idcard=" + idcard + "]";
}
}
Dom4jUtils.java
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.dom4j.Document;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
//工具类
public class Dom4jUtils {
/**
* 获取文档树
* @return
*/
public static Document getDocument(){
//获取DOM4j解析器
try {
SAXReader reader = new SAXReader() ;
Document document = reader.read("src/exam.xml") ;
return document ;
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null ;
}
/**
* 将内存中的dom树写入硬盘
* @param document 内存中的dom树
*/
public static void write2xml(Document document){
try {
XMLWriter writer = new XMLWriter(new FileOutputStream("src/exam.xml"),OutputFormat.createPrettyPrint()) ;
writer.write(document) ;
writer.close() ;
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
IStudentDao.java
import com.heima.bean.Student;
import com.heima.utils.Dom4jUtils;
public interface IStudentDao {
/**
* 添加学生
* @param student 要添加的学生
* @return
*/
public boolean addStudent(Student student) ;
/**
* 通过准考证号查询学生
* @param examid 准考证号
* @return
*/
public Student findStudentByExamId(String examid) ;
/**
* 通过姓名删除学生
* @param name 学生的姓名
* @return
*/
public boolean deleteStudentByName(String name) ;
}
StudentDom4jImpl.java
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import com.heima.bean.Student;
import com.heima.dao.IStudentDao;
import com.heima.utils.Dom4jUtils;
public class StudentDom4jImpl implements IStudentDao {
@Override
public boolean addStudent(Student student) {
//加载文档
Document document = Dom4jUtils.getDocument() ;
//拿到根节点
Element root = document.getRootElement() ;
//添加新的节点
Element stuel = root.addElement("student").addAttribute("examid", student.getExamid())
.addAttribute("idcard", student.getIdcard()) ;
stuel.addElement("name").setText(student.getName()) ;
stuel.addElement("location").setText(student.getLocation()) ;
stuel.addElement("grade").setText(student.getGrade() + "") ;
//写回硬盘
Dom4jUtils.write2xml(document) ;
return true;
}
@Override
public Student findStudentByExamId(String examid) {
//加载文档
Document document = Dom4jUtils.getDocument() ;
//第一种方法:拿到所有的student
List<Element> list = document.selectNodes("//student") ;
//遍历
// for (int i = 0; i < list.size(); i++) {
// if(){
// }
// }
//第二种方法
//拿到需要的student节点
Node node = document.selectSingleNode("//student[@examid='" + examid + "']") ;
if(node != null){
//找到了,封装数据
Student s = new Student() ;
s.setExamid(examid) ;
s.setIdcard(node.valueOf("@idcard")) ;
s.setName(((Element)node).element("name").getText()) ;
s.setLocation(((Element)node).elementText("location")) ; //拿到子节点的名字叫location的节点的主体内容
s.setGrade(Integer.parseInt(((Element)node).element("grade").getText())) ;
return s ;
}
return null;
}
@Override
public boolean deleteStudentByName(String name) {
//加载文档
Document document = Dom4jUtils.getDocument() ;
//拿到所有的name节点
List<Element> list = document.selectNodes("//name") ;
//循环判断
for (int i = 0; i < list.size(); i++) {
if(list.get(i).getText().equals(name)){
//找到了
//爷爷干掉父亲
Element el = list.get(i) ;
el.getParent().getParent().remove(el.getParent()) ;
//写回硬盘
Dom4jUtils.write2xml(document) ;
return true ;
}
}
return false;
}
}
StudentView.java
import java.util.Scanner;
import com.heima.bean.Student;
import com.heima.dao.IStudentDao;
import com.heima.dao.StudentDao;
import com.heima.dao.impl.StudentDom4jImpl;
public class StudentView {
static Scanner scan = new Scanner(System.in) ;
//static StudentDao dao = new StudentDao() ;
static IStudentDao dao = new StudentDom4jImpl() ;
public static void main(String[] args) {
System.out.println(" 添加学生 (a) 查询学生 (b) 删除学生 (c) ");
System.out.println("请选择操作:");
String op = scan.next() ;
if("a".equalsIgnoreCase(op)){
//添加学生
boolean flag = addStudent() ;
if(flag)
System.out.println("添加成功");
else
System.out.println("添加失败");
}else if("b".equalsIgnoreCase(op)){
//查询学生
Student s = findStudentByExamId() ;
if(s != null)
System.out.println(s);
else
System.out.println("查无此人");
}else if("c".equalsIgnoreCase(op)){
//删除学生
boolean flag = deleteStudentByName() ;
if(flag)
System.out.println("删除成功");
else
System.out.println("删除失败");
}
}
private static boolean deleteStudentByName() {
System.out.println("请输入学生姓名: ");
String name = scan.next() ;
//直接调用dao完成业务逻辑
return dao.deleteStudentByName(name);
}
private static Student findStudentByExamId() {
System.out.println("请输入准考证号:");
String examid = scan.next() ;
//调用dao完成业务逻辑
return dao.findStudentByExamId(examid);
}
private static boolean addStudent() {
System.out.println("请输入姓名:");
String name = scan.next() ;
System.out.println("请输入身份证号:");
String idcard = scan.next() ;
System.out.println("请输入准考证号:");
String examid = scan.next() ;
System.out.println("请输入地址:");
String location = scan.next() ;
System.out.println("请输入分数:");
String grade = scan.next() ;
//封装数据
Student s = new Student() ;
s.setExamid(examid) ;
s.setIdcard(idcard) ;
s.setName(name) ;
s.setLocation(location) ;
s.setGrade(Integer.parseInt(grade));
//做业务逻辑
return dao.addStudent(s) ;
}
}
二、Schema(掌握如何引入一个schema文件)
XML Schema 也是一种用于定义和描述 XML 文档结构与内容的模式语言,其出现是为了克服 DTD 的局限性
XML Schema VS DTD:
XML Schema符合XML语法结构。
DOM、SAX等XML API很容易解析出XML Schema文档中的内容。
XML Schema对名称空间支持得非常好。
XML Schema比XML DTD支持更多的数据类型,并支持用户自定义新的数据类型。
XML Schema定义约束的能力非常强大,可以对XML实例文档作出细致的语义限制。
XML Schema不能像DTD一样定义实体,比DTD更复杂,但Xml Schema现在已是w3c组织的标准,它正逐步取代DTD。
Schema约束快速入门
XML Schema 文件自身就是一个XML文件,但它的扩展名通常为.xsd。
一个XML Schema文档通常称之为模式文档(约束文档),遵循这个文档书写的xml文件称之为实例文档。
和XML文件一样,一个XML Schema文档也必须有一个根结点,但这个根结点的名称为schema。
编写了一个XML Schema约束文档后,通常需要把这个文件中声明的元素绑定到一个URI地址上,在XML Schema技术中有一个专业术语来描述这个过程,即把XMLSchema文档声明的元素绑定到一个名称空间上,以后XML文件就可以通过这个URI(即名称空间)来告诉解析引擎,xml文档中编写的元素来自哪里,被谁约束。
名称空间 : 指的是一个环境,所用的标签来自于哪个环境定义的。
在XML Schema中,每个约束模式文档都可以被赋以一个唯一的名称空间,名称空间用一个唯一的URI(Uniform Resource Identifier,统一资源标识符)表示。 在Xml文件中书写标签时,可以通过名称空间声明(xmlns),来声明当前编写的标签来自哪个Schema约束文档。如:
<itcast:书架 xmlns:itcast=“http://www.itcast.cn”>
<itcast:书>……</itcast:书>
</itcast:书架>
此处使用itcast来指向声明的名称,以便于后面对名称空间的引用。
注意:名称空间的名字语法容易让人混淆,尽管以 http:// 开始,那个 URL 并不指向一个包含模式定义的文件。事实上,这个 URL:http://www.itcast.cn根本没有指向任何文件,只是一个分配的名字。
使用名称空间引入Schema
为了在一个XML文档中声明它所遵循的Schema文件的具体位置,通常需要在Xml文档中的根结点中使用schemaLocation属性来指定,例如:
<itcast:书架 xmlns:itcast="http://www.itcast.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=“http://www.itcast.cn book.xsd">
schemaLocation此属性有两个值。第一个值是需要使用的命名空间。第二个值是供命名空间使用的 XML schema 的位置,两者之间用空格分隔。
注意,在使用schemaLocation属性时,也需要指定该属性来自哪里。
掌握引用schema文件:
xml中引入schema约束的步骤:
1、查看schema文档,找到根元素,在xml中写出来
<?xml version="1.0" encoding="UTF-8"?>
<书架>
</书架>
2、根元素来自哪个名称空间。使用xmlns指令来声明
名称空间是在schema中定义的,就是targetNamespace的值
<?xml version="1.0" encoding="UTF-8"?>
<itcast:书架 xmlns:itcast="http://www.itcast.com/book">
</itcast:书架>
3、引入的名称空间根哪个xsd文件对应?
使用schemaLocation来指定:两个取值:第一个为名称空间 第二个为xsd文件的路径
<?xml version="1.0" encoding="UTF-8"?>
<itcast:书架 xmlns:itcast="http://www.itcast.com/book"
schemaLocation="http://www.itcast.com/book book.xsd">
</itcast:书架>
4、schemaLocation哪里来的?它来自一个标准的名称空间,直接复制黏贴即可.
<?xml version="1.0" encoding="UTF-8"?>
<itcast:书架 xmlns:itcast="http://www.itcast.com/book"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.itcast.com/book book.xsd">
</itcast:书架>
5、只要以上4部搞好了,对于子标签myeclipse就有提示了
使用名称空间引入多个XML Schema文档
文件清单:xmlbook.xml
<?xml version="1.0" encoding="UTF-8"?>
<书架 xmlns="http://www.it315.org/xmlbook/schema"
xmlns:demo="http://www.it315.org/demo/schema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.it315.org/xmlbook/schema http://www.it315.org/xmlbook.xsd
http://www.it315.org/demo/schema http://www.it315.org/demo.xsd">
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价 demo:币种=”人民币”>28.00元</售价>
</书>
</书架>
实例:
book.xsd
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.itcast.cn"
elementFormDefault="qualified">
<xs:element name='书架' >
<xs:complexType>
<xs:sequence maxOccurs='unbounded' >
<xs:element name='书' >
<xs:complexType>
<xs:sequence>
<xs:element name='书名' type='xs:string' />
<xs:element name='作者' type='xs:string' />
<xs:element name='售价' type='xs:string' />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
NewFile.xml
<?xml version="1.0" encoding="UTF-8"?>
<itcast:书架
xmlns:itcast="http://www.itcast.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-indtance"
xsi:schemaLocation="http://www.itcast.cn book.xsd"
>
<itcast:书>
<itcast:书名>aaa</itcast:书名>
<itcast:作者>aaa</itcast:作者>
<itcast:售价>100</itcast:售价>
</itcast:书>
</itcast:书架>
shiporder.xsd
<?xml version="1.0" encoding="ISO-8859-1" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.itcast.cn"
elementFormDefault="qualified">
<xs:element name="shiporder">
<xs:complexType>
<xs:sequence>
<xs:element name="orderperson1" type="xs:string"/>
<xs:element name="shipto">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="address" type="xs:string"/>
<xs:element name="city" type="xs:string"/>
<xs:element name="country" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="note" type="xs:string" minOccurs="0"/>
<xs:element name="quantity" type="xs:positiveInteger"/>
<xs:element name="price" type="xs:decimal"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="orderid" type="xs:string" use="required"/>
</xs:complexType>
</xs:element>
</xs:schema>
shiporder.xml
<?xml version="1.0" encoding="UTF-8"?>
<shiporder
xmlns = "http://www.itcast.cn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.itcast.cn shiporder.xsd"
orderid=""
>
<orderperson1></orderperson1>
<shipto>
<name>nnnnnnnnnnn</name>
<address>aaaaaaaaaaa</address>
<city>ccccccccc</city>
<country>cccccccccccccc</country>
</shipto>
<item>
<title>ttttttttttttt</title>
<note>nnnnnnnnn</note>
<quantity>100</quantity>
<price>20</price>
</item>
</shiporder>
Tomcat配置及web程序结构
一、JavaWeb开发入门
1、WEB开发的相关知识
WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源。
Internet上供外界访问的Web资源分为:
静态web资源(如html 页面):指web页面中供人们浏览的数据始终是不变。
动态web资源:指web页面中供人们浏览的数据是由程序产生的,不同时间点访问web页面看到的内容各不相同。
静态web资源开发技术:
Html
常用动态web资源开发技术:
JSP/Servlet、ASP、PHP等
在Java中,动态web资源开发技术统称为Javaweb,我们课程的重点也是教大家如何使用Java技术开发动态的web资源,即动态web页面。
2、WEB服务器:
学习web开发,需要先安装一台web服务器,然后再在web服务器中开发相应的web资源,供用户使用浏览器访问。
ServerDemo.java
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerDemo {
public static void main(String[] args) {
try {
ServerSocket server = new ServerSocket(8888) ;
Socket socket = server.accept() ;
FileInputStream in = new FileInputStream(new File("d:/app/a.html")) ;
OutputStream os = socket.getOutputStream() ;
byte[] bs = new byte[1024] ;
int b = 0 ;
while((b = in.read(bs))!= -1){
os.write(bs,0,b) ;
}
os.close() ;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
3、常见WEB服务器
a、WebLogic是BEA公司的产品,是目前应用最广泛的Web服务器,支持JavaEE规范,而且不断的完善以适应新的开发要求,启动界面如图
b、另一个常用的Web服务器是IBM公司的WebSphereAS,支持JavaEE规范,启动界面如图
c、大名鼎鼎的红帽的产品,原来属于开源组织JbossAS,后被红帽收购。支持JavaEE规范,免费。
d、在小型的应用系统或者有特殊需要的系统中,可以使用一个免费的Web服务器:Tomcat,该服务器支持全部JSP以及Servlet规范,启动界面如图
4、Tomcat简介
a. Tomcat是在SUN公司推出的小型Servlet/JSP调试工具的基础上发展起来的一个优秀的Servlet容器,Tomcat本身完全用Java语言编写。目前是Apache开源软件组织的一个软件项目,它的官方网址为http://tomcat.apache.org。得到了广大开源代码志愿者的大力支持,且可以和目前大部分的主流Web服务器(IIS、Apache服务器)一起工作,它运行稳定、可靠且高效。已成为目前开发企业JavaWeb应用的最佳Servlet容器选择之一。
b. 我们后面的JavaWeb学习都是基于Tomcat服务器的。
c. Tomcat官方站点:http://tomcat.apache.org
d. 获取Tomcat安装程序包
tar.gz文件是Linux操作系统下的安装版本
exe文件是Windows系统下的安装版本x86 x64
zip文件是Windows系统下的压缩版本 (建议)
5、Tomcat的版本
6、安装Tomcat
a. Tomcat6本身是基于JDK1.5的应用程序,因此在安装和使用之前必须先行安装1.5及以上版本的JDK(JRE)
b. 解压安装
c. Exe安装
7、Tomcat启动方式
a. 使用Tomcat服务程序(安装版)
b. 使用Tomcat程序组中的快捷菜单(安装版)
c. 使用Tomcat.exe程序(安装版)
d. 使用批处理程序(使用解压版)
8、验证Tomcat服务器配置成功
a. 双击 bin 目录下的 startup.bat 文件
b. 输入 http://localhost:8080/,显示如下界面代表安装成功
9、Tip:Tomcat目录结构:Tomcat 的目录层次结构
10、JavaWEB应用程序
a. WEB应用程序指供浏览器访问的程序,通常也简称为web应用。
b. 一个web应用由多个静态web资源和动态web资源组成,如:
html、css、js文件
Jsp文件、java程序、支持jar包、
配置文件
……
c. Web应用开发好后,若想供外界访问,需要把web应用所在目录交给web服务器管理,这个过程称之为虚似目录的映射。
11、JavaWEB应用的组成结构
开发web应用时,不同类型的文件有严格的存放规则,否则不仅可能会使web应用无法访问,还会导致web服务器启动报错。
应用程序的目录结构(死了都要记住)
app
-->*.html
-->*.css
-->*.js
-->图片
-->WEB-INF : 文件夹(必须大写,不是必须的,当有动态的资源的时候,此文件夹必须写上) :下面的资源不允许浏览器直接访问,里面的资源是提供给服务器来访问的,我们可以间接的去访问.
-->-->web.xml : 必须的(WEB-INF文件夹存在的前提下)
-->-->classes: 放置的是Java字节码文件
-->-->lib: 放置的是本应用所用到的jar
12、Web组件的URL
无论是开放式目录结构还是打包文件方式发布web应用,web应用的默认URL入口都是Web应用的根目录名。例如要访问MyApp应用,它的URL入口为/MyApp,如访问本地服务http://localhost:8080/MyApp(http://127.0.0.1:8080/MyApp)
13、Tomcat的组成结构
Tomcat本身由一系列可配置的组件构成,其中核心组件是Servelt容器组件,它是所有其他Tomcat组件的顶层容器。每个组件都可以在Tomcat安装目录/conf/server.xml文件中进行配置,每个Tomcat组件在server.xml文件中对应一种配置元素。以下用XML的形式展示了各种Tomcat组件之间的关系
14、Tomcat体系架构
15、Context元素(了解)
Tomcat6.x提供了多种配置<Context>元素的途径。当其加载一个web应用时,会依次按照以下五种方式尝试查找Web应用的<Context>元素,直到找到为止, Note:若想让程序成为默认的Web应用,即访问http://localhost:8080时自动登录到Web应用的主页,可以在此处增加名字为ROOT.xml文件,其<Context>元素的path属性应该为””:
1)到Tomcat安装目录/conf/context.xml文件中查找<Context>元素。
2)到Tomcat安装目录/conf/[enginename]/[hostname]/context.xml.default文件中查找<Context>元素。
[enginename]:表示<Engine>的name属性
[hostname]:表示<Host>的name属性。
3)到Tomcat安装目录/conf/[enginename]/[hostname]/[contextpath].xml文件中查找<Context>元素。
[contextpath]:表示单个Web应用的URL入口。
4)到Web应用的META-INF/context.xml文件中查找<Context>元素。
5) 到Tomcat安装目录/conf/server.xml文件中查找<Context>元素。只适用于单个Web应用。
如果仅仅为单个Web应用配置<Context>元素,可以优先采用第三种配置方式。
16、Context元素的属性(了解)
在一般情况下,<Context>元素都会使用默认的标准Context组件,即className属性采用默认值org.apache.catalina.core.StandardContext,它除了拥有上面介绍到的属性外,还有自身专有的属性:
cachingAllowed:是否允许启用静态资源(HTML、图片、声音等)的缓存。默认值为true。
cacheMaxSize:设置静态资源缓存的最大值,单位为K。
workDir:指定Web应用的工作目录。
uppackWAR:如果为true,会把war文件展开为开放目录后再运行。为false,直接运行war文件。默认值为true。
17、web.xml文件
通过web.xml文件,可以将web应用中的:
某个web资源配置为网站首页
将servlet程序映射到某个url地址上
……
但凡涉及到对web资源进行配置,都需要通过web.xml文件
注意:web.xml文件必须放在web应用\WEB-INF目录下。
18、Web应用的生命周期
用Tomcat的管理平台管理Web应用的生命周期
Tomcat的管理平台是Tomcat本身的一个Web应用,管理平台对应manager应用,它位于Tomcat安装目录/webapps/manager目录下。
manager应用会对用户进行安全验证。它要求用户具有manager角色。因此,应该先在Tomcat中添加具有manager角色的用户信息,方法为打开Tomcat安装目录/conf/tomcat-users.xml文件,在其中增加以下内容:
<tomcat-users>
<role rolename=”manager”/>
<user username=”tomcat” password=”tomcat” roles=”manager”/>
</tomcat-users>
19、WEB开发的前景:
随着网络带宽的不断提升,云计算概念的提出,浏览器只要足够强大,c/s架构立马就会被淘汰,不仅c/s架构会被淘汰,软件最终都会消失、操作系统都可以没有,最终将会是b/s架构的天下,也就是浏览器+搜索引擎的天下。所有现在桌面软件提供的功能,最后都由网站提供,也就是说,将来打开电脑就是一个浏览器,想要什么服务,通过搜索引擎一找,就可以在网上找到相应的服务,用就是了。所以web开发人员是现在最流行的岗位。
a. 软件开发的两种架构:c/s和b/s
b. 服务器,规范,web程序三方关系图
二、Tomcat服务器配置实验
1、应用程序的部署方式 a、将应用程序直接拷贝到webapps目录下 将编写了HELLO的1.html放进自定义的文档app,并打开tomcat服务器:
测试tomcat服务器打开正常后在浏览器输入http://localhost:8080/app/1.html
b、将应用程序打成war包, 直接拷贝到webapps目录下
在dos命令窗口下键入: jar –cvf 名字.war .
首先先把原来自定义好的app文档整个剪切到别的盘符(为了测试,让webapps文档不存在该文档),
然后把app文档进行打包成war格式的文件,打包方法如图,图中意思是把d盘下的app文档打包成app.war压缩包:
成功:
把app.war拖入到tomcat服务器里的文档webapps,tomcat服务器会根据服务器conf里的xml配置文档对app.war文件自动解压。
若把app.war删除,已经解压好的app文档也会被自动删除
2、配置XML文档
a ) : 虚拟应用:
(此种配置不推荐)
在server.xml文件中配置如下
通过浏览器输入 http://localhost:8080/abc/1.html 来访问
缺点: 必须重新启动服务器
b) : 默认应用的配置
只需要在conf/catalina/localhost/目录下建立一个ROOT.xml文件,内容同上,这个应用就是默认应用
访问的时候通过URL: http://localhost:8080/a.html 来访问