简单的servlet容器实现【转载别人的,觉得很有用~】

本文介绍了一个简单的HTTP服务器实现,包括启动、请求处理、Servlet加载与响应发送。通过自定义类实现了基本的服务器功能,并展示了如何处理静态资源与自定义Servlet。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. HttpServer1

packageex02.pyrmont;

importjava.net.Socket;
importjava.net.ServerSocket;
importjava.net.InetAddress;
importjava.io.InputStream;
importjava.io.OutputStream;
importjava.io.IOException;

publicclassHttpServer1 {

/** WEB_ROOT is the directory where our HTML and other files reside.
*For this package, WEB_ROOT is the "webroot" directory under the working
*directory.
*The working directory is the location in the file system
*from where the java command was invoked.
*/
// shutdown command
privatestaticfinalString SHUTDOWN_COMMAND ="/SHUTDOWN";

// the shutdown command received
privatebooleanshutdown =false;

publicstaticvoidmain(String[] args) {
HttpServer1 server =newHttpServer1();
server.await();
}

publicvoidawait() {
ServerSocket serverSocket =null;
intport = 8080;
try{
serverSocket =newServerSocket(port, 1, InetAddress.getByName("127.0.0.1"));
}
catch(IOException e) {
e.printStackTrace();
System.exit(1);
}

// Loop waiting for a request
while(!shutdown) {
Socket socket =null;
InputStream input =null;
OutputStream output =null;
try{
socket = serverSocket.accept();
input = socket.getInputStream();
output = socket.getOutputStream();

// create Request object and parse
Request request =newRequest(input);
request.parse();

// create Response object
Response response =newResponse(output);
response.setRequest(request);

// check if this is a request for a servlet or a static resource
// a request for a servlet begins with "/servlet/"
if(request.getUri().startsWith("/servlet/")) {
ServletProcessor1 processor =newServletProcessor1();
processor.process(request, response);
}
else{
StaticResourceProcessor processor =newStaticResourceProcessor();
processor.process(request, response);
}

// Close the socket
socket.close();
//check if the previous URI is a shutdown command
shutdown = request.getUri().equals(SHUTDOWN_COMMAND);
}
catch(Exception e) {
e.printStackTrace();
System.exit(1);
}
}
}
}

2. Request
java 代码
packageex02.pyrmont;

importjava.io.InputStream;
importjava.io.IOException;
importjava.io.BufferedReader;
importjava.io.UnsupportedEncodingException;
importjava.util.Enumeration;
importjava.util.Locale;
importjava.util.Map;
importjavax.servlet.RequestDispatcher;
importjavax.servlet.ServletInputStream;
importjavax.servlet.ServletRequest;


publicclassRequestimplementsServletRequest {

privateInputStream input;
privateString uri;

publicRequest(InputStream input) {
this.input = input;
}

publicString getUri() {
returnuri;
}

privateString parseUri(String requestString) {
intindex1, index2;
index1 = requestString.indexOf(' ');
if(index1 != -1) {
index2 = requestString.indexOf(' ', index1 + 1);
if(index2 > index1)
returnrequestString.substring(index1 + 1, index2);
}
returnnull;
}

publicvoidparse() {
// Read a set of characters from the socket
StringBuffer request =newStringBuffer(2048);
inti;
byte[] buffer =newbyte[2048];
try{
i = input.read(buffer);
}
catch(IOException e) {
e.printStackTrace();
i = -1;
}
for(intj=0; j
request.append((char) buffer[j]);
}
System.out.print(request.toString());
uri = parseUri(request.toString());
}

/* implementation of the ServletRequest*/
publicObject getAttribute(String attribute) {
returnnull;
}

publicEnumeration getAttributeNames() {
returnnull;
}

publicString getRealPath(String path) {
returnnull;
}

publicRequestDispatcher getRequestDispatcher(String path) {
returnnull;
}

publicbooleanisSecure() {
returnfalse;
}

publicString getCharacterEncoding() {
returnnull;
}

publicintgetContentLength() {
return0;
}

publicString getContentType() {
returnnull;
}

publicServletInputStream getInputStream()throwsIOException {
returnnull;
}

publicLocale getLocale() {
returnnull;
}

publicEnumeration getLocales() {
returnnull;
}

publicString getParameter(String name) {
returnnull;
}

publicMap getParameterMap() {
returnnull;
}

publicEnumeration getParameterNames() {
returnnull;
}

publicString[] getParameterValues(String parameter) {
returnnull;
}

publicString getProtocol() {
returnnull;
}

publicBufferedReader getReader()throwsIOException {
returnnull;
}

publicString getRemoteAddr() {
returnnull;
}

publicString getRemoteHost() {
returnnull;
}

publicString getScheme() {
returnnull;
}

publicString getServerName() {
returnnull;
}

publicintgetServerPort() {
return0;
}

publicvoidremoveAttribute(String attribute) {
}

publicvoidsetAttribute(String key, Object value) {
}

publicvoidsetCharacterEncoding(String encoding)
throwsUnsupportedEncodingException {
}

}

3. response

java 代码
packageex02.pyrmont;

importjava.io.OutputStream;
importjava.io.IOException;
importjava.io.FileInputStream;
importjava.io.FileNotFoundException;
importjava.io.File;
importjava.io.PrintWriter;
importjava.util.Locale;
importjavax.servlet.ServletResponse;
importjavax.servlet.ServletOutputStream;

