Jodd 5.0 使用自定义WebApp及设置默认拦截器

首先使用IDEA创建Java工程,目录如下图所示:

使用 Jetty作为Web服务器,配置 jetty.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
<Configure id='Contexts' class="org.eclipse.jetty.webapp.WebAppContext">
    <New id="mysql" class="org.eclipse.jetty.plus.jndi.Resource">
        <Arg></Arg>
        <Arg>jdbc/mall</Arg>
        <Arg>
            <New class="com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource">
                <Set name="Url">jdbc:mysql://127.0.0.1:3306/mall?useUnicode=true&amp;amp;characterEncoding=utf-8&amp;amp;jdbcCompliantTruncation=false&amp;amp;autoReconnect=true&amp;allowPublicKeyRetrieval=true</Set>
                <Set name="User">root</Set>
                <Set name="Password"></Set>
            </New>
        </Arg>
    </New>
</Configure>

配置joy.props:

jndiName=java:comp/env/jdbc/mall

编写AppListener.java

package io.github.mall.api;

import jodd.db.connection.DataSourceConnectionProvider;
import jodd.joy.JoddJoy;
import jodd.joy.JoyContextListener;
import jodd.madvoc.petite.PetiteWebApp;
import jodd.petite.PetiteContainer;
import jodd.props.Props;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.annotation.WebListener;
import java.util.function.Supplier;

@WebListener
public class AppListener extends JoyContextListener {
    private static Logger logger = LoggerFactory.getLogger(AppListener.class);
    private PetiteContainer container = null;

    @Override
    protected JoddJoy createJoy() {
        Props props = new Props();
        props.loadFromClasspath("/joy.props");
        String jndiName = props.getValue("jndiName");
        logger.info("使用 [{}] 作为默认的数据源!", jndiName);
         Supplier<PetiteContainer> petiteContainer= PetiteContainer::new;
        JoddJoy joy = super.createJoy();

        joy.withDb(db -> db.withConnectionProvider(() -> new DataSourceConnectionProvider(jndiName)));

        joy.withPetite(joyPetiteConfig -> joyPetiteConfig.withPetite(consumer->{
            container = consumer;
            logger.info("容器 container={}",container);
        }));

        Supplier<PetiteWebApp> petiteWebAppSupplier = () -> new AppWeb(container);
        joy.useWebApp(petiteWebAppSupplier); // 使用自定义AppWeb

        return joy;
    }
}

编写自定义的AppWeb.java:

package io.github.mall.api;

import io.github.mall.api.config.AppRestActionConfig;
import jodd.madvoc.WebApp;
import jodd.madvoc.component.ActionConfigManager;
import jodd.madvoc.meta.RestAction;
import jodd.madvoc.petite.PetiteWebApp;
import jodd.petite.PetiteContainer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class AppWeb extends PetiteWebApp {
    private static Logger logger = LoggerFactory.getLogger(AppWeb.class);

    public AppWeb(PetiteContainer petiteContainer) {
        super(petiteContainer);
    }

    @Override
    public WebApp start() {
        // 登记默认的RestActionConfig配置
        super.withRegisteredComponent(ActionConfigManager.class,acm->{
            acm.bindAnnotationConfig(RestAction.class, AppRestActionConfig.class);
        });
        return super.start();
    }
}

AppRestActionConfig.java:

package io.github.mall.api.config;

import io.github.mall.api.interceptor.ApiInterceptor;
import jodd.joy.i18n.I18nInterceptor;
import jodd.madvoc.action.RestActionConfig;
import jodd.madvoc.interceptor.ServletConfigInterceptor;
/**
  * 此处设置默认的拦截器配置 
 **/
public class AppRestActionConfig extends RestActionConfig {
    @SuppressWarnings("unchecked")
    public AppRestActionConfig() {
        super();
        setInterceptors(
                I18nInterceptor.class,
                ApiInterceptor.class,
                ServletConfigInterceptor.class
        );
    }
}

ApiInterceptor.java 拦截器:

package io.github.mall.api.interceptor;

import io.github.mall.api.data.Result;
import io.github.mall.api.exception.ServiceException;
import jodd.madvoc.ActionRequest;
import jodd.madvoc.interceptor.ActionInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ApiInterceptor implements ActionInterceptor {
    private static final Logger  logger = LoggerFactory.getLogger(ApiInterceptor.class);
    @Override
    public Object intercept(ActionRequest actionRequest) throws Exception {
        Result<Object> result = new Result<>();
        logger.info("在 {} 拦截器中运行...",ApiInterceptor.class.getName());
        try {
            Object val = actionRequest.invoke();
            result.setData(val);
            result.setResultCode(0);
            result.setResultMsg("");
        }catch (ServiceException se){
            result.setResultCode(se.getErrorCode());
            result.setResultMsg(se.getErrorMsg());
        }
        return result;

    }
}

