1.写一个Mvc框架_超轻量级MVC框架的设计和实现

java实现的轻量级web MVC框架         该项目是一个轻量级MVC框架,重点实现了IOC和AOP特性,适合需要学习这两方面知识的人。这个项目是博主在git上找到并且自己做了修改和注释的。希望可以帮到大家,也促进我自己的学习。其中原git地址为:git地址:https://github.com/wacxt/light-framework。博主的git地址为:https://github.com... 阅读详情
  超轻量级MVC框架的设计和实现  2009-11-17 16:01:15

分类: Java

1.设计背景
   前段时间准备做一个小网站,但是又不想用Spring/Struts/WebWork这样的大块头,因此决定自己写一个MVC框架。花了3天左右时间完成,目前运行良好,整个MVC框架仅21KB,感兴趣的朋友可以从http://code.google.com/p/lightweight-mvc/downloads/list下载完整的源代码和jar包。

2.设计目标
   一个最简单最小巧的MVC框架,花哨的功能一个不要,越简洁越好,并且不使用XML配置文件,而是完全用Java 5注解配置。

3.功能列表
   .组件必须用IoC配置
   .处理HTTP请求的Action,类似WebWork每个请求都生成一个新实例,并自动填充属性
   .类似Filter的Interceptor机制,但是在IoC容器中配置
   .统一的异常处理
   .多视图支持

   由于组件需要用IoC容器配置,因此,第一步就是寻找小巧的IoC容器,Google Guice是一个很不错的选择,并且完全用Java 5注解配置组件。这个MVC框架唯一依赖的也就是Guice和Commons Logging两个jar包,如果使用Velocity作为视图则还需要Velocity的jar包。

4.设计各主要功能类
4.1Action接口
   负责处理Http请求的Action类必须实现的Action接口

package com.javaeedev.lightweight.mvc;
public interface Action {
    ModelAndView execute() throws Exception;
}
   从WebWork抄过来,不过返回值由String改成了ModelAndView(从Spring抄过来的),好处是不必再次根据String查找视图的绝对路径,直接在ModelAndView中包含了。用Spring的MVC其实可以发现,ModelAndView同时包含一个Model(本质是一个 Map)和View的路径,减少了Struts和WebWork需要的一个XML映射文件,而维护XML配置文件是一件相当令人头疼的问题,往往改了代码还要改配置,索性写死在代码中得了,视图路径又不会经常改变,没必要为了额外的灵活性给自己搞一堆XML配置文件。

4.2Action返回模型ModelAndView
   Action返回的ModelAndView:
package com.javaeedev.lightweight.mvc;
public final class ModelAndView {

    private String view;
    private Map model;

    /**
     * Construct a View with empty model.
     * @param view View's logic name.
     */
    public ModelAndView(String view) {
        this.view = view;
        this.model = Collections.emptyMap();
    }

    /**
     * Construct a View with model.
     * @param view View's logic name.
     * @param model Model as a Map.
     */
    public ModelAndView(String view, Map model) {
        this.view = view;
        this.model = model;
    }

    /**
     * Return View.
     * @return View's logic name.
     */
    public String getView() {
        return view;
    }

    /**
     * Return model.
     * @return Model as a Map.
     */
    public Map getModel() {
        return model;
    }
}
   这个完全是从Spring MVC抄过来的,Map改成了泛型,View路径可以以"redirect:"开头表示重定向,这个和Spring MVC一致。虽然直接调用HttpServletResponse也可以重定向,但是遇到事务处理起来会很麻烦,还是让MVC框架自己来处理会好一些。

4.3类ActionContext
   WebWork的Action设计的好处是大大简化了参数的绑定,不过很多时候也需要在Action中访问HttpSession等对象,因此还需要设计一个ActionContext类,通过ThreadLocal让Action对象能轻易地访问到这些对象:

package com.javaeedev.lightweight.mvc;
public final class  ActionContext {
    private static ThreadLocal contextThreadLocal = new ThreadLocal();

    private HttpServletRequest request;
    private HttpServletResponse response;
    private HttpSession session;
    private ServletContext context;

