xie233 / Note

some ex
0 stars 0 forks source link

简易MVC #3

Open xie233 opened 5 years ago

xie233 commented 5 years ago

需要用的的注解

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NPAutowired {
    String value() default "";
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NPService {
    String value() default "";
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NPController {

    String value() default "";
}
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NPRequestMapping {
    String value() default "";
}
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NPRequestParam {
    String value() default "";
}

提供的一个简单服务


public interface IDemoService {

    String get(String name);
}
import mvc.core.NPService;
@NPService
public class DemoImpl implements IDemoService {

    @Override
    public String get(String name) {
        return name+ " is 18";
    }
}

一个例子,相应的路径触发相应的方法

import mvc.core.NPAutowired;
import mvc.core.NPController;
import mvc.core.NPRequestMapping;
import mvc.core.NPRequestParam;
import mvc.example.service.IDemoService;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@NPController
@NPRequestMapping("/example")
public class ExampleAction {

    @NPAutowired
    private IDemoService demoService;

    @NPRequestMapping("/query")
    public void query(HttpServletRequest req,
                      HttpServletResponse resp,
                      @NPRequestParam("name") String name){
        String result = demoService.get(name);
        try{

            resp.getWriter().write(result);
        }catch (IOException e){
            e.printStackTrace();
        }
    }

    @NPRequestMapping("/plus")
    public void plus(HttpServletRequest req,
                    HttpServletResponse resp,
                    @NPRequestParam("a") Integer a,
                    @NPRequestParam("b") Integer b){
        try{
            resp.getWriter().write(a+"+"+b+"="+(a+b));
        }catch (IOException e){
            e.printStackTrace();
        }
    }

}
xie233 commented 5 years ago

最主要的核心类,负责初始化以及事件分发

    public void init(ServletConfig config) throws ServletException {
'''最开始执行初始化操作,加载扫描路径,扫描包含注解的类,
初始化相应类以及用一个ioc包装类与实例和接口与实现类实例的的映射,
再包装用户请求路径与执行方法的映射
'''
        doLoadConfig(config.getInitParameter(LOCATION));
        doScanner(p.getProperty("scanPackage"));
        doInstance();
        doAutowired();
        initHandlerMapping();
        System.out.println("mvc is init");
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try{
            doDispatch(req,resp);
        }catch (Exception e){
            resp.getWriter().write("Your input is wrong");
        }
    }

    private void doDispatch(HttpServletRequest req,HttpServletResponse resp) throws Exception{
        if(this.handleMapping.isEmpty()){
            return;
        }
        String url = req.getRequestURI();
//        String contextPath = req.getContextPath();

        if(!this.handleMapping.containsKey(url)){

            resp.getWriter().write("404 NOT FOUND");
            return;
        }

        Method method = this.handleMapping.get(url);
//根据参数类型返回相应值给调用方法
        Class<?>[] parameterTypes = method.getParameterTypes();
        Map<String,String[]> parameterMap = req.getParameterMap();
        Object[] paramValues = new Object[parameterTypes.length];
        Iterator params = parameterMap.entrySet().iterator();
        for(int i=0;i<parameterTypes.length;i++){
            Class parameterType = parameterTypes[i];
            if(parameterType == HttpServletRequest.class){
                paramValues[i] = req;
                continue;
            }else if(parameterType==HttpServletResponse.class){
                paramValues[i] = resp;
                continue;
            }else if(parameterType==String.class){
                Map.Entry<String,String[]> param = (Map.Entry<String,String[]>)params.next();
                String value = Arrays.toString(param.getValue())
                        .replaceAll("\\[|\\]","")
                        .replaceAll(",\\s",",");
                paramValues[i] = value;

            }else if(parameterType==Integer.class){
                Map.Entry<String,String[]> param = (Map.Entry<String,String[]>)params.next();
                Integer value = Integer.valueOf(param.getValue()[0]);
                paramValues[i] = value;
            }
        }
        try{
            String beanName = lowerFirstCase(method.getDeclaringClass().getSimpleName());
            method.invoke(this.ioc.get(beanName),paramValues);
        }catch (Exception e){
            e.printStackTrace();
        }

    }
xie233 commented 5 years ago

在web.xml 配置好初始参数和serlvet映射就差不多了,选择tomcat容器,进行启动,访问http://localhost:8080/example/plus?a=11&b=2 即可得到 image

后续还可增加Named注解 分配服务的多个实现类