【发布时间】:2018-01-01 12:51:24
【问题描述】:
我尝试制作多租户 REST API。
Java EE 7
应用服务器:WildFly-Swarm 2017.11.0
JAX-RS:wildfly-swarm-weld
目的是从查询参数中获取租户(德语 Mandant)名称,并设置租户名称以触发代理 EntityManager。
这是 TOMAS DVORAK 的基本概念:https://www.tomas-dvorak.cz/posts/jpa-multitenancy/
我与拦截器斗争,如标题中所述,我需要使用 HTTP 代码和 JSON 错误消息中止拦截的 REST 请求的响应。
我不能使用过滤器,因为 EE 正在使用另一个带有过滤器的线程,我无法通过 ThreadLocal 传递租户名称。
我很难得到响应对象。
这是我到目前为止的代码:
import javax.inject.Inject;
import javax.interceptor.*;
import javax.servlet.http.*;
import org.multitenancy.test.beans.*;
/**
* Wrap every call with tenant identification, detected from list of parameters
* of called method.
*/
@Interceptor
public class TenantInterceptor
{
@Inject
private TenantRegistry tenantRegistry;
@Inject
HttpServletRequest servletRequest;
@AroundInvoke
public Object wrapWithTenant(final InvocationContext ctx) throws Exception
{
System.out.println("wrapWithTenant() Called");
printParameter();
if (servletRequest.getParameterMap().containsKey("mandant"))
{
String mandantNameReq = servletRequest.getParameterMap().get("mandant")[0];
if (tenantRegistry.verifyMandantByName(mandantNameReq))
{
System.out.println(mandantNameReq + " is verified");
final String oldValue = TenantHolder.getCurrentTenant();
System.out.println("old value " + oldValue);
try
{
TenantHolder.setTenant(mandantNameReq);
System.out.println("Mandant gesetzt: " + mandantNameReq);
return ctx.proceed();
}
finally
{
if (oldValue != null)
{
TenantHolder.setTenant(oldValue);
}
else
{
TenantHolder.cleanupTenant();
}
}
}
else
{
//TODO: Response einbauen
// containerRequestContext.abortWith(
// Response.status(Response.Status.BAD_REQUEST)
// .entity(new ApiError("Mandant not found"))
// .type(MediaType.APPLICATION_JSON)
// .build());
}
}
else
{
// containerRequestContext.abortWith(
// Response.status(Response.Status.BAD_REQUEST)
// .entity(new ApiError("Parameter doesnt contain mandant"))
// .type(MediaType.APPLICATION_JSON)
// .build());
}
return null;
}
private void printParameter()
{
if (servletRequest.getParameterMap().isEmpty())
{
System.out.println("No Properties given");
}
else
{
for (String key : servletRequest.getParameterMap().keySet())
{
for (String val : servletRequest.getParameterValues(key))
{
System.out.println(key + "\t" + val);
}
}
}
}
}
提前致谢:)
【问题讨论】:
-
你的问题有点混乱,不清楚你在问什么。只是想知道,您是否尝试使用 JAX-RS
ContainerRequestFilter而不是 CDI/Interceptor 规范拦截器?您将有权中止请求。 -
我不明白你为什么不能使用过滤器?为什么要在另一个线程中运行?
-
您好,我尝试了过滤器,但我的 ThreadLocal 存储中的租户名称为空。我可以将我的私人 Bitbucket 项目复制到 GitHub 吗?
标签: jakarta-ee cdi interceptor