publicclassResponseimplementsServletResponse {

privatestaticfinalintBUFFER_SIZE = 1024;
Request request;
OutputStream output;
PrintWriter writer;

publicResponse(OutputStream output) {
this.output = output;
}

publicvoidsetRequest(Request request) {
this.request = request;
}

/* This method is used to serve a static page */
publicvoidsendStaticResource()throwsIOException {
byte[] bytes =newbyte[BUFFER_SIZE];
FileInputStream fis =null;
try{
/* request.getUri has been replaced by request.getRequestURI */
File file =newFile(Constants.WEB_ROOT, request.getUri());
fis =newFileInputStream(file);
/*
HTTP Response = Status-Line
*(( general-header | response-header | entity-header ) CRLF)
CRLF
[ message-body ]
Status-Line = HTTP-Version SP Status-Code SP Reason-Phrase CRLF
*/
intch = fis.read(bytes, 0, BUFFER_SIZE);
while(ch!=-1) {
output.write(bytes, 0, ch);
ch = fis.read(bytes, 0, BUFFER_SIZE);
}
}
catch(FileNotFoundException e) {
String errorMessage ="HTTP/1.1 404 File Not Found\r\n"+
"Content-Type: text/html\r\n"+
"Content-Length: 23\r\n"+
"\r\n"+
"
File Not Found
";
output.write(errorMessage.getBytes());
}
finally{
if(fis!=null)
fis.close();
}
}


/** implementation of ServletResponse*/
publicvoidflushBuffer()throwsIOException {
}

publicintgetBufferSize() {
return0;
}

publicString getCharacterEncoding() {
returnnull;
}

publicLocale getLocale() {
returnnull;
}

publicServletOutputStream getOutputStream()throwsIOException {
returnnull;
}

publicPrintWriter getWriter()throwsIOException {
// autoflush is true, println() will flush,
// but print() will not.
writer =newPrintWriter(output,true);
returnwriter;
}

publicbooleanisCommitted() {
returnfalse;
}

publicvoidreset() {
}

publicvoidresetBuffer() {
}

publicvoidsetBufferSize(intsize) {
}

publicvoidsetContentLength(intlength) {
}

publicvoidsetContentType(String type) {
}

publicvoidsetLocale(Locale locale) {
}
}

4. 用于处理servlet的类ServletProcessor1

java 代码
packageex02.pyrmont;

importjava.net.URL;
importjava.net.URLClassLoader;
importjava.net.URLStreamHandler;
importjava.io.File;
importjava.io.IOException;
importjavax.servlet.Servlet;
importjavax.servlet.ServletRequest;
importjavax.servlet.ServletResponse;

publicclassServletProcessor1 {

publicvoidprocess(Request request, Response response) {

String uri = request.getUri();
String servletName = uri.substring(uri.lastIndexOf("/") + 1);
URLClassLoader loader =null;

try{
// create a URLClassLoader
URL[] urls =newURL[1];
URLStreamHandler streamHandler =null;
File classPath =newFile(Constants.WEB_ROOT);
// the forming of repository is taken from the createClassLoader method in
// org.apache.catalina.startup.ClassLoaderFactory
String repository = (newURL("file",null, classPath.getCanonicalPath() + File.separator)).toString() ;
// the code for forming the URL is taken from the addRepository method in
// org.apache.catalina.loader.StandardClassLoader class.
urls[0] =newURL(null, repository, streamHandler);
loader =newURLClassLoader(urls);
}
catch(IOException e) {
System.out.println(e.toString() );
}
Class myClass =null;
try{
myClass = loader.loadClass(servletName);
}
catch(ClassNotFoundException e) {
System.out.println(e.toString());
}

Servlet servlet =null;

try{
servlet = (Servlet) myClass.newInstance();
servlet.service((ServletRequest) request, (ServletResponse) response);
}
catch(Exception e) {
System.out.println(e.toString());
}
catch(Throwable e) {
System.out.println(e.toString());
}

}
}

5.处理静态资源的类


java 代码
packageex02.pyrmont;

importjava.io.IOException;

publicclassStaticResourceProcessor {

publicvoidprocess(Request request, Response response) {
try{
response.sendStaticResource();
}
catch(IOException e) {
e.printStackTrace();
}
}
}

6. 用于测试的servlet


java 代码
importjavax.servlet.*;
importjava.io.IOException;
importjava.io.PrintWriter;

publicclassPrimitiveServletimplementsServlet {

publicvoidinit(ServletConfig config)throwsServletException {
System.out.println("init");
}

publicvoidservice(ServletRequest request, ServletResponse response)
throwsServletException, IOException {
System.out.println("from service");
PrintWriter out = response.getWriter();
out.println("Hello. Roses are red.");
out.print("Violets are blue.");
}

publicvoiddestroy() {
System.out.println("destroy");
}

publicString getServletInfo() {
returnnull;
}
publicServletConfig getServletConfig() {
returnnull;
}

}

这个servlet服务器是一个很简单的实现,只能处理很简单的功能,比如将字符创输出到网页上。。

ServletProcessor1类实现了利用自建的ClassLoader加载自己的servlet,然后实例化这个servlet实现他的service方法。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值