    /**
     * Get current ActionContext.
     * @return ActionContext.
     */
    public static ActionContext getActionContext() {
        return contextThreadLocal.get();
    }

    /**
     * Initiate all servlet objects as thread local.
     * @param request HttpServletRequest object.
     * @param response HttpServletResponse object.
     * @param session HttpSession object.
     * @param context ServletContext object.
     */
    static void setActionContext(HttpServletRequest request, HttpServletResponse response, HttpSession session, ServletContext context) {
        ActionContext actionContext = new ActionContext();
        actionContext.setRequest(request);
        actionContext.setResponse(response);
        actionContext.setSession(session);
        actionContext.setServletContext(context);
        contextThreadLocal.set(actionContext);
    }

    /**
     * Remove all servlet objects from thread local.
     */
    static void remove() {
        contextThreadLocal.remove();
    }

    /**
     * Get HttpServletRequest object.
     *
     * @return HttpServletRequest object.
     */
    public HttpServletRequest getRequest() {
        return request;
    }

    /**
     * Set HttpServletRequest object.
     *
     * @param request HttpServletRequest object.
     */
    void setRequest(HttpServletRequest request) {
        this.request = request;
    }

    /**
     * Get HttpServletResponse object.
     *
     * @return HttpServletResponse object.
     */
    public HttpServletResponse getResponse() {
        return response;
    }

    /**
     * Set HttpServletResponse object.
     *
     * @param response HttpServletResponse object.
     */
    void setResponse(HttpServletResponse response) {
        this.response = response;
    }

    /**
     * Get HttpSession object.
     *
     * @return HttpSession object.
     */
    public HttpSession getSession() {
        return session;
    }

    /**
     * Set HttpSession object.
     *
     * @param session HttpSession object.
     */
    void setSession(HttpSession session) {
        this.session = session;
    }

    /**
     * Get ServletContext object.
     *
     * @return ServletContext object.
     */
    public ServletContext getServletContext() {
        return context;
    }

    /**
     * Set ServletContext object.
     *
     * @param context ServletContext object.
     */
    void setServletContext(ServletContext context) {
        this.context = context;
    }

}

4.4接口Interceptor
   定义类似Filter功能的Interceptor接口:
package com.javaeedev.lightweight.mvc;
/**
 * Intercept action's execution like servlet Filter, but interceptors are
 * configured and managed by IoC container. Another difference from Filter
 * is that Interceptor is executed around Action's execution, but before
 * rendering view.
 *
 * @author Xuefeng
 */
public interface Interceptor {
    /**
     * Do intercept and invoke chain.doInterceptor() to process next interceptor.
     * NOTE that process will not continue if chain.doInterceptor() method is not
     * invoked.
     *
     * @param action Action instance to handle http request.
     * @param chain Interceptor chain.
     * @throws Exception If any exception is thrown, process will not continued.
     */
    void intercept(Action action, InterceptorChain chain) throws Exception;

}
   InterceptorChain对象和FilterChain是一样的,它允许一个拦截器是否将请求继续交给下一拦截器处理,还是中断当前请求的处理:

package com.javaeedev.lightweight.mvc;
/**
 * Holds all interceptors as a chain.
 *
 * @author Xuefeng
 */
public interface InterceptorChain {
    /**
     * Apply next interceptor around the execution of Action.
     *
     * @param action Target Action to execute.
     * @throws Exception Any exception if error occured.
     */
    void doInterceptor(Action action) throws Exception;
}

4.5类ViewResolver
   最后是支持多种View的ViewResolver,这个也抄自Spring MVC:
package com.javaeedev.lightweight.mvc;
import java.io.IOException;
import java.util.Map;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * To resolve and render a view.
 *
 * @author Xuefeng
 */
public interface ViewResolver {
    /**
     * Init this ViewResolver.
     *
     * @param context ServletContext object that holds information of current
     *                web application.
     * @throws ServletException If init failed.
     */
     void init(ServletContext context) throws ServletException;

