Java Web 框架 Latke v2.4.39,重写控制器层

2018-12-21 12:03:53 +08:00
 88250

简介

Latke('lɑ:tkə,土豆饼)是一个简单易用的 Java Web 应用开发框架,包含 MVC、IoC、事件通知、ORM、插件等组件。

在实体模型上使用 JSON 贯穿前后端,使应用开发更加快捷。这是 Latke 不同于其他框架的地方,非常适合小型应用的快速开发。

特性

案例

安装

<dependency>
    <groupId>org.b3log</groupId>
    <artifactId>latke-core</artifactId>
    <version>${latke.version}</version>
</dependency>

控制器层用法

注解声明式路由

@RequestProcessing("/")
public void index(final RequestContext context) {
    context.setRenderer(new SimpleFMRenderer("index.ftl"));
    final Map<String, Object> dataModel = context.getRenderer().getRenderDataModel();
    dataModel.put("greeting", "Hello, Latke!");
}

函数式路由

DispatcherServlet.post("/register", registerProcessor::register);
DispatcherServlet.mapping();

路径变量和查询字符串

@RequestProcessing("/var/{pathVar}")
public void paraPathVar(final RequestContext context) {
    final String paraVar = context.param("paraVar");
    final String pathVar = context.pathVar("pathVar");
    context.renderJSON(new JSONObject().put("paraVar", paraVar).put("pathVar", pathVar));
}

JSON 解析

final JSONObject requestJSON = context.requestJSON();

Servlet 封装

final String remoteAddr = context.remoteAddr();
final String requestURI = context.requestURI();
final Object att = context.attr("name");
final String method = context.method();
context.sendRedirect("https://b3log.org");
final HttpServletRequest request = context.getRequest();
final HttpServletResponse response = context.getResponse();

服务层用法

依赖注入、事务

@Service
public class UserService {

    private static final Logger LOGGER = Logger.getLogger(UserService.class);

    @Inject
    private UserRepository userRepository;

    @Transactional
    public void saveUser(final String name, final int age) {
        final JSONObject user = new JSONObject();
        user.put("name", name);
        user.put("age", age);

        String userId;

        try {
            userId = userRepository.add(user);
        } catch (final RepositoryException e) {
            LOGGER.log(Level.ERROR, "Saves user failed", e);

            // 抛出异常后框架将回滚事务
            throw new IllegalStateException("Saves user failed");
        }

        LOGGER.log(Level.INFO, "Saves a user successfully [userId={0}]", userId);
    }
}

持久层用法

构造 ORM

@Repository
public class UserRepository extends AbstractRepository {

    public UserRepository() {
        super("user");
    }
}

单表 CRUD

public interface Repository {
    String add(final JSONObject jsonObject) throws RepositoryException;
    void update(final String id, final JSONObject jsonObject) throws RepositoryException;
    void remove(final String id) throws RepositoryException;
    void remove(final Query query) throws RepositoryException;
    JSONObject get(final String id) throws RepositoryException;
    long count(final Query query) throws RepositoryException;
}

条件查询

public JSONObject getByName(final String name) throws RepositoryException {
    final List<JSONObject> records = getList(new Query().
            setFilter(new PropertyFilter("name", FilterOperator.EQUAL, name)));
    if (records.isEmpty()) {
        return null;
    }

    return records.get(0);
}

分页查询

new Query().setCurrentPageNum(1).setPageSize(50)

按字段排序

new Query().addSort("name", SortDirection.DESCENDING);

仅获取需要字段

new Query().addProjection("name", String.class);

原生 SQL

final List<JSONObject> records = select("SELECT * FROM `user` WHERE `name` = ?", name);

文档

社区

鸣谢

Latke 的诞生离不开以下开源项目:

2223 次点击
所在节点    分享创造
10 条回复
kidlj
2018-12-21 12:34:41 +08:00
哇,看到 golang 的 gin
blueskea
2018-12-21 13:45:28 +08:00
用过 solo 博客,功能和外观上没话说,但是会将账号、用户评论这些信息同步到你们那边,感觉不爽,后来想自己改改,发现底层的框架里也封装了这些东西,改起来好麻烦。不过还是很感谢作者付出的辛苦。
88250
2018-12-21 14:01:46 +08:00
@blueskea 同步可以选择关闭,没必要改代码啊。
cnbobolee
2018-12-21 14:20:39 +08:00
瞄过 gin ?
88250
2018-12-21 15:03:58 +08:00
@cnbobolee
@kidlj

我们另一个项目用的是 Gin https://github.com/b3log/pipe
blueskea
2018-12-21 17:18:01 +08:00
@88250 在哪边改啊,一直没找到
88250
2018-12-21 17:27:28 +08:00
@blueskea 在黑客派社区的个人设置中,更新一下 B3 Key 就行了。 关于同步内容这件事的详细介绍可以了解一下 https://hacpai.com/b3log
dezhou9
2018-12-23 17:05:58 +08:00
star 一下
fox0001
2018-12-24 12:59:35 +08:00
当年 Spring 说自己是轻量级,把 EJB 那一套干掉了。但是,如果要再轻量级,为什么不考虑其它语言而死守 Java ?

另外有个疑问,关于采用 json 代替 class 贯穿全局,如果数据库字段名改,改 json 不是更麻烦?毕竟 IDE 不能检查 json 对象 get 属性名是否正确。这样的话,只能全局字符串替换。class 的话,属性方法名变化后,IDE 直接报错,不是更方便。
88250
2018-12-25 07:35:09 +08:00
@fox0001 如果项目大了,get 的字段名可以定义一下,这样也方便重构。不过改字段这事情一般很少碰到,数据库一般都是一次性就设计好吧。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/519696

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX