补充:如何配置阿里 maven 镜像
(1) 把 D:\program\JavaIDEA 2020.2\plugins\maven\lib\maven3\conf\settings.xml 拷贝默认的 maven 配置目录
(2) C:\Users\Administrator.m2 目录 settings.xml
** (3) 修改 C:\Users\Administrator.m2\settings.xml , 增加红色的部分**
alimaven
aliyun maven
http://maven.aliyun.com/nexus/content/groups/public/ central
dependency 表示依赖, 也就是我们这个项目需要依赖的jar 包
groupId 和 artifactId 被统称为坐标, 是为了去定位这个项目/jar
groupId: 一般是公司 比如 com.baidu , 这里是 avax.servlet
artifactId 一般是项目名, 这里是 javax.servlet-api
这样的化就可以定位一个 jar 包
version 表示你引入到我们项目的 jar 包的版本是 3.1.0
scope: 表示作用域,也就是你引入的 jar 包的作用范围
provided 表示在 tomcat 本身是有这个 jar 的,因此在编译,测试使用,但是在打包发布就不用要带上
在默认情况下, 引入的 jar 会到 中央仓库去下载 https://mvnrepository.com/
会下载到哪里到你指定的目录 C:\Users\Administrator.m2\repository
有时为了下载更快, 往往配置镜像,
在 默 认 的 路 径 下 拷 贝 一份setting.xml 到C:\Users\Administrator.m2\settings.xml
1.HSPRequestHandler 是一个线程对象 2.处理Http请求的
import com.hspedu.servlet.CalServlet;
import com.hspedu.tomcat.HspTomcatV3;
import com.hspedu.tomcat.http.HspRequest;
import com.hspedu.tomcat.http.HspResponse;
import com.hspedu.tomcat.servlet.HspCalServlet;
import com.hspedu.tomcat.servlet.HspHttpServlet;
import com.hspedu.tomcat.utils.WebUtils;
import java.io.*;
import java.net.Socket;
public class HSPRequestHandler implements Runnable {
//定义一个Socket
private Socket socket = null;
public HSPRequestHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
//对客户端/浏览器进行交互
InputStream inputStream;
try {
HspRequest hspRequest = new HspRequest(socket.getInputStream());
HspResponse hspResponse = new HspResponse(socket.getOutputStream());
//1.得到uri=>servletUrlMapping的key
String uri = hspRequest.getUri();
if (WebUtils.isHtml(uri)){//如果就是一个静态页面
String content = WebUtils.readHtml(uri.substring(1));
content=HspResponse.respHeader+content;
//得到outputstream,返回信息给浏览器
OutputStream outputStream = hspResponse.getOutputStream();
outputStream.write(content.getBytes());
outputStream.flush();
outputStream.close();
socket.close();
return;
}
String servletName = HspTomcatV3.servletUrlMapping.get(uri);
//2.通过uri->servletName->servlet实例,真正的运行类型是其子类 HspCalServlet
HspHttpServlet hspHttpServlet = HspTomcatV3.servletMapping.get(servletName);
//3.调用service,通过或OOP的动态绑定机制,调用运动类型的doGet/doPost
if (hspHttpServlet != null) {//得到
hspHttpServlet.service(hspRequest, hspResponse);
} else {
//没有这个servlet,返回404提示信息
String resp = HspResponse.respHeader + "404 Not Found
";
OutputStream outputStream = hspResponse.getOutputStream();
outputStream.write(resp.getBytes());
outputStream.flush();
outputStream.close();
}
socket.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
//确保socket要关闭
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
1.HspRequest 作用是封装http请求的数据 2.比如:method 、uri、还有参数列表 3.HspRequest等价与原生的servlet中的HttpServletRequest 4.此处只考虑GET请求
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
public class HspRequest {
private String method;
private String uri;
//存放参数列表 使用HashMap
private HashMap parametersMapping =
new HashMap<>();
private InputStream inputStream=null;
//构造器
//inputStream是和对应的Http请求的socket关联
public HspRequest(InputStream inputStream) {
this.inputStream=inputStream;
//完成对http请求的封装
encapHttpRequest();
}
//将http请求的相关数据,进行封装,然后提供相关的方法,进行获取
private void encapHttpRequest(){
try {
//将inputStream转化为BufferedReader
BufferedReader bufferedReader =
new BufferedReader(new InputStreamReader(inputStream, "utf-8"));
//读取第一行
String requestLine = bufferedReader.readLine();
String[] requestLineArr = requestLine.split(" ");
//获取method
method = requestLineArr[0];
//
int index = requestLineArr[1].indexOf("?");
if (index == -1) {//说明没有参数列表
uri = requestLineArr[1];
} else {
uri = requestLineArr[1].substring(0, index);
//获取参数列表放入parametersMapping
String parameters = requestLineArr[1].substring(index + 1);
String[] parametersPair = parameters.split("&");
if (null != parametersPair && !"".equals(parametersPair)) {
for (String parameterPair : parametersPair) {
String[] parameterVal = parameterPair.split("=");
if (parameterVal.length == 2) {
//放入到parametersMapping
parametersMapping.put(parameterVal[0], parameterVal[1]);
}
}
}
}
//这里不能关闭流
// inputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//request有一个特别重要的方法
public String getParameter(String name) {
if (parametersMapping.containsKey(name)) {
return parametersMapping.get(name);
} else {
return "";
}
}
public String getMethod() {
return method;
}
public void setMethod(String method) {
this.method = method;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
@Override
public String toString() {
return "HspRequest{" +
"method='" + method + '\'' +
", uri='" + uri + '\'' +
", parametersMapping=" + parametersMapping +
'}';
}
}
1.HspResponse对象可以封装OutputStream(是socket关联) 2.即可以通过 HspResponse对象 返回Http响应给浏览器/客户端、 3.HspResponse等价于原生的servlet的HttpServletResponse
public class HspResponse {
private OutputStream outputStream=null;
//写一个http响应头
public static final String respHeader = "HTTP/1.1 200 OK\r\n" +
"Content-Type:text/html;charset=utf-8\r\n\r\n";
//在创建HspResponse 对象时,传入的outputStream是和Socket关联的
public HspResponse(OutputStream outputStream) {
this.outputStream = outputStream;
}
//当需要给浏览器返回数据时,可以通过HspResponse 的输出流完成
public OutputStream getOutputStream() {
return outputStream;
}
}
1.业务代码,完成计算任务
import com.hspedu.tomcat.http.HspRequest;
import com.hspedu.tomcat.http.HspResponse;
import com.hspedu.tomcat.utils.WebUtils;
import java.io.IOException;
import java.io.OutputStream;
public class HspCalServlet1 extends HspHttpServlet{
@Override
public void doGet(HspRequest request, HspResponse response) {
//写业务代码,完成计算任务
int num1 = WebUtils.parseInt(request.getParameter("num1"), 0);
int num2 = WebUtils.parseInt(request.getParameter("num2"), 0);
int sum = num1 * num2;
//返回计算结果给浏览器/客户端
//outputStream 是和当前 Socket关联
OutputStream outputStream = response.getOutputStream();
String respMes = HspResponse.respHeader
+ "" + num1 + "*" + num2 + "=" + sum + "HspTomcatV3 -反射+xml创建 -乘法
";
try {
outputStream.write(respMes.getBytes());
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void doPost(HspRequest request, HspResponse response) {
this.doGet(request,response);
}
@Override
public void init() throws Exception {
}
@Override
public void destroy() {
}
}
抽象类
package com.hspedu.tomcat.servlet;
import com.hspedu.tomcat.http.HspRequest;
import com.hspedu.tomcat.http.HspResponse;
import java.io.IOException;
public abstract class HspHttpServlet implements HspServlet {
@Override
public void service(HspRequest request, HspResponse response) throws IOException {
//equalsIgnoreCase 比较两个字符串内容是否相等,并且不区分大小写
if ("GET".equalsIgnoreCase(request.getMethod())){
//这里会有动态绑定
this.doGet(request,response);
}else if("POST".equalsIgnoreCase(request.getMethod())){
this.doPost(request,response);
}
}
//使用了模板设计模式
//让HspHttpServlet 子类 HspCalServlet 实现
public abstract void doGet(HspRequest request,HspResponse response);
public abstract void doPost(HspRequest request,HspResponse response);
}
接口
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;
/**
* 先搭建结构,再写内容
* 只保留了三个核心方法
*/
public interface HspServlet {
void init() throws Exception;
void service(HspRequest request, HspResponse response) throws IOException;
void destroy();
工具类
package com.hspedu.tomcat.utils;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class WebUtils {
//将字符串转化为数字的方法
public static int parseInt(String StrNum,int defaultVal){
try{
return Integer.parseInt(StrNum);
}catch (NumberFormatException e){
System.out.println(StrNum+"格式不对,转换失败");
}
return defaultVal;
}
//判断uri是不是html文件
public static boolean isHtml(String uri){
return uri.endsWith(".html");
}
//根据文件名来读取文件‘
public static String readHtml(String fileName){
String path= com.hspedu.utils.WebUtils.class.getResource("/").getPath();
StringBuilder stringBuilder = new StringBuilder();
try {
BufferedReader bufferedReader = new BufferedReader(new FileReader(path + fileName));
String buff="";
while ((buff=bufferedReader.readLine())!=null){
stringBuilder.append(buff);
}
} catch (IOException e) {
e.printStackTrace();
}
return stringBuilder.toString();
}
}
实现类
package com.hspedu.tomcat;
import com.hspedu.tomcat.handler.HSPRequestHandler;
import com.hspedu.tomcat.servlet.HspHttpServlet;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
//第3版Tomcat,实现通过xml+反射来初始化容器
public class HspTomcatV3 {
//1.存放容器 servletMapping
//-ConcurrentHashMap
//-HashMap
//key -value
//ServletName 对应的实例
public static final HashMap
servletMapping = new HashMap<>();
//2.容器 servletUrlMapping
//-ConcurrentHashMap
//-HashMap
//key -value
//url-pattern ServletName
public static final HashMap
servletUrlMapping=new HashMap<>();
public static void main(String[] args) {
HspTomcatV3 hspTomcatV3 = new HspTomcatV3();
hspTomcatV3.init();
//启动后hspTomcat容器
hspTomcatV3.run();
}
//启动HspTomcatV3容器
public void run(){
try {
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("======MyTomcatV3在8080端口监听======");
while (!serverSocket.isClosed()){
Socket socket = serverSocket.accept();
HSPRequestHandler hspRequestHandler = new HSPRequestHandler(socket);
new Thread(hspRequestHandler).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
//直接对两个容器进行初始化
public void init(){
//读取web.xml =>使用dom4j
//得到web.xml文件路径
String path=HspTomcatV3.class.getResource("/").getPath();
SAXReader saxReader=new SAXReader();
try {
Document document = saxReader.read(new File(path + "web.xml"));
System.out.println("document="+document);
//得到根元素
Element rootElement = document.getRootElement();
//得到根元素下的所有元素
List elements = rootElement.elements();
//遍历并过滤到 servlet servlet-mapping
for (Element element : elements) {
if("servlet".equalsIgnoreCase(element.getName())){
//这是一个servlet配置
//使用反射讲该servlet实例放入到servletMapping
Element servletName = element.element("servlet-name");
Element servletClass = element.element("servlet-class");
servletMapping.put(servletName.getText(),
(HspHttpServlet) Class.forName(servletClass.getText().trim()).newInstance());
}else if("servlet-mapping".equalsIgnoreCase(element.getName())){
//这是一个servlet-mapping配置
Element servletName = element.element("servlet-name");
Element urlPattern = element.element("url-pattern");
servletUrlMapping.put(urlPattern.getText(),servletName.getText());
}
}
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("servletMapping="+servletMapping);
System.out.println("servletUrlMapping="+servletUrlMapping);
}
}