问题
PROBLEM : I'm using NanoHTTPD . It's working great but it's not serving .js files, images and others.
DETAILED EXPLANATION : i have a pages
folder inside of assets folder. This folder containing index.html
, css files, images and others. I'm using NanoHTTPD like this, but when i browse with my browser, there aren't any styles or images. Server can't found images and other files. There is only index.html file's content.
Activity :
MyHTTPD server = null;
try {
server = new MyHTTPD(getApplicationContext());
try
{
server.start();
}
catch( IOException ioe )
{
System.err.println( "Couldn't start server:\n" + ioe );
System.exit( -1 );
}
System.out.println( "Listening on port 8080. Hit Enter to stop.\n" );
try { System.in.read(); } catch( Throwable t ) {
System.out.println("read error");
};
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
MyHTTPD class
public Context ctx = null;
/**
* Constructs an HTTP server on given port.
*/
public MyHTTPD(Context ctx) throws IOException {
super(8080);
this.ctx = ctx;
}
@Override
public Response serve( String uri, Method method,
Map<String, String> header, Map<String, String> parms,
Map<String, String> files )
{
String html = null;
InputStream is = null;
try {
is = ctx.getAssets().open("pages/index.html");
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
byte[] b;
try {
b = new byte[is.available()];
is.read(b);
html = new String(b);
} catch (IOException e) { // TODO Auto-generated catch block
e.printStackTrace();
}
return new NanoHTTPD.Response(html);
}
NOTE : I've read this questions (and answers) : Using NanoHTTPD in Android file uploading error nanohttpd How to create nanohttpd server in android?
回答1:
in my serve()
method it looks like this:
@Override
public Response serve(String uri, String method, Properties header, Properties parms, Properties files) {
Log.d(TAG,"SERVE :: URI "+uri);
final StringBuilder buf = new StringBuilder();
for (Entry<Object, Object> kv : header.entrySet())
buf.append(kv.getKey() + " : " + kv.getValue() + "\n");
InputStream mbuffer = null;
try {
if(uri!=null){
if(uri.contains(".js")){
mbuffer = mContext.getAssets().open(uri.substring(1));
return new NanoHTTPD.Response(HTTP_OK, MIME_JS, mbuffer);
}else if(uri.contains(".css")){
mbuffer = mContext.getAssets().open(uri.substring(1));
return new NanoHTTPD.Response(HTTP_OK, MIME_CSS, mbuffer);
}else if(uri.contains(".png")){
mbuffer = mContext.getAssets().open(uri.substring(1));
// HTTP_OK = "200 OK" or HTTP_OK = Status.OK;(check comments)
return new NanoHTTPD.Response(HTTP_OK, MIME_PNG, mbuffer);
}else if (uri.contains("/mnt/sdcard")){
Log.d(TAG,"request for media on sdCard "+uri);
File request = new File(uri);
mbuffer = new FileInputStream(request);
FileNameMap fileNameMap = URLConnection.getFileNameMap();
String mimeType = fileNameMap.getContentTypeFor(uri);
Response streamResponse = new Response(HTTP_OK, mimeType, mbuffer);
Random rnd = new Random();
String etag = Integer.toHexString( rnd.nextInt() );
streamResponse.addHeader( "ETag", etag);
streamResponse.addHeader( "Connection", "Keep-alive");
return streamResponse;
}else{
mbuffer = mContext.getAssets().open("index.html");
return new NanoHTTPD.Response(HTTP_OK, MIME_HTML, mbuffer);
}
}
} catch (IOException e) {
Log.d(TAG,"Error opening file"+uri.substring(1));
e.printStackTrace();
}
return null;
}
There is some not so clean solution with mime types. Validation should be done with something like this Getting A File's Mime Type In Java, I my simple project I am just checking few kinds of mime.
Reference mime types are static fields in NanoHTTPD class:
/**
* Common mime types for dynamic content
*/
public static final String
MIME_PLAINTEXT = "text/plain",
MIME_HTML = "text/html",
MIME_JS = "application/javascript",
MIME_CSS = "text/css",
MIME_PNG = "image/png",
MIME_DEFAULT_BINARY = "application/octet-stream",
MIME_XML = "text/xml";
With this implementation I was able to read files from assets as well as from external memory.
来源:https://stackoverflow.com/questions/17102954/why-images-and-style-files-couldnt-found-on-nanohttpd