Jsp Java EE错误:javax.enterprise.inject.UnsatifiedResolutionException:Api类型

Jsp Java EE错误:javax.enterprise.inject.UnsatifiedResolutionException:Api类型,jsp,jakarta-ee,model-view-controller,ejb,apache-tomee,Jsp,Jakarta Ee,Model View Controller,Ejb,Apache Tomee,我正在构建一个基于MVC架构的简单webapp。我有一个带有HTML表单的小JSP页面。表单数据被转发到servlet,然后servlet委托给控制器类 在表单上单击submit时,我得到一个HTTP状态500-由“UnsatifiedResolutionException”引起的错误。容器似乎找不到控制器 Context.xml文件用作我的数据源。我正在使用ApacheTomee webprofile 1.7.4 错误: type Exception report message Error

我正在构建一个基于MVC架构的简单webapp。我有一个带有HTML表单的小JSP页面。表单数据被转发到servlet,然后servlet委托给控制器类

在表单上单击submit时,我得到一个HTTP状态500-由“UnsatifiedResolutionException”引起的错误。容器似乎找不到控制器

Context.xml
文件用作我的数据源。我正在使用ApacheTomee webprofile 1.7.4

错误:

type Exception report

message Error instantiating servlet class a1.DispatcherServlet

description The server encountered an internal error that prevented it from fulfilling this request.

exception

javax.servlet.ServletException: Error instantiating servlet class a1.DispatcherServlet
    org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:44)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:436)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1078)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    java.lang.Thread.run(Thread.java:745)
root cause

javax.enterprise.inject.UnsatisfiedResolutionException: Api type [a1.Controller] is not found with the qualifiers 
Qualifiers: [@javax.inject.Named(value=customerController)]
for injection into Field Injection Point, field name :  customerController, Bean Owner : [DispatcherServlet, Name:null, WebBeans Type:DEPENDENT, API Types:[java.io.Serializable,javax.servlet.GenericServlet,java.lang.Object,a1.DispatcherServlet,javax.servlet.Servlet,javax.servlet.http.HttpServlet,javax.servlet.ServletConfig], Qualifiers:[javax.enterprise.inject.Any,javax.enterprise.inject.Default]]
    org.apache.webbeans.util.InjectionExceptionUtil.throwUnsatisfiedResolutionException(InjectionExceptionUtil.java:60)
    org.apache.webbeans.container.InjectionResolver.getInjectionPointBean(InjectionResolver.java:250)
    org.apache.webbeans.inject.AbstractInjectable.inject(AbstractInjectable.java:76)
    org.apache.webbeans.inject.InjectableField.doInjection(InjectableField.java:65)
    org.apache.webbeans.portable.InjectionTargetImpl.injectFields(InjectionTargetImpl.java:208)
    org.apache.webbeans.portable.InjectionTargetImpl.inject(InjectionTargetImpl.java:194)
    org.apache.webbeans.portable.InjectionTargetImpl.inject(InjectionTargetImpl.java:184)
    org.apache.webbeans.component.AbstractOwbBean.create(AbstractOwbBean.java:125)
    org.apache.openejb.core.WebContext.newInstance(WebContext.java:138)
    org.apache.tomee.catalina.JavaeeInstanceManager.newInstance(JavaeeInstanceManager.java:46)
    org.apache.tomee.catalina.JavaeeInstanceManager.newInstance(JavaeeInstanceManager.java:66)
    org.apache.tomee.catalina.JavaeeInstanceManager.newInstance(JavaeeInstanceManager.java:61)
    org.apache.tomee.catalina.OpenEJBValve.invoke(OpenEJBValve.java:44)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:436)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1078)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
    java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
    org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    java.lang.Thread.run(Thread.java:745)
DispatcherServlet.java:

package a1;

/* Imports */

public class DispatcherServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Inject
    @Named("customerController")
    private Controller customerController;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        try {
            String methodName = "addCustomer";

            Method method = customerController.getClass().getDeclaredMethod(methodName, HttpServletRequest.class);
            method.setAccessible(true);
            method.invoke(customerController, req);

            req.getRequestDispatcher("/success.jsp").forward(req, resp);
        } catch (SecurityException | IllegalArgumentException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }
}
CustomerController.java:

package a1;

/* Imports */

@Named("customerController")
public class CustomerController implements Controller {

    @EJB
    private CustomerService customerServiceImpl;

    private void addCustomer(HttpServletRequest req) {
        long cn1 = Long.parseLong(req.getParameter("form_cust_no"));
        String n = req.getParameter("form_name");
        String s = req.getParameter("form_surname");

        try {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
            String formDate = req.getParameter("form_dob");
            java.util.Date dateUtil = sdf.parse(formDate);
            java.sql.Date dateSql = new java.sql.Date(dateUtil.getTime());
            Customer customer = new Customer(cn1, n, s, dateSql);

            customerServiceImpl.addCustomer(customer);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }
}
Web.xml:

<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0" metadata-complete="true">

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>a1.DispatcherServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/dispatcher/*</url-pattern>
    </servlet-mapping>

    <resource-ref>
        <res-ref-name>jdbc/MyDataSource</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
    </resource-ref>
</web-app>
文件夹结构:

我不建议像本例中那样基于字符串进行注入;您的代码实际上对我来说运行得很好,所以您项目中的其他错误导致了您没有发布的问题。通过使用编译的限定符而不是基于字符串的限定符,可以避免这些问题

因此,与此相反:

@Named("customerController")
public class CustomerController implements Controller {

只需这样做:(如果您只有一个
控制器的实现

你完成了。您没有将代码发布到
控制器
,或者如果有多个
控制器
的实现。假设您有多个实现,根据您的需求,有很多方法可以处理它

最简单的:

@Inject
private CustomerController customerController;
更灵活:

@Qualifier
@Retention(RUNTIME)
@Target({FIELD, TYPE})
public @interface Customer {
}

或者,您可能只有多个实现,但需要在应用程序范围内每隔一段时间更改一次实现:

@Inject
private Controller customerController;

然后激活替代方案:

<beans ... >
    <alternatives>
        <class>a1.AnotherCustomerController</class>
    </alternatives>
</beans>

a1.另一个客户控制器
祝你好运!用进一步的问题或跟进回帖

附言:


我使用了
@ApplicationScoped
而不是
@Dependent
,因为您的代码似乎没有共享状态

出色的工作为您的问题提供了100%的所需信息。我不知道你为什么会被否决,但你提问的方式令人难以置信。@exabrial我担心我可能包含了太多的信息。也许这就是投票失败的原因。谢谢你的提示。在web.xml中将
metadata complete
设置为
false
,似乎解决了这个问题。但是,我确实打算添加更多的
Controller
实现,然后使用属性文件将表单数据映射到相关的控制器。你提到的注释可能还有用。很高兴你能理解它!
@Inject
@Named("customerController")
private Controller customerController;
@Inject
private Controller customerController;
@ApplicationScoped
public class CustomerController implements Controller {
@Inject
private CustomerController customerController;
@Qualifier
@Retention(RUNTIME)
@Target({FIELD, TYPE})
public @interface Customer {
}
@Inject
@Customer
private Controller customerController;
@ApplicationScoped
@Customer
public class CustomerController implements Controller {
@Inject
private Controller customerController;
@ApplicationScoped
@Default
public class CustomerController implements Controller {
@ApplicationScoped
@Alternative
public class AnotherCustomerController implements Controller {
<beans ... >
    <alternatives>
        <class>a1.AnotherCustomerController</class>
    </alternatives>
</beans>