meethigher-基于Netty的轻量级Web框架Jooby

news2024/11/15 8:28:41

Spring-Web的好处是,快速上手、快速成型,且成熟稳定无Bug。

但对于个人而言,这套框架太重了。由此探寻更好的轻量Web框架Jooby!

本文源码地址meethigher/jooby-example: 基于Netty的轻量级Web框架Jooby使用示例

一、搭建项目

创建原生maven空项目,引入依赖

<dependency>
    <groupId>io.jooby</groupId>
    <artifactId>jooby-netty</artifactId>
    <version>2.16.1</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.12</version>
</dependency>

创建启动类

import io.jooby.Jooby;

public class Application extends Jooby {

    //构造函数快
    {
        get("/", ctx -> "Hello World");
    }

    public static void main(String[] args) {
        runApp(args, Application.class);
    }
}

二、配置文件

Jooby同样支持解析多种类型的配置文件,只记录常用的application.conf

Jooby读取配置文件优先级顺序

  1. 优先应用根目录下。即System.getProperty("user.dir")
  2. 其次类路径下,即resources下或者jar包内的。

resources添加application.conf

server.port = 8080
app.name = "内部"
database.url = "jdbc:mysql://localhost:3306/mydb"

示例接口

import io.jooby.Jooby;
import io.jooby.MediaType;

import java.nio.charset.StandardCharsets;

public class Application extends Jooby {

    //构造函数快
    {
        // use Decorator.
        decorator(next -> ctx -> {
            // get response content-type.
            final MediaType responseType = ctx.getResponseType();
            // if content-type is text-specific
            if(responseType.isTextual())
                // override response type with current media type and always use UTF-8 charset!
                ctx.setResponseType(responseType, StandardCharsets.UTF_8);
            // pipe next response procedure.
            return next.apply(ctx);
        });
        get("/", ctx -> {

            String appName = getConfig().getString("app.name");
            return "Welcome to " + appName;
        });

        get("/database", ctx -> {
            String dbUrl = getConfig().getString("database.url");
            return "Database URL: " + dbUrl;
        });
    }

    public static void main(String[] args) {
        runApp(args, Application.class);
    }
}

三、开发接口

3.1 Script API-仅支持简单路由

Script API 通常用于编写小型的、单一用途的路由处理器。

支持占位符路由规则,但是像拼参形式的就不支持。

import static io.jooby.Jooby.runApp;

public class ScriptAPIApplication {

    public static void main(String[] args) {
        //consumer函数式接口简写
        runApp(args, app -> {
            app.get("/param/{id}", ctx -> {
                String id = ctx.path("id").value();
                return id;
            });
            app.post("/param/{id}", ctx -> {
                return ctx.path("id").value();
            });
        });
    }
}

3.2 MVC API-支持复杂路由

添加依赖

<!-- MVC API 核心模块 -->
<dependency>
    <groupId>io.jooby</groupId>
    <artifactId>jooby-apt</artifactId>
    <version>2.16.1</version>
</dependency>
<!-- json模块 -->
<dependency>
    <groupId>io.jooby</groupId>
    <artifactId>jooby-gson</artifactId>
    <version>2.16.1</version>
</dependency>

创建controller

import io.jooby.MediaType;
import io.jooby.Multipart;
import io.jooby.annotations.*;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

@Path("/mvc")
public class Controller {

    @GET("/get")
    public String get() {
        return "Hello World";
    }

    @GET("/pathParam/{id}")
    public String pathParam(@PathParam String id) {
        return id;
    }

    @GET("/queryParam")
    public String queryParam(@QueryParam String id, @QueryParam String name) {
        return name + "--->" + id;
    }

    /**
     * form表单,支持两种形式
     * application/x-www-form-urlencoded,不支持文件
     * multipart/form-data,支持文件
     */
    @POST("/formParam")
    public String formParam(@FormParam String name, @FormParam String age, @FormParam Multipart file) {
        if (file != null) {
            try (InputStream is = file.file("file").stream(); FileOutputStream fos = new FileOutputStream("test.txt")) {
                int b;
                while ((b = is.read()) != -1) {
                    fos.write(b);
                }
                fos.flush();
            } catch (IOException e) {
            }
        }
        return name + "--->" + age;
    }


    @POST("/bodyParam")
    @Consumes(MediaType.JSON)//可省略
    @Produces(MediaType.JSON)//可省略
    public Object bodyParam(Object body) {
        return body;
    }

    @POST("/pageQuery")
    public String pageQuery(PageRequest req) {
        return req.toString();
    }
}

class PageRequest {
    private Integer pageIndex;
    private Integer pageSize;