    /**
     * To resolve view's name and render view if necessary.
     *
     * @param view View's logic name.
     * @param model Model represent as a generic Map.
     * @param request HttpServletRequest object.
     * @param response HttpServletResponse object.
     * @throws ServletException If any ServletException occur.
     * @throws IOException If any IOException occur.
     */
     void resolveView(String view, Map model, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException;

}
   第一个版本支持JSP和Velocity两种View,其实支持其他的View完全是可扩展的,只需要参考现有的两种ViewResolver的实现再写一个实现即可,例如支持FreeMarker的ViewResolver。
   到此为止,提供给客户端的API准备完毕。下一步是如何实现这些API。虽然概念和结构都来自WebWork和Spring,但是其具体实现却没有参考他们的源代码,因为读大块头的源码本身就是一件非常费力的事情,还不如自己身体力行,写代码往往比读懂代码更快。

5.开发MVC具体实现类
   MVC框架的核心是一个DispatcherServlet,用于接收所有的HTTP请求,并根据URL选择合适的Action对其进行处理。在这里,和Struts不同的是,所有的组件均被IoC容器管理,因此,DispatcherServlet需要实例化并持有Guice IoC容器,此外,DispatcherServlet还需要保存URL映射和Action的对应关系,一个Interceptor拦截器链,一个 ExceptionResolver处理异常。

5.1类DispatcherServlet
package com.javaeedev.lightweight.mvc;
/**
 * Core dispatcher servlet.
 *
 * @author Xuefeng
 */
public class DispatcherServlet extends HttpServlet {

    private Log log = LogFactory.getLog(getClass());

    private Map actionMap;
    private Interceptor[] interceptors = null;
    private ExceptionResolver exceptionResolver = null;
    private ViewResolver viewResolver = null;

    private Injector injector = null; // Guice IoC容器

    ...
}
   Guice 的配置完全由Java 5注解完成,而在DispatcherServlet中,我们需要主动从容器中查找某种类型的Bean,相对于客户端被动地使用IoC容器(客户端甚至不能感觉到IoC容器的存在),DispatcherServlet需要使用ServiceLocator模式主动查找Bean,写一个通用方法:

private List<key<? style="word-wrap: break-word;">> findKeysByType(Injector inj, Class type) {
    Map<key<? style="word-wrap: break-word;">, Binding> map = inj.getBindings();
    List<key<? style="word-wrap: break-word;">> keyList = new ArrayList<key<? style="word-wrap: break-word;">>();
    for(Key key : map.keySet()) {
        Type t = key.getTypeLiteral().getType();
        if(t instanceof Class) {
            Class clazz = (Class) t;
            if(type==null || type.isAssignableFrom(clazz)) {
                keyList.add(key);
            }
        }
    }
    return keyList;
}

DispatcherServlet初始化时就要首先初始化Guice IoC容器:

public void init(ServletConfig config) throws ServletException {
    String moduleClass = config.getInitParameter("module");
    if(moduleClass==null || moduleClass.trim().equals(""))
        throw new ServletException("Cannot find init parameter in web.xml: "
                + "?"
                + getClass().getName()
                + "module"
                + "put-your-config-module-full-class-name-here");
    ServletContext context = config.getServletContext();
    // init guice:
    injector = Guice.createInjector(Stage.PRODUCTION, getConfigModule(moduleClass.trim(), context));
    ...
}

然后,从IoC容器中查找Action和URL的映射关系:

private Map getUrlMapping(List<key<? style="word-wrap: break-word;">> actionKeys) {
    Map urlMapping = new HashMap();
    for(Key key : actionKeys) {
        Object obj = safeInstantiate(key);
        if(obj==null)
            continue;
        Class actionClass = (Class) obj.getClass();
        Annotation ann = key.getAnnotation();
        if(ann instanceof Named) {
            Named named = (Named) ann;
            String url = named.value();
            if(url!=null)
                url = url.trim();
            if(!"".equals(url)) {
                log.info("Bind action [" + actionClass.getName() + "] to URL: " + url);
                // link url with this action:
                urlMapping.put(url, new ActionAndMethod(key, actionClass));
            }
            else {
                log.warn("Cannot bind action [" + actionClass.getName() + "] to *EMPTY* URL.");
            }
        }
        else {
            log.warn("Cannot bind action [" + actionClass.getName() + "] because no @Named annotation found in config module. Using: binder.bind(MyAction.class).annotatedWith(Names.named(\"/url\"));");
        }
    }
    return urlMapping;
}

我们假定客户端是以如下方式配置Action和URL映射的:

public class MyModule implements Module {

