主类:
public class Catalina {
static {
try {
Container.WEB_CONFIG.load(Catalina.class.getClassLoader().getResourceAsStream("web.properties"));
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception{
ServerSocket server = new ServerSocket();
server.bind(new InetSocketAddress(7777));
while (true){
Socket accept = server.accept();
StringBuilder sb = new StringBuilder();
InputStream in = accept.getInputStream();
int len;
byte[] buf = new byte[512];
while ((len = in.read(buf)) != -1) {
sb.append(new String(buf, 0, len));
if (len < buf.length) {
accept.shutdownInput();
}
}
Request request = Request.buildRequest(sb.toString());
request.setRemoteHost(accept.getInetAddress().getHostAddress());
String url = request.getUrl();
if("/favicon.ico".equals(url)){
continue;
}
Servlet servlet = Container.SERVLET_CONTAINER.get(url);
if(servlet==null){
★★★
★★
String fullClassName = Container.WEB_CONFIG.getProperty(url);
if(!"".equals(fullClassName) && fullClassName!=null){
servlet = (Servlet)Class.forName(fullClassName).newInstance();
}else {
servlet = new IndexServlet();
}
Container.SERVLET_CONTAINER.put(url,servlet);
}
Response response = new Response();
response.setOs(accept.getOutputStream());
if(request.getHeaders().get("cookie")==null || !request.getHeaders().get("cookie").contains("jsessionid")) {
String jsessionid = UUID.randomUUID().toString();
Container.SESSIONS.put(jsessionid,new HashMap<>(8));
response.addHeader("set-cookie","jsessionid="+jsessionid);
}
servlet.service(request,response);
}
}
}
容器:
public class Container {
public final static Properties WEB_CONFIG=new Properties();
public final static HashMap<String,Servlet> SERVLET_CONTAINER =new HashMap<>(8);
public final static Map<String, Map<String,Object>> SESSIONS =new HashMap<>(8);
}
Servlet接口:
public interface Servlet {
void init();
void service(Request request,Response response);
void destroy();
}
Request:
public class Request {
private String type;
private String url;
private String protocol;
private String contentType;
private String remoteHost;
private Map<String,String> headers = new HashMap<>(8);
private Map<String,String> attributes = new HashMap<>(8);
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getProtocol() {
return protocol;
}
public void setProtocol(String protocol) {
this.protocol = protocol;
}
public String getContentType() {
return contentType;
}
public void setContentType(String contentType) {
this.contentType = contentType;
}
public Map<String, String> getHeaders() {
return headers;
}
public void setHeaders(Map<String, String> headers) {
this.headers = headers;
}
public Map<String, String> getAttributes() {
return attributes;
}
public void setAttributes(Map<String, String> attributes) {
this.attributes = attributes;
}
public String getRemoteHost() {
return remoteHost;
}
public void setRemoteHost(String remoteHost) {
this.remoteHost = remoteHost;
}
@Override
public String toString() {
return "Request{" +
"type='" + type + '\'' +
", url='" + url + '\'' +
", protocol='" + protocol + '\'' +
", contentType='" + contentType + '\'' +
", headers=" + headers +
", attributes=" + attributes +
'}';
}
public static Request buildRequest(String requestStr){
Request request = new Request();
String[] split = requestStr.split("\r\n\r\n");
String[] lineAndHeader = split[0].split("\r\n");
String[] lines = lineAndHeader[0].split(" ");
request.setType(lines[0]);
request.setUrl(lines[1]);
request.setProtocol(lines[2]);
for (int i = 1; i < lineAndHeader.length; i++) {
String[] header = lineAndHeader[i].split(": ");
request.getHeaders().put(header[0].trim().toLowerCase(),header[1].trim());
}
request.setContentType(request.getHeaders().get("content-type"));
if (split.length == 2){
}
return request;
}
}
Response:
public class Response {
private String protocol = "HTTP/1.1";
private Integer code = 200;
private String msg = "OK";
private String ContentType = "text/html;charset=utf-8";
private String ContentLength;
private Map<String,String > headers = new HashMap(){{
put("content-type",ContentType);
}};
private String data;
private OutputStream os;
public Response(){}
public Response(String protocol, Integer code, String msg) {
this.protocol = protocol;
this.code = code;
this.msg = msg;
}
public String buildResponse(){
StringBuilder sb = new StringBuilder();
sb.append(this.getProtocol()).append(" ")
.append(this.getCode()).append(" ")
.append(this.getMsg()).append("\r\n");
for (Map.Entry<String,String> entry : this.getHeaders().entrySet()){
sb.append(entry.getKey()).append(": ").append(entry.getValue()).append("\r\n");
}
sb.append("\r\n").append(this.getData());
return sb.toString();
}
public void write(){
try {
os.write(buildResponse().getBytes());
} catch (IOException e) {
e.printStackTrace();
} finally {
if(os != null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public void write(String content){
this.setData(content);
this.write();
}
public void addHeader(String key,String value){
this.getHeaders().put(key,value);
}
public String getProtocol() {
return protocol;
}
public void setProtocol(String protocol) {
this.protocol = protocol;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Map<String, String> getHeaders() {
return headers;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
this.setContentLength(data.getBytes().length+"");
}
public OutputStream getOs() {
return os;
}
public void setOs(OutputStream os) {
this.os = os;
}
public String getContentType() {
return this.getHeaders().get("content-type");
}
public void setContentType(String contentType) {
this.getHeaders().put("content-type",contentType);
}
public String getContentLength() {
return this.getHeaders().get("content-length");
}
public void setContentLength(String contentLength) {
this.getHeaders().put("content-length",this.data.getBytes().length + "");
}
}
配置文件web.properties:
/index=com.itnls.Tomcat.servlet.IndexServlet
/home=com.itnls.Tomcat.servlet.HomeServlet
/order=com.itnls.Tomcat.servlet.OrderServlet
/user=com.itnls.Tomcat.servlet.UserServlet
HttpUtils:
public class HttpUtils {
// 使用流获得页面的字符串
public static String getPage(String url){
StringBuilder sb = new StringBuilder();
try {
if ("".equals(url) || "/".equals(url) || url == null){
url = "index.html";
}
// 寻找绝对的父路劲
String path = Test.class.getProtectionDomain().getCodeSource().getLocation().getPath();
path = path.substring(0,path.lastIndexOf("/")) + "/pages/";
url = path + url;
boolean exists = new File(url).exists();
if (!exists){
url = path +"404.html";
}
InputStream resource = new FileInputStream(url);
byte[] buf = new byte[1024];
int len;
while ((len = resource.read(buf)) != -1){
sb.append(new String(buf,0,len));
}
} catch (Exception e){
e.printStackTrace();
}
return sb.toString();
}
}
GenericServlet抽离冗余方法:
/**
* 抽离冗余代码,新建servlet的时候就不必再实现一遍两个方法了
*/
public abstract class GenericServlet implements Servlet {
@Override
public void init() {
}
@Override
public void destroy() {
}
}
OrderServlet继承GenericServlet:
public class OrderServlet extends GenericServlet {
@Override
public void service(Request request, Response response) {
}
}
HttpServlet继承genericservlet:
public class HttpServlet extends GenericServlet {
@Override
public void service(Request request, Response response) {
if("GET".equals(request.getType())){
this.doGet(request,response);
}else if("POST".equals(request.getType())){
this.doPost(request,response);
}
}
public void doGet(Request request, Response response){
}
public void doPost(Request request, Response response){
}
}
UserServlet继承HttpServlet:
public class UserServlet extends HttpServlet {
@Override
public void doGet(Request request, Response response) {
response.write("<h1>hahaha,user!</h1>");
}
}
IndexServlet实现Servlet接口(有cookie):
public class IndexServlet implements Servlet {
public IndexServlet(){
init();
}
@Override
public void init() {
}
@Override
public void service(Request request, Response response) {
String cookie = request.getHeaders().get("cookie");
if(cookie==null){
response.write("<h1>login please!!</h1>");
}else{
String sessionId = cookie.split("=")[1];
Map<String, Object> session = Container.SESSIONS.get(sessionId);
session.put("user","zhangsan");
response.write("<h1>登陆成功!</h1>");
}
}
@Override
public void destroy() {
}
}
HomeServlet实现Servlet接口(有cookie):
public class HomeServlet implements Servlet {
public static final List<String> BLACK_NAMES =new ArrayList(){{
add("192.168.67.66");
}};
public HomeServlet(){
init();
}
@Override
public void init() {
}
@Override
public void service(Request request, Response response) {
String cookie = request.getHeaders().get("cookie");
if(cookie==null){
response.write("<h1>login please!!</h1>");
}else{
String sessionId = cookie.split("=")[1];
Map<String, Object> session = Container.SESSIONS.get(sessionId);
if(session==null || session.get("user")==null){
response.write("<h1>未登录</h1>");
}else{
response.write("<h1>你好"+ session.get("user") +"</h1>");
}
}
}
@Override
public void destroy() {
}
}