    public Integer getPageIndex() {
        return pageIndex;
    }

    public void setPageIndex(Integer pageIndex) {
        this.pageIndex = pageIndex;
    }

    public Integer getPageSize() {
        return pageSize;
    }

    public void setPageSize(Integer pageSize) {
        this.pageSize = pageSize;
    }
}

注册controller

import io.jooby.json.GsonModule;
import top.meethigher.mvc.controller.Controller;

import static io.jooby.Jooby.runApp;

public class MVCApplication {
    public static void main(String[] args) {
        runApp(args, app -> {
            // 设置 JSON 支持
            app.install(new GsonModule());
            //注册控制器
            app.mvc(new Controller());
        });
    }
}

四、参考致谢

jooby:做更多! 更容易!
// 设置 JSON 支持
app.install(new GsonModule());
//注册控制器
app.mvc(new Controller());
});
}
}


[外链图片转存中...(img-mFU1u5le-1687016527518)]

# 四、参考致谢

[jooby:做更多! 更容易!](https://jooby.io/#introduction)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/658170.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能python:Python遍历指南:掌握5种常用方法实现高效遍历

Python遍历指南&#xff1a;掌握5种常用方法实现高效遍历 作为一种高效且易学的编程语言&#xff0c;Python在数据处理和分析方面常常被誉为行业标准。在Python中&#xff0c;遍历数据结构是处理数据的基本操作之一。它可以帮助您将大规模数据转换成可视化、文本分析、机器学习…

复杂前端组件 - 拖拽排序功能设计与实现

复杂前端组件 - 拖拽排序功能设计与实现 最终效果 原生实现原理 关于拖拽 标签的图片默认是可以拖动的&#xff08;效果如上图&#xff09; 然而其他的标签&#xff08;div等&#xff09;是不能被拖动的&#xff0c;鼠标点击选择后移动没有拖拽效果&#xff0c;需要添加属性…

dubbo源码阅读之-ExtensionLoader

dubbo源码阅读之-ExtensionLoader 概述构造方法说起extensionPostProcessors 后置处理器初始化实例策略ExtensionInjector 完成ioc 中的set注入 获取扩展点实现类getExtensionClasses 加载普通的扩展点getAdaptiveExtensionClass 加载自适应的扩展点创建Adaptive代理类 获取扩展…

算法刷题-字符串-替换空格

题目&#xff1a;剑指Offer 05.替换空格 力扣题目链接 请实现一个函数&#xff0c;把字符串 s 中的每个空格替换成"%20"。 示例 1&#xff1a; 输入&#xff1a;s “We are happy.” 输出&#xff1a;“We%20are%20happy.” 思路 如果想把这道题目做到极致&…

Python 3 | 菜鸟教程 (一)

目录 一、Python3 简介 二、Python 发展历史 三、Python 特点 &#xff08;一&#xff09;易于学习 &#xff08;二&#xff09;易于阅读 &#xff08;三&#xff09;易于维护 &#xff08;四&#xff09;一个广泛的标准库 &#xff08;五&#xff09;互动模式 &#…

【C】static关键字详解

概述 static的汉语意思是静态的&#xff0c;在C语言中static关键字可以用来修饰局部变量、全局变量和函数。 在这里给大家补充一个知识&#xff0c;我们的数据在内存中存储时&#xff0c;大概分为3个区域。 1.栈区&#xff1a;我们创建的局部变量、形参等一般就存放在这个区域…

Python3 数字(Number)与字符串 | 菜鸟教程(五)

目录 一、Python3 数字(Number) &#xff08;一&#xff09;Python 数字数据类型用于存储数值。 1、以下实例在变量赋值时 Number 对象将被创建&#xff1a; 2、您也可以使用del语句删除一些数字对象的引用。 3、您可以通过使用del语句删除单个或多个对象的引用 &#xff08;…

Golang每日一练(leetDay0100) 数据流中位数、二叉树序列化

目录 295. 数据流的中位数 Find-median-from-data-stream &#x1f31f;&#x1f31f;&#x1f31f; 297. 二叉树的序列化与反序列化 Serialize-and-deserialize-binary-tree &#x1f31f;&#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Rus…

从零开始Vue项目中使用MapboxGL开发三维地图教程(六)加载点、线、面图层以及三维面图层(白模)

目录 1、加载点图层2、加载线和面图层3、加载三维面图层&#xff08;白模&#xff09; 1、加载点图层 开发地图应用时&#xff0c;加载POI等点状数据&#xff0c;显示文字或者图标信息&#xff0c;mapbox-gl对应使用的是符号图层&#xff08;symbol&#xff09;&#xff0c;下面…

Canvas.drawText 是以哪里为基线往什么方向开始画的。有什么居中方案?

0 前言 Canvas.drawText(String text, float x, float y, Paint paint) 这个方法在绘制文本时是从以什么为基线向什么地方开始绘制呢&#xff0c;水平方向上&#xff0c;可以通过设置 setTextAlign(Paint.Align.??) 来设置基线在文本左边、右边或者中间。但是垂直方向上是在哪…

三、DI 依赖注入学习总结

文章目录 一、依赖注入1.1 构造函数注入1.2 Setter 方法注入&#xff08;重点掌握&#xff09;1.2.1 通过 Set 注入复杂类型和集合类型数据 一、依赖注入 依赖注入&#xff08;Dependency Injection&#xff0c;DI&#xff09;是 Spring 框架的核心特性之一&#xff0c;也是 S…

chatgpt赋能python:Python中如何输出换行符\n

Python中如何输出换行符\n 如果你是一个Python开发者&#xff0c;你可能已经熟悉了多个输出Python变量的方法。但是&#xff0c;当你需要输出换行符’\n’时&#xff0c;你可能会遇到一些问题。这篇文章将介绍在Python中输出换行符的几种方法&#xff0c;并且告诉你哪种方法是…

13.IOC容器

IOC容器 IOC&#xff1a;Inversion of Control&#xff0c;翻译过来是反转控制 IOC思想 获取资源的传统方式&#xff1a;在应用程序中的组件需要获取资源时&#xff0c;传统的方式是组件主动的从容器中获取所需要的资源&#xff0c;在这样的模式下开发人员往往需要知道在具体…

第12课【嵌入式常见存储器类型】ROM RAM 一次性 DDR双倍速率 Flash

目录 存储器易失性存储器RAMDRAMSDRAMDDR SDRAM SRAMDRAM/SRAM总结 非易失性存储器ROMMASK ROMOTPROMEPROMEEPROM FLASH 存储器 存储器是组成计算机的重要部分&#xff0c;它可以存储数据&#xff0c;能让计算机拥有“记忆”。目前根据断电后&#xff0c;存储的数据是否会丢失…

TiDB v7.1.0 版本 Resource Control体验

作者&#xff1a; Ming 原文来源&#xff1a; https://tidb.net/blog/8abfaa25 简介 近期迎来了 TiDB v7.1.0 版本&#xff0c;也是2023年首发的LTS&#xff08;Long-Term Support Release&#xff09;版本&#xff0c;相比于之前的 v6.5.0 LTS版本已经过去了很长时间&…

Android PagerSnapHelper改造RecyclerView为ViewPage,kotlin

Android PagerSnapHelper改造RecyclerView为ViewPage&#xff0c;kotlin <?xml version"1.0" encoding"utf-8"?> <androidx.recyclerview.widget.RecyclerView xmlns:android"http://schemas.android.com/apk/res/android"xmlns:tool…

Spring Web vs Spring Webflux

当你需要构建Web应用程序时&#xff0c;Spring Web 和 Spring Webflux 是Spring生态系统中的两个框架&#xff0c;但它们之间有一些关键区别。 Spring Web 是一个传统的Web框架&#xff0c;它构建在Servlet API之上。它旨在处理阻塞式I/O&#xff0c;即线程在从数据库或其他服务…

CTFHub | 过滤cat

0x00 前言 CTFHub 专注网络安全、信息安全、白帽子技术的在线学习&#xff0c;实训平台。提供优质的赛事及学习服务&#xff0c;拥有完善的题目环境及配套 writeup &#xff0c;降低 CTF 学习入门门槛&#xff0c;快速帮助选手成长&#xff0c;跟随主流比赛潮流。 0x01 题目描述…

Springboot读取配置文件的方式以及多环境读取的方式

Springboot读取配置文件的方式以及多环境读取的方式 一.首先介绍一下读取配置文件中的值的方式1.Value注解2.ConfigurationProperties注解赋值3.使用 Environment 读取配置文件 多环境读取 在项目中我们可能需要灵活的配置一些参数&#xff0c;就会将这些参数写到yaml文件或者p…

C++技能系列 ( 4 ) - 深入理解C++临时对象【解析与提高性能手段】

系列文章目录 C技能系列 C高性能优化编程系列 深入理解软件架构设计系列 高级C并发线程编程 期待你的关注哦&#xff01;&#xff01;&#xff01; 现在的一切都是为将来的梦想编织翅膀&#xff0c;让梦想在现实中展翅高飞。 Now everything is for the future of dream w…