    public void configure(Binder binder) {
        // bind actions:
        binder.bind(Action.class)
              .annotatedWith(Names.named("/start.do"))
              .to(StartAction.class);
        binder.bind(Action.class)
              .annotatedWith(Names.named("/register.do"))
              .to(RegisterAction.class);
        binder.bind(Action.class)
              .annotatedWith(Names.named("/signon.do"))
              .to(SignonAction.class);
        ...
    }
}

即通过Guice提供的一个注解Names.named()指定URL。当然还可以用其他方法,比如标注一个@Url注解可能更方便,下一个版本会加上。

Interceptor,ExceptionResolver和ViewResolver也是通过查找获得的。

下面讨论DispatcherServlet如何真正处理用户请求。第一步是根据URL查找对应的Action:

String contextPath = request.getContextPath();
String url = request.getRequestURI().substring(contextPath.length());
if(log.isDebugEnabled())
    log.debug("Handle for URL: " + url);
ActionAndMethod am = actionMap.get(url);
if(am==null) {
    response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404 Not Found
    return;
}

没找到Action就直接给个404 Not Found,找到了进行下一步,实例化一个Action并填充参数:

// init ActionContext:
HttpSession session = request.getSession();
ServletContext context = session.getServletContext();

ActionContext.setActionContext(request, response, session, context);

// 每次创建一个新的Action实例:
Action action = (Action) injector.getInstance(am.getKey());
// 把HttpServletRequest的参数自动绑定到Action的属性中:
List props = am.getProperties();
for(String prop : props) {
    String value = request.getParameter(prop);
    if(value!=null) {
        am.invokeSetter(action, prop, value);
    }
}

注意,为了提高速度,所有的set方法已经预先缓存了,因此避免每次请求都用反射重复查找Action的set方法。

然后要应用所有的Interceptor以便拦截Action:

InterceptorChainImpl chains = new InterceptorChainImpl(interceptors);
chains.doInterceptor(action);
ModelAndView mv = chains.getModelAndView();

实现InterceptorChain看上去复杂,其实就是一个简单的递归,大家看InterceptorChainImpl代码就知道了:

package com.javaeedev.lightweight.mvc;

/**
 * Used for holds an interceptor chain.
 *
 * @author Xuefeng
 */
class InterceptorChainImpl implements InterceptorChain {

    private final Interceptor[] interceptors;
    private int index = 0;
    private ModelAndView mv = null;

    InterceptorChainImpl(Interceptor[] interceptors) {
        this.interceptors = interceptors;
    }

    ModelAndView getModelAndView() {
        return mv;
    }

    public void doInterceptor(Action action) throws Exception {
        if(index==interceptors.length)
            // 所有的Interceptor都执行完毕:
            mv = action.execute();
        else {
            // 必须先更新index,再调用interceptors[index-1],否则是一个无限递归:
            index++;
            interceptors[index-1].intercept(action, this);
        }
    }
}

把上面的代码用try ... catch包起来,就可以应用ExceptionResolver了。

如果得到了ModelAndView,最后一步就是渲染View了,这个过程极其简单:

// render view:
private void render(ModelAndView mv, HttpServletRequest reqest, HttpServletResponse response) throws ServletException, IOException {
    String view = mv.getView();
    if(view.startsWith("redirect:")) {
        // 重定向:
        String redirect = view.substring("redirect:".length());
        response.sendRedirect(redirect);
        return;
    }
    Map model = mv.getModel();
    if(viewResolver!=null)
        viewResolver.resolveView(view, model, reqest, response);
}

最简单的JspViewResolver的实现如下:

package com.javaeedev.lightweight.mvc.view;

/**
 * Let JSP render the model returned by Action.
 *
 * @author Xuefeng
 */
public class JspViewResolver implements ViewResolver {

    /**
     * Init JspViewResolver.
     */
    public void init(ServletContext context) throws ServletException {
    }

