上一篇Java模拟服务器(Java模拟服务器(Version_1.0)),对比Version_2.0版本的区别
Java模拟服务器version_1.0中的WebApp类维护的映射其实就是在写JavaWeb时写的web.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>com.shsxt.controller.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/log</url-pattern>
</servlet-mapping>
</web-app>
现在,在版本二中我们要达到什么目的呢?
版本一中,我们需要配置映射关系,我们觉得很麻烦。那么在版本二中,我们通过注解做,我们先来看一下程序分析图
项目包图:
注解类:
package tomcat.annotation;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE) //该注解作用于类
public @interface WebServlet {
String[] value(); //Servlet的访问URL
}
扫描包的工具类:博客:https://mp.csdn.net/postedit/82112233
Web_Xml类:
/*
* 相当于配置文件
*/
public class Web_Xml {
private String basePackage; //提供一个包名
public String getBasePackage() {
return basePackage;
}
public void setBasePackage(String basePackage) {
this.basePackage = basePackage;
}
}
ServletContext类:
/*
* 通过这个类获取对应的servlet
*/
public class ServletContext {
//测试数据
private static Web_Xml web=new Web_Xml();
private String servletUrl;
static {
web.setBasePackage("tomcat.servlet");
}
public Servlet getServlet(String url) throws InstantiationException, IllegalAccessException, ClassNotFoundException{
servletUrl=new FindServlet(web.getBasePackage()).findServletByUrl(url);
return (Servlet) Class.forName(servletUrl).newInstance();
}
}
FindServlet类:
public class FindServlet {
private String packageName;//包名
/**
* 构造函数
* @param basePackage
*/
public FindServlet(String packageName) {
this.packageName=packageName;
}
/**
* 返回找到的Servlet
* @return
*/
public String findServletByUrl(String url) {
List<Class<?>> ls=new ArrayList<>();
ls=MyClassUtil.getClassListByAnnotation(packageName, WebServlet.class,true);
for(Class<?> clz:ls){
WebServlet web=(WebServlet) clz.getAnnotation(WebServlet.class);
boolean flag=true;
for(int i=0;i<web.value().length && flag;i++){
if(web.value()[i].equals(url)){
flag=false;
return clz.getName().toString();
}
}
}
return null;
}
}
LoginServlet类:
@WebServlet(value={"/login","/log"}) //加上注解
public class LoginServlet extends Servlet{
@Override
public void doGet(Request req, Response resp) {
String name=req.getParemter("uname");
String respContent="<!DOCTYPE html><html><head><title>欢迎登陆</title></head><body>欢迎"+name+"登陆</body></html>";
resp.print(respContent);
try {
resp.pushToClient(200);
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void doPost(Request req, Response resp) {
}
}
注:Request、Response、Server、Dispacher、Servlet以及前端的测试代码都与版本一相同,这里不再赘述。
思考:我们将代码封装起来,方便了使用,但同时也降低了效率,为了取到对应的Servlet,我们需要对包进行扫描。版本二,主要是学习怎么使用注解,注解对于框架也是一个很重要的知识点(这里先有一个初步的认识就好)。