Result.java:

package io.github.mall.api.data;
/*
* Api 接口返回对象
*/
public class Result<T> {
    private Integer resultCode = null;
    private String resultMsg = "";
    private T data = null;

    public Integer getResultCode() {
        return resultCode;
    }

    public void setResultCode(Integer resultCode) {
        this.resultCode = resultCode;
    }

    public String getResultMsg() {
        return resultMsg;
    }

    public void setResultMsg(String resultMsg) {
        this.resultMsg = resultMsg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}

测试的IndexAction.java:

package io.github.mall.api.action;

import io.github.mall.api.entity.User;
import io.github.mall.api.exception.ServiceException;
import io.github.mall.api.service.UserService;
import jodd.madvoc.meta.In;
import jodd.madvoc.meta.MadvocAction;
import jodd.madvoc.meta.RestAction;
import jodd.petite.meta.PetiteInject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

@MadvocAction
public class IndexAction {
    private static final Logger logger = LoggerFactory.getLogger(IndexAction.class);
    @PetiteInject
    private UserService userService=null;

    @In
    private Integer index=null;

    //RestAction标注的Action其返回将默认使用AppRestActionConfig中配置的拦截器
    @RestAction("/")
    public List<User> index(){
        List<User> users = userService.list(User.class);
        logger.info("index={}",index);
        userService.check();
        if(index!=null)
            throw new ServiceException(3,"错误");
        return users;
    }
}

BaseDao.java:

package io.github.mall.api.dao;

import jodd.db.DbOom;
import jodd.db.oom.DbOomQuery;
import jodd.db.oom.dao.GenericDao;
import jodd.jtx.meta.ReadOnlyTransaction;
import jodd.petite.meta.PetiteBean;

import java.util.List;
import java.util.Map;

@PetiteBean
public class BaseDao<T> {
    private GenericDao dao;

    public BaseDao() {
        dao = new GenericDao(DbOom.get());
    }

    public T load(Class<T> glass, Long id) {
        return dao.findById(glass, id);
    }

    public void insert(T o) {
        dao.store(o);
    }

    public void update(T o) {
        dao.update(o);
    }

    public void remove(T o) {
        dao.deleteById(o);
    }

    public List<T> list(String sql, Map<String, Object> params) {
        DbOomQuery query = DbOomQuery.query(sql).autoClose();
        if (params != null && params.size() > 0) {
            for (Map.Entry<String, Object> entry : params.entrySet()) {
                query.setObject(entry.getKey(), entry.getValue());
            }
        }
        return query.list();
    }

    @ReadOnlyTransaction
    public List<T> all(Class<T> glass) {
        return dao.listAll(glass);
    }
}

如此则其他Dao类写起来就非常简单了,继承BaseDao即可,例如 UserDao.java:

package io.github.mall.api.dao;

import io.github.mall.api.entity.User;
import jodd.petite.meta.PetiteBean;

@PetiteBean
public class UserDao extends BaseDao<User>{
}

对于Service类,同样如此,编写BaseService.java:

package io.github.mall.api.service;

import io.github.mall.api.dao.BaseDao;
import jodd.jtx.meta.ReadOnlyTransaction;
import jodd.jtx.meta.ReadWriteTransaction;
import jodd.petite.meta.PetiteBean;
import jodd.petite.meta.PetiteInject;

import java.util.List;
import java.util.Map;

@PetiteBean
public class BaseService<T> {
    @PetiteInject
    private BaseDao<T> dao;

    @ReadOnlyTransaction
    public T load(Class<T> glass,Long id){
        return dao.load(glass,id);
    }

    @ReadWriteTransaction
    public void save(T entity)
    {
        dao.insert(entity);
    }

    @ReadWriteTransaction
    public void update(T entity){
        dao.update(entity);
    }

    @ReadWriteTransaction
    public void remove(T entity){
        dao.remove(entity);
    }

    @ReadOnlyTransaction
    public List<T> list(String sql, Map<String,Object> params){
        return dao.list(sql,params);
    }

    @ReadOnlyTransaction
    public List<T> list(Class<T> glass){
        return dao.all(glass);
    }
}

由于从Jodd 5.0.4开始支持超类(SupperClass)的私有属性的注入(private field),以及超类的私有属性的注解解析,因此 其他的Service类更加简单,例如UserService.java:

package io.github.mall.api.service;

import io.github.mall.api.entity.User;
import jodd.petite.meta.PetiteBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;

@PetiteBean
public class UserService extends BaseService<User>{
    private static final Logger logger = LoggerFactory.getLogger(UserService.class);

//    @PetiteInject
//    private BaseDao<User> baseDao;
    @ReadOnlyTransaction
    public List<User> users(){
        // logger.info("baseDao={}",baseDao);
        return list(User.class);
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值