    /**
     * Render view using JSP.
     */
    public void resolveView(String view, Map model, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        if(model!=null) {
            Set keys = model.keySet();
            for(String key : keys) {
                request.setAttribute(key, model.get(key));
            }
        }
        request.getRequestDispatcher(view).forward(request, response);
    }
}

至此,MVC框架的核心已经完成。
使用Java MVC框架 设计模式 设计一个简单的新闻信息管理系统 基于MVC框架的新闻信息管理系统 MVC框架的简介 主流框架是MVC框架技术 - 1:jsp+servlet+javabean适用于较小的项目 - 2:Struts+Spring+Hibernate 目前这是主流框架技术组合在一起就是SSH了 , 适用于要求可维护性强的框架技术 - Struts主要负责表示层的显示 - Spring利用它的IOC和APO来处理控制业务(负... 阅读详情

相关推荐

简易MVC与轻量级Spring框架实现项目

本文还有配套的精品资源,点击获取 简介:本压缩包含两个项目:第一个模仿Struts框架的简易MVC实现,第二个实现类Spring的轻量级依赖注入(IOC)和面向切面编程(AOP)。通过实践这些项目,可以提高对MVC设计模式、依赖注入和面向切面编程的理解,为学习和掌握更复杂的软件设计原则和框架提供基础。 1. 简易MVC模式实现 在开发Web应用时,MVC(M...

weixin_29041443的博客 1001

设计 REST 风格的 MVC 框架

级别: 中级 廖 雪峰, 软件工程师, HP 2010 年 1 月 04 日 传统的 JavaEE MVC 框架如 Struts 等都是基于 Action 设计的后缀式映射,然而,流行的 Web 趋势是 REST 风格的架构。尽管使用 Filter 或者 Apache mod_rewrite 能够通过 URL 重写实现 REST 风格的 URL,为什么不直接设计一个全新的 REST 风格...

料峭春风吹酒醒,微冷,山头斜照却相迎。 324

手把手实现轻量级自定义MVC框架

相较Spring MVC等重量级框架,自研MVC框架更轻量、透明,便于理解底层机制,适合教学与特定场景定制。现代Web趋向前后端分离,MVC中的“View”逐步由JSON输出替代,但其分层思想仍深刻影响着RESTful API架构设计,是构建可扩展系统的重要基石。我们首先定义一个标准的接口,模仿Spring MVC的设计风格:/*** 请求预处理,在控制器方法执行前调用* 返回false表示中断后续流程*//*** 控制器方法执行后,视图渲染前调用*//**

weixin_36074800的博客 718

warp-mvc

转载自:http://www.iteye.com/topic/176623   契机是robbin老大之前的一个帖子,评说warp这个基于guice的框架是蛮有前途的,之前一直羡慕ajoo老大可以在项目中使用guice,可又不知道如何下手,这次有了引子也可以见识一下guice的风采了。 话说这个guice可是完全使用annotation进行依赖注射、可通过官方那22页的说明文档楞是怎么...

xiajingsong的博客 167

人脸关键点定义汇总

前几天看一份代码临时需要找49个人脸关键点位置定义的图片发现怎么百度都搜不到,最后幸好谷歌可以使用了就用谷歌搜到了。所以在这里汇总一下我所知道的人脸关键点的定义和相关的一点东西,以备不时之需。 68个关键点 最常用的工具是Dlib,网址:http://dlib.net/ dlib的68个特征点检测算法是ERT算法【1】 使用dlib检测68个特征点的python示例见:http://dlib.n...

程序媛 7644

WOL唤醒配置(以太网、PHY、MAC)

MAC 就是以太网控制器,属于OSI的数字链路层。phy 属于OSI的物理层(Physical layer),所以叫phy。CPU Mac与phy通信通过MII接口,数据的传输通过MDIO数据线。通过配置phy的相关寄存器实现不同的功能。

qq_58264156的博客 8636

guice 整合ninja framework(七)

ninja是一个优秀的,轻量级的mvc框架,它与google guice整合比较好。下面看一下例子: 我们在web.xml 配置一下: <listener> <listener-class>ninja.servlet.NinjaServletListener</listener-class> </...

a304096740的博客 269

HFSS入门 - 传输线线路损耗和串扰仿真

下图中两相近传输线存在端口间的串扰,而同一根传输线存在线路损耗。 我们可用S21描述端口1到端口2的线路损耗(插损?),用S13描述近端串扰,S24描述远端串扰,串扰通常要求-20dB以下。 实验目的:传输线线路损耗和串扰仿真 具体步骤: 1.草图: 其中板厚Subh为1mm。其余参数具体值如下: 2.由草图作图: 其中介质板表面设为GND。 3.设置激励:先在第一根传输线相连的XZ平面上做一...

qq_37274411的博客 9162

设计REST风格的MVC框架[转]

传统的JavaEE MVC框架如Struts等都是基于Action设计的后缀式映射,然而,流行的Web趋势是REST风格的架构。尽管使用Filter或者Apache mod_rewrite能够通过URL重写实现REST风格的URL,为什么不直接设计一个全新的REST风格的MVC框架呢?本文将讲述如何从头设计一个基于REST风格的Java MVC框架,配合Annotation,最大限度地简...

dengzhu0449的博客 177

华为OD机试真题 新系统2026-04-08 Python&JS 实现【直捣黄龙】

小王在玩一款叫做直捣黄龙的小游戏,在该游戏中他需要从入口位置进入敌营,绕过哨兵的层层封锁,达到敌军司令部实施斩首行动。 敌军阵营是一个n*n的矩阵,入口在坐标(0,n/2),敌军司令部在坐标(n-1,n/2),每个哨兵警戒以自己为中心的9宫格,一旦被哨兵发现则行动失败。

MISAYAONE的博客 593

YOLOv12改进策略【Neck】| 使用CARAFE轻量级通用上采样算子

CARAFE内容感知的特征重新组合。

Limiiiing的博客 664

werkzeug实现简单Python web框架(1):MVC模式

Werkzeug是Python的WSGI规范的实用函数库。使用广泛,基于BSD协议。 Flask底层就是使用了Werkzeug。关键点: add_url_rule方法调用,导致视图类通过调用类方法,返回一个闭包,闭包返回一个视图函数,于是建立了url与视图函数的映射关系。代码from werkzeug.wrappers import BaseRequest, BaseResponse from

yz764127031的博客 3375

基于PINN求解裂纹扩展问题的优化开发

本文提出了一种基于物理信息神经网络(PINN)的裂纹扩展问题求解方法。通过将线弹性断裂力学控制方程和裂纹尖端场特性嵌入神经网络损失函数,PINN有效克服了传统有限元法在处理裂纹扩展时面临的网格重构困难、计算成本高等问题。文章详细介绍了PINN网络架构设计、裂纹尖端奇异场处理、损失函数构造以及优化策略等关键技术。数值实验表明,该方法能准确预测裂纹扩展路径和应力强度因子,且在处理复杂几何和动态扩展问题时展现出显著优势。相比传统方法,PINN具有无网格、并行计算友好等特点,为断裂力学问题提供了新的求解范式。

huanghm88的专栏 157

超轻量级MVC框架的设计和实现 (1)

前段时间准备做一个小网站,但是又不想用Spring/Struts/WebWork这样的大块头,因此决定自己写一个MVC框架。花了3天左右时间完成,目前运行良好,整个MVC框架仅21KB,感兴趣的朋友可以从http://code.google.com/p/lightweight-mvc/downloads/list下载完整的源代码和jar包。设计目标:一个最简单最小巧的MVC框架,花哨的功能一个

软件开发资料汇总 1068

基于Simulink的异步电机定子磁链定向控制(SFOC)仿真

本文带你从零构建了异步电机SFOC系统​ 的完整Simulink仿真模型,实现了:✅ 搭建异步电机、逆变器、风机负载的主电路与传感器模型;✅ 用MATLAB Function实现定子磁链观测(电压模型)、坐标变换、双闭环PI控制;✅ 验证SFOC在转速跟踪(响应0.2s、超调4%)、转矩响应(恢复0.15s)中的高性能;✅ 对比RFOC,明确SFOC在参数鲁棒性(转子电阻+50%时波动<2%)上的独特优势;✅ 理解SFOC“定子磁链定向+解耦控制”的核心思想(低成本高鲁棒性驱动的工程实现)。

xiaoheshang_123的博客 393

Cesium 实现动态加载气象数据:渲染成动态雨雪/云层效果(源码 + 原理)

本文介绍了在Cesium中实现动态天气效果的技术方案。核心思路是通过时间轴驱动多层数据动态切换,包括:1)时间维度处理,按序列加载不同气象图层;2)空间维度处理,将气象数据切分为瓦片;3)效果层实现,制作风场、降水等动态可视化效果。文章详细讲解了后端数据预处理(生成瓦片和风场JSON)、前端实现(双层雷达瓦片交替渐变、风场粒子系统)的具体方法,并提供了完整的代码示例。此外还探讨了雨雪粒子、云层效果等增强功能,以及工程化建议,为构建科学准确的动态天气可视化系统提供了实用解决方案。

专注AI大模型,软件混淆,授权 628

超轻量级MVC框架的设计和实现 (2)

在设计完API后,我们就需要实现这个MVC框架。MVC框架的核心是一个DispatcherServlet,用于接收所有的HTTP请求,并根据URL选择合适的Action对其进行处理。在这里,和Struts不同的是,所有的组件均被IoC容器管理,因此,DispatcherServlet需要实例化并持有Guice IoC容器,此外,DispatcherServlet还需要保存URL映射和Action的

.NET博文收藏 484

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

自己动手模仿 springmvc 写一个 mvc框架

spring的知识那么多,看源码也不知从何看起,那应该怎么学呢?我觉得,完整的自己动手去实现一个,是最好的方式。 bfmvc模仿springmvc的轻量级web框架,适合学习和搭建小型web项目使用,持续更新项目地址:https://github.com/CFshuming/bfmvc感兴趣的记得star哟~目录介绍

mystery的博客 7991

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

【Spring MVC】MVC设计模式的Java Web框架

Spring MVC 是 Spring 框架中的一个模块,基于 Model-View-Controller (MVC) 设计模式,用于构建灵活和可扩展的 Java Web 应用程序。它通过前端控制器 DispatcherServlet 处理所有请求,并将请求分发给对应的控制器,负责业务逻辑处理,再将结果传递给视图进行渲染,简化了开发过程并实现了应用程序的高效组织和维护。​

科马的博客 3384

C MVC + layui.js 超轻量级框架(包含数据库)

C# MVC + layui.js 超轻量级框架(包含数据库) 去发现同类优质开源项目:https://gitcode.com/ 项目简介 本项目提供了一个基于C# MVC框架的超轻量级开发模板,结合了前端layui.js框架和后端sqlsugar数据处理库。该框架支持多种数据库(SQL Server、MySQL、SQLite、Oracle),并包含了用户、角色和页面配置的完整功能,非常适合小微型...

gitblog_09785的博客 1036

自己用Java写一个HTTP服务器和MVC框架

自己刚实现了一个轻量级的嵌入式http服务器,Java语言,基于nio。同时提供类似spring mvc的功能, 包括@Controller,@RequestMapping,参数注入等功能。项目地址:LightWebServer项目总计1700行java代码, {理解原理 + 不实现}三天左右,{理解原理 + 自己实现}需要一周左右。下面分享一下自己的学习步骤:1.学习nio相关知识简单来说nio...

小肥牛 1947

超轻量级MVC框架的设计和实现 (3)

由于MVC框架的设计,必须保证配置IoC容器时指定正确的Scope,否则无法正常工作:用户定义的所有的Action类必须是Prototype域,即Guice默认的作用域,如果定义为Singleton会导致并发请求的数据混乱;用户定义的所有的Interceptor,ViewResolver和ExceptionResolver应该是Singleton的,MVC框架会保持其引用,即时定义为Prototy

软件开发资料汇总 284
上一篇: 开源C/C++网络库比较 ace &&bosst
下一篇: Android开发--仿微信语音对讲录音
codepython
博客等级 码龄20年 125粉丝 6原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值