6

ジャージー: 1.12 春: 3.11 JDK: 1.6.0_35 Tomcat: 6..0.33

SpringServlet のコンテキストで Spring IoC コンテナーによってインスタンス化された Jersey サーブレットの ExceptionMapper インスタンスを登録しようとしていますが、Jersey サーブレット中に古い「コンポーネント クラス X のスコープはシングルトンでなければなりません」という例外が発生しています。初期化。現時点では実際のコードを投稿する立場にないので、実装の要点を示して、誰かに明らかな何かが飛び出すかどうか、または私が持っているドキュメントを指摘できるかどうかを確認します。逃した。

ExceptionMapper インスタンスは基本的に次のとおりです。

// ... package definitions omitted ...

@Provider
@Singleton
public class MyExceptionMapper
    implements ExceptionMapper<MyException>
{
    // ... injected attributes omitted ...

    @Override
    public Response toResponse(MyException exception)
    {
        // ... specific handling logic omitted ...

       return Response.status(Status.BAD_REQUEST).entity(exception.getMessage()).build();
    }
}

applicationContext.xml の Bean 定義は次のとおりです。デフォルトはシングルトン スコープです (明示的なスコープ指定子を追加しても動作は変わらないようです)。

<bean id="myExceptionMapper" class="my.package.MyExceptionMapper" />

web.xml の Spring コンテキスト ローダー リスナーと SpringServlet 構成は基本的にボイラープレートであり、MyExceptionMapper の Bean 定義が applicationContext.xml からコメント アウトされている場合、サーブレットは他の注入属性を使用して適切にロード、初期化、および動作します。しかし、Bean 定義が applicationContext.xml に存在する場合、次のようなログ メッセージが表示されます。

SpringProviderFactory - Registering Spring bean, myExpectionMapper, of type my.package.MyExceptionMapper as a provider class
SpringProviderFactory - Registering Spring bean, myServiceController, of type my.package.MyServiceController as a root resource class
... other root resource classes loading ...
SpringServlet - Exception occurred when initialization
java.lang.RuntimeException: The scope of the component class my.package.MyExceptionMapper must be a singleton
  at som.sun.jersey.core.spi.component.ioc.IoCProviderFactory.wrap(...)

初期化中に SpringServlet によって取得されるように、スキャンされたパッケージ階層に MyExceptionMapper を配置しようとしましたが、別のパッケージ階層に配置しようとしましたが、結果は変わりません。

これに関する支援やガイダンスをいただければ幸いです。

4

6 に答える 6

4

春の設定でスコープを明示的に追加すると、うまくいきました:

<bean id="exceptionMapper" class="my.pkg.MyExceptionMapper" scope="singleton" />
于 2013-04-15T15:49:39.403 に答える
4

私のはコンポーネントスキャンを行っている構造の下にあり、私のものは単にSpringレジストリとJerseyのExceptionMapper注釈が付けられています。@Component@Provider

私のコンポーネントスキャンは次のようになります。

<context:component-scan base-package="com.company.web"/>

そして、ExceptionMapperあなたのように見えます:

package com.mycompany.web.provider;

import com.mycompany.exception.SpecialException;
import com.mycompany.exception.Error;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import javax.ws.rs.ext.Provider;

@Provider
@Component
public class SpecialExceptionMapper implements ExceptionMapper<SpecialException> {

    @Autowired
    private MessageSource messageSource;

    @Override
    public Response toResponse(SpecialException exception) {

        Error error = new Error();


        error.errorMessage = messageSource.getMessage(exception.getResourceBundleKey(), exception.getArgs());

        return Response.status(Response.Status.BAD_REQUEST).
                entity(error).
                type(MediaType.APPLICATION_JSON).
                build();
    }
}
于 2013-02-18T19:18:29.593 に答える
1

私は同じ問題を抱えていましたが、 MessageReaderWriterProvider クラスで:

package my.provider.package;
...
@Provider
@Consumes({MediaType.APPLICATION_JSON, "text/json"})
@Produces({MediaType.APPLICATION_JSON, "text/json"})
public class ReRwProvider extends AbstractMessageReaderWriterProvider<Object> {
...
}

解決策は、web.xml の Jersey の SpringServlet の init-param タグにこのクラスのパッケージを追加することでした。

<init-param>
    <param-name>com.sun.jersey.config.property.packages</param-name>
    <param-value>my.provider.package</param-value>
</init-param>

Spring コンテキストでこの Bean を定義しないでください。

于 2013-02-18T14:26:46.020 に答える
0

また、カスタム ExceptionMapper が機能しないこともあり、常に機能するとは限りません。

だから私はジャージのソースコードをデバッグします。

クラス: org.glassfish.jersey.server.ServerRuntime、methed:mapException

 ...
 final long timestamp = tracingLogger.timestamp(ServerTraceEvent.EXCEPTION_MAPPING);
 **ExceptionMapper mapper = runtime.exceptionMappers.findMapping(throwable);**
 if (mapper != null) {
      request.getRequestEventBuilder().setExceptionMapper(mapper);

... マッパーが null の場合、カスタム ExceptionMapper は機能しません。

クラス: org.glassfish.jersey.internal.ExceptionMapperFactory メソッド: ExceptionMapperFactory

例外マッパー:(1つの同じ例外をマッピングする2つの例外があります:java.lang.Exception)

org.glassfish.jersey.server.mvc.internal.ErrorTemplateExceptionMapper@6473fc2,class java.lang.Exception

...

com.baidu.ssp.web.ws.exception.BaseExceptionMapper@7a84639c,class java.lang.Exception

それは、MvcFeature にあるためです。

@Override public boolean configure(final FeatureContext context) { final Configuration config = context.getConfiguration();

if (!config.isRegistered(ErrorTemplateExceptionMapper.class)) {
    context.register(ErrorTemplateExceptionMapper.class);
    context.register(new MvcBinder());

    return true;
}

return false;

} ErrorTemplateExceptionMapper も ExceptionMapper に追加されます。

だから私は私のカスタム MapperException の汎用性タイプを変更します: ExceptionMapper を ExceptionMapper に

私の解決策はあなたに合わないかもしれません、主な問題はExceptionMapperです

于 2014-11-26T10:32:29.963 に答える