3.7Servlet忘記實現(xiàn)HttpServlet接口處理【理解】
出現(xiàn)情況
在寫Servlet時,忘記了實現(xiàn)HttpServlet接口
導致結果
在反射創(chuàng)建對象后,強轉成HttpServlet時,會報類型轉換異常
解決方案
在反射創(chuàng)建對象后,強轉成HttpServlet前,進行判斷如果有實現(xiàn)HttpServlet接口,就進行強轉否則拋出一個異常
public class PropertiesParseServletConfig implements ParseServletConfig {
@Override
public void parse() {
try {
//1.讀取配置文件中的數(shù)據(jù)
Properties properties = new Properties();
FileReader fr = new FileReader("http‐dynamic‐server/webApp/config/servlet‐info.properties");
properties.load(fr);
fr.close();
//2.獲取集合中servlet‐info的屬性值
String properValue = (String) properties.get("servlet‐info");
// uri,全類名;uri,全類名
//3.解析
String[] split = properValue.split(";");
for (String servletInfo : split) {
String[] servletInfoArr = servletInfo.split(",");
String uri = servletInfoArr[0];
String servletName = servletInfoArr[1];
//我們需要通過servletName(全類名)來創(chuàng)建他的對象
Class clazz = Class.forName(servletName);
//獲取該類所實現(xiàn)的所有的接口信息,得到的是一個數(shù)組
Class[] interfaces = clazz.getInterfaces();
//定義一個boolean類型的變量
boolean flag = false;
//遍歷數(shù)組
for (Class clazzInfo : interfaces) {
//判斷當前所遍歷的接口的字節(jié)碼對象是否和HttpServlet的字節(jié)碼文件對象相同
if(clazzInfo == HttpServlet.class){
//如果相同,就需要更改flag值.結束循環(huán)
flag = true;
break;
}
}
if(flag){
//true就表示當前的類已經(jīng)實現(xiàn)了HttpServlet接口
HttpServlet httpServlet = (HttpServlet) clazz.newInstance();
//4.將uri和httpServlet添加到map集合中
ServletConcurrentHashMap.map.put(uri,httpServlet);
}else{
//false就表示當前的類還沒有實現(xiàn)HttpServlet接口
throw new NotImplementsHttpServletException(clazz.getName() + "Not
Implements HttpServlet");
}
}
} catch (NotImplementsHttpServletException e) {
e.printStackTrace();
}catch (Exception e) {
System.out.println("解析數(shù)據(jù)異常.....");
e.printStackTrace();
}
}
}
3.8響應404【理解】
出現(xiàn)情況
客戶端瀏覽器請求了一個服務器中不存在的動態(tài)資源
導致結果
服務器中代碼出現(xiàn)異常,程序停止
解決方案
如果請求的動態(tài)資源不存在,服務器根據(jù)請求的uri找到對應的Servlet時為null,繼續(xù)調用方法會出現(xiàn)異常增加一個非空的判斷,如果不為null,則繼續(xù)處理請求,調用方法如果為null,則響應404
public class DynamicResourceProcess {
//執(zhí)行指定動態(tài)資源的service方法
//參數(shù)一
//由于后期可能根據(jù)用戶請求的uri做出相應的處理.
//參數(shù)二
//要給用戶響應數(shù)據(jù),那么就需要使用到httpResponse.
public void process(HttpRequest httpRequest,HttpResponse httpResponse){
//獲取請求的uri
String requestURI = httpRequest.getRequestURI();
//根據(jù)請求的uri到map集合中直接找到對應的servlet的對象
HttpServlet httpServlet = ServletConcurrentHashMap.map.get(requestURI);
if(httpServlet != null){
//調用service方法對請求進行處理并響應
httpServlet.service(httpRequest,httpResponse);
}else{
//瀏覽器請求的動態(tài)資源不存在
//響應404
response404(httpResponse);
}
}
//瀏覽器請求動態(tài)資源不存在,響應404的方法
private void response404(HttpResponse httpResponse) {
try {
//準備響應行
String responseLine = "HTTP/1.1 404 NOT FOUNDrn";
//準備響應頭
String responseHeader = "Content‐Type: text/html;charset=UTF‐8rn";
//準備響應空行
String emptyLine = "rn";
//拼接在一起
String result = responseLine + responseHeader + emptyLine;
//把響應行,響應頭,響應空行去響應給瀏覽器
SelectionKey selectionKey = httpResponse.getSelectionKey();
SocketChannel channel = (SocketChannel) selectionKey.channel();
ByteBuffer byteBuffer1 = ByteBuffer.wrap(result.getBytes());
channel.write(byteBuffer1);
//給瀏覽器 響應 響應體內(nèi)容
ByteBuffer byteBuffer2 = ByteBuffer.wrap("404 NOT FOUND....".getBytes());
channel.write(byteBuffer2);
//釋放資源
channel.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}