springMvc框架实现

 springMvc框架是基于MVC设计模式,的spring实现,它主要一下三个核心功能
 1 跳转
 2 ioc
 3 aop(暂不实现)

自己手动书写springMvc框架,通过注解方式实现了跳转和ioc两个核心功能,工程结构如下:

分别创建注解@Controller

package com.hongsen.annotation;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Controller {
    String value();
}

创建@RequestMapping注解

package com.hongsen.annotation;

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestMapping {
    String value();
}

创建@resource注解

package com.hongsen.annotation;

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Resource {
    String value();
}

创建@Service注解

package com.hongsen.annotation;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Service {
    String value();
}

创建servlet,代码如下:

package com.hongsen.servlet;

/**
 * springMvc 作用
 * <p>
 * 1 跳转
 * 2 ioc
 * 3 aop
 *
 * @author wanghongsen 2018.07.27
 */

public class DispatcherServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;
    private List<String> classList = new ArrayList<>();
    private Map<String, Object> beanInstanceMap = new HashMap<>();
    private Map<String, Method> urlHandlerMap = new HashMap<>();

    /**
     * servlet初始化方法
     * 1 scan扫描包路径
     * 2 构造所有类集合 (list<String>)
     * 3 构造所有bean实例集合 (beanName-> bean)
     * 4 构造所有请求handler跳转(uri -> method)
     */
    public void init() throws ServletException {
        System.out.println("init() start");
        String scanBasePath = "com.hongsen";
        scan(scanBasePath);
        initBeanInstance();
        ioc();
        initUrlHandlerMap();
    }

    private void scan(String scanBasePath) {
        URL url = this.getClass().getResource("/" + scanBasePath.replace(".", "/"));
        String baseFilePath = url.getFile();
        File baseFile = new File(baseFilePath);
        String[] subFilePaths = baseFile.list();
        for (String subFilePath : subFilePaths != null ? subFilePaths : new String[0]) {
            File subFile = new File(baseFilePath + subFilePath);
            if (subFile.isDirectory()) {
                scan(scanBasePath + "." + subFilePath);
            } else {
                classList.add(scanBasePath + "." + subFilePath);
            }
        }
    }
    private void initBeanInstance() {
        for (String beanName : classList) {
            try {
                beanName = beanName.replace(".class", "");
                Class beanClass = Class.forName(beanName);
                try {
                    if (beanClass.isAnnotationPresent(Controller.class)) {
                        Controller controller = (Controller) beanClass.getAnnotation(Controller.class);
                        beanInstanceMap.put(controller.value(), beanClass.newInstance());
                    } else if (beanClass.isAnnotationPresent(Service.class)) {
                        Service service = (Service) beanClass.getAnnotation(Service.class);
                        beanInstanceMap.put(service.value(), beanClass.newInstance());
                    }
                } catch (InstantiationException | IllegalAccessException e) {
                    e.printStackTrace();
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
    private void ioc() {
        for (String beanName : classList) {
            try {
                beanName = beanName.replace(".class", "");
                Class beanClass = Class.forName(beanName);
                Field[] fields = beanClass.getDeclaredFields();
                for (Field field : fields) {
                    if (field.isAnnotationPresent(Resource.class)) {
                        Resource resource = field.getAnnotation(Resource.class);
                        String val = resource.value();
                        try {
                            field.setAccessible(true);
                            Service service = (Service) beanClass.getAnnotation(Service.class);
                            if (service != null) {
                                field.set(beanInstanceMap.get(service.value()), beanInstanceMap.get(val));
                            } else {
                                Controller controller = (Controller) beanClass.getAnnotation(Controller.class);
                                if (controller != null) {
                                    field.set(beanInstanceMap.get(controller.value()), beanInstanceMap.get(val));
                                }
                            }
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

    private void initUrlHandlerMap() {
        for (String beanName : classList) {
            try {
                beanName = beanName.replace(".class", "");
                Class beanClass = Class.forName(beanName);
                if (beanClass.isAnnotationPresent(RequestMapping.class)) {
                    RequestMapping baseReqMap = (RequestMapping) beanClass.getAnnotation(RequestMapping.class);
                    if (baseReqMap != null) {
                        String requestBaseUrl = baseReqMap.value();
                        Method[] methods = beanClass.getMethods();
                        for (Method method : methods) {
                            RequestMapping reqMap = method.getAnnotation(RequestMapping.class);
                            if (reqMap != null) {
                                urlHandlerMap.put(requestBaseUrl + reqMap.value(), method);
                            }
                        }
                    }
                }
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws javax.servlet.ServletException, IOException {

        String uri = request.getRequestURI();
        String contextPath = request.getContextPath();
        String requestUrl = uri.replace(contextPath, "");
        Method method = urlHandlerMap.get(requestUrl);
        if (method == null) {
            return;
        }
        Class beanClass = method.getDeclaringClass();
        Controller controller = (Controller) beanClass.getAnnotation(Controller.class);
        Object bean = beanInstanceMap.get(controller.value());
        try {
            Map<String, String[]> requestParameterMap = request.getParameterMap();

            Object[] args = new Object[requestParameterMap.entrySet().size()];
            int index = 0;
            for (Map.Entry entry : requestParameterMap.entrySet()) {
                args[index] = entry.getValue();
                index++;
            }
            method.invoke(bean, args);
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

创建完servlet后web.xml自动生成相应代码

<load-on-startup>加这个标签,tomcat启动时会自动加载指定的servlet  大于等于0时启动tomcat会加载 servlet的init()方法 数字越小代表加载的优先级越高

<url-pattern>/这个标签是tomcat请求扫描路径,扫到后会调用servlet相应的doGet或doPost方法

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>com.hongsen.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

创建Controller类

package com.hongsen.controller;

@Controller("testController")
@RequestMapping("/test")
public class TestController {

    @Resource("testAddService")
    private TestAddServiceImpl testAddService;

    @Resource("testDelService")
    private TestDelServiceImpl testDelService;

    @RequestMapping("/add.json")
    public void testAdd() {
        testAddService.add();
    }
    @RequestMapping("/del.json")
    public void testDel(Object num1, Object num2) {
        testDelService.del(num1.toString(), num2.toString());
    }
}

创建service接口和实现类

package com.hongsen.service;

public interface TestAddService {
    void add(String num);
}
package com.hongsen.service;

@Service("testAddService")
public class TestAddServiceImpl implements TestAddService{
    @Override
    public void add(String num) {
        System.out.println("add方法执行!");
    }
}

部署tomcat启动成功后:

访问:http://localhost:8080/test/add.json

原文地址:https://www.cnblogs.com/wanghongsen/p/9376914.html

时间: 2024-08-06 00:09:37

springMvc框架实现的相关文章

springMVC框架集成tiles模板

将tiles模板集成到springMVC框架下,大概流程如下: 1.在配置文件中加入tiles支持 我的servlet配置文件名为spring-mvc.xml.具体配置如下: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.

【转载】SpringMVC框架介绍

转自:http://com-xpp.iteye.com/blog/1604183 SpringMVC框架图 SpringMVC接口解释 DispatcherServlet接口: Spring提供的前端控制器,所有的请求都有经过它来统一分发.在DispatcherServlet将请求分发给Spring Controller之前,需要借助于Spring提供的HandlerMapping定位到具体的Controller. HandlerMapping接口: 能够完成客户请求到Controller映射.

SpringMVC框架整理(二)

SpringMVC框架整理第二发,数据绑定流程,数据校验(错误信息国际化),拦截器,异常处理. 数据绑定流程(数据转换,数据格式化,数据校验) 1. Spring MVC 主框架将 ServletRequest  对象及目标方法的入参实例传递给 WebDataBinderFactory 实例,以创建 DataBinder 实例对象 2. DataBinder 调用装配在 Spring MVC 上下文中的 ConversionService 组件进行数据类型转换.数据格式化工作.将 Servlet

关于springMVC框架访问web-inf下的jsp文件

问题:springMVC框架访问web-inf下的jsp文件,具体如下: 使用springMVC,一般都会使用springMVC的视图解析器,大概会这样配置 <property name="prefix" value="/WEB-INF/jsp/"></property> <property name="suffix" value=".jsp"></property> 当我的co

rapid-framework脚手架快速搭建springMVC框架项目

rapid-framework介绍:   一个类似ruby on rails的java web快速开发脚手架,本着不重复发明轮子的原则,框架只是将零散的struts(struts2)+spring+hibernate各个组件组装好在一起,并对struts及struts2进行改造,提供零配置编程,并内置一个强大的代码生成器及模板文件,可以生成java的hibernat model,dao,manager,struts+struts2 action类,可以生成jsp的增删改查及列表页面.  整个项目

springMVC框架下JQuery传递并解析Json数据

json作为一种轻量级的数据交换格式,在前后台数据交换中占领着很重要的地位.Json的语法很简单,採用的是键值对表示形式.JSON 能够将 JavaScript 对象中表示的一组数据转换为字符串,然后就能够在函数之间轻松地传递这个字符串,或者在异步应用程序中将字符串从 Web 客户机传递给server端程序,也能够从server端程序传递json格式的字符串给前端并由前端解释.这个字符串是符合json语法的,而json语法又是javascript语法的子集,所以javascript很easy解释

项目搭建系列之二:SpringMVC框架下配置MyBatis

1.什么是MyBatis? MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录. 回到目录 2.环境准备 搭建好SpringMVC框架,可以阅读<项目搭建系列之一:使用Maven搭建SpringMVC项目>,也可以直

springMVC框架在js中使用window.location.href请求url时IE不兼容问题解决

是使用springMVC框架时,有时候需要在js中使用window.location.href来请求url,比如下面的路径: window.location.href = 'forecast/download.do' 在谷歌浏览器下,实际请求的路径是:项目名/forecast/download.do 而在IE下访问时在中间多了好几层文件夹: 造成这种情况的原因是各种浏览器在使用window.localtion.href请求相对路径时处理方法不同 IE是从当前当前路径开始跳转 谷歌是从根目录开始跳

SpringMVC框架学习笔记(1)——HelloWorld

搭建SpringMVC框架 1.添加jar包 jsp-api.jar servlet-api.jar jstl.jar commons-logging-1.1.1.jar spring-beans-4.1.6.RELEASE.jar spring-context-4.1.6.RELEASE.jar spring-core-4.1.6.RELEASE.jar spring-expression-4.1.6.RELEASE.jar spring-tx-4.1.6.RELEASE.jar spring

[jbdj]SpringMVC框架(2)加载自定义目录下的springmvc.xml配置文件

自己定义文件目录,文件名称无疑是件快乐的事情! 如果springmvc.xml配置文件放在src目录下,web.xml代码如下: <?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/200