《Android版Web服务器实现(二)使用服务来监听HTTP请求》一文实现了HTTP请求的监听,那么我们要如何作出响应呢?在响应时,有几种情况。
1、请求的方法不支持。比如服务端仅支持了GET/POST方法,而请求却有DELETE等,此时回复501。
2、请求的资源不存在。在服务端不存在该资源文件,将回复404页面。
3、请求的类型不支持。服务端可能存在该资源,但是该资源的类型没有支持,将回复404.7。
4、请求正常。服务端将相应的资源回复给客户端。
5、其他情况。
下面是依据这些情况的代码实现。
SessionThread.java
package com.sparkle.webservice; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import android.util.Log; public class SessionThread extends Thread { private Socket _clientSocket = null; private final int BUFFER_MAX = 8192; private DataHandle _dataHandle = null; private MyLog _myLog = new MyLog(getClass().getName()); public SessionThread(Socket clientSocket) { this._clientSocket = clientSocket; } public void closeSocket() { if (_clientSocket == null) { return; } try { _clientSocket.close(); } catch (IOException e) { _myLog.e(e.getMessage()); } } public void run() { try { InputStream socketInput = _clientSocket.getInputStream(); byte[] buffer = new byte[BUFFER_MAX]; socketInput.read(buffer); _dataHandle = new DataHandle(buffer); byte[] content = _dataHandle.fetchContent(); sendResponse(_clientSocket, content); } catch (Exception e) { _myLog.l(Log.DEBUG, "Exception in TcpListener"); } } private void sendResponse(Socket clientSocket, byte[] content) { try { OutputStream socketOut = clientSocket.getOutputStream(); byte[] header = _dataHandle.fetchHeader(content.length); socketOut.write(header); socketOut.write(content); socketOut.close(); clientSocket.close(); } catch (Exception e) { } } }注:
1、在收到请求后,新建一个SessionThread来处理请求(在上一篇中有说到)。
2、SessionThread建立后,在run中新建DataHandle来处理数据,具体请参看后文代码。
3、在sendResponse来回应请求。
4、在响应时,先发送header,再发送content来响应
DataHandle.java
package com.sparkle.webservice; import java.io.UnsupportedEncodingException; import com.sparkle.io.FileSp; import android.annotation.SuppressLint; import android.util.Log; public class DataHandle { private String _receiveInfo = ""; private HttpHeader _httpHeader = null; private String _encoding = "utf-8"; private String _serverName = "Simple Web Server"; private String _responseCode = "200 OK"; private String _contentType = "text/html"; public DataHandle(byte[] recieveData) { try { this._receiveInfo = new String(recieveData, _encoding); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } _httpHeader = new HttpHeader(_receiveInfo); } public byte[] fetchContent() { byte[] backData = null; if (!isSupportMethod()) { backData = fetchNotSupportMethodBack(); return backData; } String filePath = fetchFilePath(); boolean hasFile=FileSp.isExist(filePath); Log.e("FilePath", filePath+" "+hasFile); if (!hasFile) { backData = fetchNotFoundBack(); return backData; } if (!isSupportExtension()) { backData = fetchNotSupportFileBack(); return backData; } backData = fetchBackFromFile(filePath); return backData; } public byte[] fetchHeader(int contentLength) { byte[] header = null; try { header = ("HTTP/1.1 " + _responseCode + " " + "Server: "+ _serverName + " " + "Content-Length: " + contentLength+ " " + "Connection: close " + "Content-Type: "+ _contentType + ";charset="+_encoding+" ").getBytes(_encoding); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return header; } @SuppressLint("DefaultLocale") private boolean isSupportMethod() { String method = _httpHeader.getMethod(); if (method == null || method.length() <= 0) { return false; } method = method.toUpperCase(); if (method.equals("GET") || method.equals("POST")) { return true; } return false; } private boolean isSupportExtension() { String contentType = _httpHeader.getContentType(); if (contentType == null || contentType.length() <= 0) { return false; } _contentType=contentType; return true; } private byte[] fetchNotSupportMethodBack() { byte[] backData = null; String notImplementMethod = "<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body><h2>" + _serverName + "</h2><div>501 - Method Not Implemented</div></body></html>"; try { backData = notImplementMethod.getBytes(_encoding); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return backData; } private byte[] fetchNotSupportFileBack() { byte[] backData = null; String notImplementMethod = "<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body><h2>" + _serverName + "</h2><div>404.7 Not Found(Type Not Support)</div></body></html>"; try { backData = notImplementMethod.getBytes(_encoding); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return backData; } private byte[] fetchBackFromFile(String filePath) { byte[] content = null; content = FileSp.read(filePath); return content; } private String fetchFilePath() { String root = Defaults.getRoot(); String fileName = _httpHeader.getFileName(); String filePath = ""; if (fileName.startsWith("/") || fileName.startsWith("\")) { filePath = root + fileName.substring(1); } else { filePath = root + fileName; } return filePath; } private byte[] fetchNotFoundBack() { byte[] notFoundData = null; String notFoundStr = "<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body><h2>" + _serverName + "</h2><div>404 - Not Found</div></body></html>"; try { notFoundData = notFoundStr.getBytes(_encoding); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return notFoundData; } }注:
1、isSupportMethod判断是否是支持的方法,如果不支持,从fetchNotSupportMethodBack获取数据进行响应。
2、判断请求的资源是否存在,如果不存在,从fetchNotFoundBack获取数据进行响应。
3、isSupportExtension判断是否是支持的数据类型,如果不支持,从fetchNotSupportFileBack获取数据进行响应。
4、请求方法支持、请求资源存在,且请求类型支持,将从fetchBackFromFile获取数据进行响应。
在对HTTP作出相应的响应之后,现在就剩下如果在界面中实现相应的控制了,具体请看下一篇。
转载请注明出处:Android版Web服务器实现(三)HTTP响应