文章目录
1、java xpath
先新建一个xml文件
在java中使用xpath
获取teacher节点下的name
获取teacher/student
新建一个xml文档
获取文档对象
Element是Node的子类
2、自定义web容器
2.1、新建一个java项目
新建一个java项目newWeb
根目录新建文件夹lib,将dom4j放进去
dom4j下载地址: http://xz.cncrk.com:8080/soft/keygen/dom4j.zip
commons-io.jar下载: 链接:https://pan.baidu.com/s/1qtbcFkiXkLsLIuClmf04wg 密码:xfum
//Dom4j是java xml操作库
//Common IO 是一个工具库,里面封装的内容包括输入输出流、文件操作等
然后Build Path
在项目根目录,新建web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<servlet>
<sevlet-name>loginPage</sevlet-name>
<sevlet-class>com.newweb.controller.LoginPage</sevlet-class>
</servlet>
<servlet-mapping>
<sevlet-name>loginPage</sevlet-name>
<url-patten>/loginPage</url-patten>
</servlet-mapping>
</web-app>
在src下新建一个包
com.newweb.controller,包下新建类LoginPage
在src下新建一个包
org.javax.http,包下新建类HttpServlet
先在HttpServlet里写一个service方法
LoginPage extends HttpServlet
2.2、浏览器发送请求,返回登录界面
实现步骤
1、创建请求路径和class对应的容器
2、在service方法中转发login.html
3、服务器获取到login.html返回给浏览器
2.2.1、解析web.xml
org.javax.http下新建RequestCls类(用于解析web.xml文档)
package org.javax.http;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class RequestCls {
private static Map<String,String> urlMapClass = new HashMap<String,String>();
static {
try {
initUrlMapClass();
}catch(Exception e){
e.printStackTrace();
}
}
public static String getClassPath(String uri) {
// 这里get来源String java.util.Map.get(Object key)
return urlMapClass.get(uri);
}
public static void initUrlMapClass() throws Exception {
SAXReader reader = new SAXReader();
Document docu = reader.read("web.xml");
Element root = docu.getRootElement();
Map<String,String> servletMap = getMapInfo(root,"//servlet","servlet-name","servlet-class");
Map<String,String> servletMappMap = getMapInfo(root,"//servlet-mapping","servlet-name","url-patten");
Set<Entry<String,String>> servEntrySet = servletMap.entrySet();
for(Entry<String,String> entry : servEntrySet) {
String uri = servletMappMap.get(entry.getKey());
String value = entry.getValue();
urlMapClass.put(uri,value);
}
}
//根据节点获取子元素对应的text,并封装到map中,k:elementName,v:elementClass
private static Map<String,String> getMapInfo(Element root,String path, String elementName, String elementClass){
Map<String,String> map = new HashMap<String,String>();
List<Element> servletList = root.selectNodes(path);
for(Element e : servletList) {
Element sName = e.element(elementName);
Element sClass = e.element(elementClass);
map.put(sName.getText(), sClass.getText());
}
return map;
}
}
Map.Entry,Entry即键值对对象,这样我们在遍历Map集合时,就可以从每一个键值对(Entry)对象中获取对应的键与对应的值。
entrySet实现了Set接口,里面存放的是键值对。一个K对应一个V。
用法: for(Entry<String, Object> entry :map.entrySet( )) { }
Set<Entry<String,String>>
里面是Entry,Entry,Entry,Entry。。。,然后每个Entry里面是k:v,k:v,k:v。。。。
Map.get() 方法返回指定键所映射的值
2.2.2、与服务器建立连接
新建server包,新建MyServer类
利用socket建立与浏览器的连接
package org.javax.server;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class MyServer {
public static void main(String[] args) throws Exception {
ServerSocket server = new ServerSocket(8111);
Socket socket = server.accept();
String content = "hello socket";
OutputStream out = socket.getOutputStream();
//StringBuilder可变字符序列
StringBuilder strB = new StringBuilder();
//添加hhttp协议字段
strB.append("HTTP/1.1 200 OK \r\n");
strB.append("text/html; charset=utf-8");
strB.append("\r\n \r\n"+content);
System.err.println(strB);
out.write(strB.toString().getBytes());
socket.close();
}
}
运行,然后进入浏览器访问(有的浏览器可能会显示无法正常访问)
改造MyServer,返回浏览器访问路径
package org.javax.server;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class MyServer {
private static ServerSocket server = null;
private static Socket socket = null;
private static InputStream in = null;
private static OutputStream out = null;
static {
try {
server = new ServerSocket(8111);
socket = server.accept();
in = socket.getInputStream();
out = socket.getOutputStream();
} catch (Exception e) {
e.printStackTrace();
}
}
public static String getURIStr() throws Exception {
InputStreamReader isr = new InputStreamReader(in);
BufferedReader br = new BufferedReader(isr);
String str = br.readLine();
str = str.split(" ")[1];
return str;
}
public static void sendResponse(String content) throws Exception {
OutputStream out = socket.getOutputStream();
//StringBuilder可变字符序列
StringBuilder strB = new StringBuilder();
//添加hhttp协议字段
strB.append("HTTP/1.1 200 OK \r\n");
strB.append("text/html; charset=utf-8");
strB.append("\r\n \r\n"+content);
System.err.println(strB);
out.write(strB.toString().getBytes());
socket.close();
}
public static void main(String[] args) throws Exception {
System.err.println(getURIStr());
}
}
浏览器访问
返回结果
加上sendResponse
运行,浏览器
成功运行,现在注释掉MyServer类的main方法
到这里一个简单的、能与服务器建立连接的java类就完成了,下面进行完善
2.3、servlet容器实现
新建类Request、Response
先写一个Response请求
package org.javax.http;
import org.javax.server.MyServer;
public class Request {
public static void main(String[] args) throws Exception {
String uri=MyServer.getURIStr();
String classPath = RequestCls.getClassPath(uri);
Class<HttpServlet> cls = (Class<HttpServlet>)Class.forName(classPath);
System.out.println(cls);
}
}
运行,浏览器
思路整理
2.4、 传递html到前端
Request
/**
* 转发
* @param path
* @throws FileNotFoundException
*/
public void getRequestDispacher(String path) throws Exception {
File resFile = new File(path);
FileInputStream fis = new FileInputStream(resFile);
// 字节流->字符流
InputStreamReader in = new InputStreamReader(fis);
// 字符流->缓冲字符
BufferedReader br = new BufferedReader(in);
String content = null;
// 创建一个可变的字符序列
StringBuilder strb = new StringBuilder();
while ((content = br.readLine()) !=null ) {
strb.append(content);
}
br.close();
System.out.println(strb);
MyServer.sendResponse(strb.toString());
}
LoginPage
package com.newweb.controller;
import org.javax.http.HttpServlet;
import org.javax.http.Request;
import org.javax.http.Response;
public class LoginPage extends HttpServlet{
@Override
protected void service(Request req, Response resp) throws Exception{
System.out.println("service方法运行了");
req.getRequestDispacher("login.html");
}
}
项目根目录下新建login.html
HttpServlet
package org.javax.http;
public class HttpServlet {
protected void service(Request req, Response resp) throws Exception{
}
}
运行,浏览器访问:http://localhost:8111/loginPage
2.5、代码总结
package com.newweb.controller;
import org.javax.http.HttpServlet;
import org.javax.http.Request;
import org.javax.http.Response;
public class LoginPage extends HttpServlet{
@Override
protected void service(Request req, Response resp) throws Exception{
System.out.println("service方法运行了");
req.getRequestDispacher("login.html");
}
}
package org.javax.http;
public class HttpServlet {
protected void service(Request req, Response resp) throws Exception{
}
}
package org.javax.http;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStreamReader;
import java.lang.reflect.Method;
import org.javax.server.MyServer;
public class Request {
public static void main(String[] args) throws Exception {
String uri=MyServer.getURIStr();
String classPath = RequestCls.getClassPath(uri);
Class<HttpServlet> cls = (Class<HttpServlet>)Class.forName(classPath);
// 获取有参方法(方法名,参数类型,参数类型。。)
Method method = cls.getDeclaredMethod("service", Request.class, Response.class);
// 访问私有对象
method.setAccessible(true);
// 执行某个的对象的目标方法
method.invoke(cls.newInstance(), new Request(), new Response());
}
/**
* 转发
* @param path
* @throws FileNotFoundException
*/
public void getRequestDispacher(String path) throws Exception {
File resFile = new File(path);
FileInputStream fis = new FileInputStream(resFile);
// 字节流->字符流
InputStreamReader in = new InputStreamReader(fis);
// 字符流->缓冲字符
BufferedReader br = new BufferedReader(in);
String content = null;
// 创建一个可变的字符序列
StringBuilder strb = new StringBuilder();
while ((content = br.readLine()) !=null ) {
strb.append(content);
}
br.close();
System.out.println(strb);
MyServer.sendResponse(strb.toString());
}
}
package org.javax.http;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class RequestCls {
private static Map<String,String> urlMapClass = new HashMap<String,String>();
static {
try {
initUrlMapClass();
}catch(Exception e){
e.printStackTrace();
}
}
public static String getClassPath(String uri) {
// 这里get来源String java.util.Map.get(Object key)
return urlMapClass.get(uri);
}
public static void initUrlMapClass() throws Exception {
SAXReader reader = new SAXReader();
Document docu = reader.read("web.xml");
Element root = docu.getRootElement();
Map<String,String> servletMap = getMapInfo(root,"//servlet","servlet-name","servlet-class");
Map<String,String> servletMappMap = getMapInfo(root,"//servlet-mapping","servlet-name","url-patten");
Set<Entry<String,String>> servEntrySet = servletMap.entrySet();
for(Entry<String,String> entry : servEntrySet) {
String uri = servletMappMap.get(entry.getKey());
String value = entry.getValue();
urlMapClass.put(uri,value);
}
}
//根据节点获取子元素对应的text,并封装到map中,k:elementName,v:elementClass
private static Map<String,String> getMapInfo(Element root,String path, String elementName, String elementClass){
Map<String,String> map = new HashMap<String,String>();
List<Element> servletList = root.selectNodes(path);
for(Element e : servletList) {
Element sName = e.element(elementName);
Element sClass = e.element(elementClass);
map.put(sName.getText(), sClass.getText());
}
return map;
}
}
package org.javax.http;
public class Response {
}
package org.javax.server;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class MyServer {
private static ServerSocket server = null;
private static Socket socket = null;
private static InputStream in = null;
private static OutputStream out = null;
static {
try {
server = new ServerSocket(8111);
// accept返回一个Socket类型的对象与客户端形成一个通讯管道
socket = server.accept();
// 得到从服务器端发回的数据
in = socket.getInputStream();
// 发送给服务器端的数据
out = socket.getOutputStream();
} catch (Exception e) {
e.printStackTrace();
}
}
public static String getURIStr() throws Exception {
// 从字节流到字符流的桥接器
InputStreamReader isr = new InputStreamReader(in);
// 从字符输入流中读取文本并缓冲字符
BufferedReader br = new BufferedReader(isr);
// readLine()是一个阻塞函数,当没有数据读取时,就一直会阻塞在那,而不是返回null;
// readLine()只有在数据流发生异常或者另一端被close()掉时,才会返回null值。
String str = br.readLine();
str = str.split(" ")[1];
return str;
}
public static void sendResponse(String content) throws Exception {
//StringBuilder可变字符序列
StringBuilder strB = new StringBuilder();
//添加http协议字段
strB.append("HTTP/1.1 200 OK \r\n");
strB.append("text/html; charset=utf-8");
strB.append("\r\n \r\n"+content);
System.out.println(strB);
out.write(strB.toString().getBytes());
socket.close();
}
// public static void main(String[] args) throws Exception {
// System.err.println(getURIStr());
// sendResponse("我的第一个web容器");
// }
}
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<servlet>
<servlet-name>loginPage</servlet-name>
<servlet-class>com.newweb.controller.LoginPage</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>loginPage</servlet-name>
<url-patten>/loginPage</url-patten>
</servlet-mapping>
</web-app>
3、myeclipce查找快捷键
快捷键ctrl+h
4、maven
4.1、maven简介
什么是maven:是apache下的一个开源项目,纯java开发,只用来管理java项目 。
maven的好处:
1、项目比较小(项目里面没有jar包、jar包都在本地仓库)
2、在没有eclipse等软件时,可以直接在本地仓库运行tomcat
先进入项目文件夹
使用指令:mvn tomcat:run
项目构建步骤:编码、编译、测试、运行、打包、部署
maven可以干的事:编译、测试、运行、打包、部署
4.2、maven安装配置
maven下载地址
https://maven.apache.org/download.cgi
将下载好的包解压后放到一个纯英文路径下
这里注意一个问题:maven 3.3.x以上版本需要jdk1.7以上
然后进行maven环境配置
右键“计算机”,选择“属性”,之后点击“高级系统设置”,点击“环境变量”,来设置环境变量,有以下系统变量需要配置:
新建系统变量 MAVEN_HOME 变量值(maven解压的目录):G:apache-maven-3.6.3
编辑系统变量 Path 添加变量值: %MAVEN_HOME%\bin
在cmd里面查看是否安装成功:mvn -v
maven环境变量配置完之后
在maven解压目录找到conf / settings.xml
在里面找到localRepository
新添加这一行配置,配置自己的本地仓库位置
<localRepository>G:\apache-maven-3.6.3\jarHome</localRepository>
搭建好本地仓库还可以搭建远程仓库(私服),也可以配置中央仓库。中央仓库几乎拥有所有的jar包
由于中央仓库是国外网站,访问较慢,可以给maven配置阿里镜像
<mirror>
<id>alimaven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/repositories/central/</url>
</mirror>
在conf / settings.xml里面的/mirrors里加入这串代码
4.3、maven目录结构
项目编译前:
项目根目录,其中pom.xml是项目核心文件
src下的目录结构,main是主目录,test是测试目录
main下目录结构,java里放java代码,resources里面放配置文件web.xml、properties等
4.4、maven常用命令
tomcat:run :运行项目
Clean :清理target文件夹(也就是编译好的东西)
Compile : 编译(生成target文件夹),Compile只编译主文件
Test :编译并运行test目录的代码
package :打包
install :把项目发布到本地仓库
4.5、eclipse编码环境
先切换一个工作空间
切换到java浏览视图
检查eclipse编码环境
wokspace编码改成utf-8
把jsp的编码成utf-8
调节字体大小
4.6、在eclipse里面构建maven项目
4.6.1、检查maven环境配置
在eclipse里面构建maven需要M2e插件(新版本的eclipse很多也不需要插件)
查看celipse集成的maven版本
默认集成的是3.5.3,把它改成我们下载的版本
eclipse里面maven默认的仓库地址
修改默认的本地仓库地址
之后点击Apply and close就可以了(有些版本的eclipse点ok)
4.6.2、新建项目
新建项目后会发现这个错误
找到src-》main-》webapp-》新建文件夹WEB-INF-》新建web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
</web-app>
然后我们发现编译器版本是1.5的,maven 3.3以上需要jdk1.7以上
找到pom.xml添加下面这段代码
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
然后项目名上可能会有个红叉叉,需要手动更新一下项目
总结新项目创建步骤:
1、新建maven项目
2、添加web.xml
3、pom.xml里面配置编译器版本
4.6.3、新建servlet类
创建完成之后会出现报错,先找到web.xml
先查看有没有重复的xmlns=“http://java.sun.com/xml/ns/javaee”,有的话删除
然后添加jar包,修改pom文件,添加下面代码
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
ctrl+s保存之后,如果本地仓库没有对应的jar包,eclipse就开始下载
完成之后出现maven dependcies
然后开始运行
运行前将项目添加到tomcat服务里面
Eclipse中配置Tomcat: https://www.cnblogs.com/li-yan-long/p/10339919.html