Jetty-7.1.6.v20100715 获取 X509Certificate 时抛出 ClassCastException
我编写的过滤器抛出了 ClassCastException
[Ljava.security.cert.X509Certificate; 无法转换为 java.security.cert.X509Certificate
当我尝试转换从 ServletRequest 属性中提取的对象时,
public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws
IOException, ServletException
{
X509Certificate cert = (X509Certificate) req.getAttribute("javax.servlet.request.X509Certificate");
System.out.println("cert dn " + cert.getSubjectDN().toString());
filterChain.doFilter(req, res);
}
,即当我深入挖掘时,我了解到像这样的异常很可能是由不同的类加载器引起的,尽管它们是同一类类型。我该如何解决这个问题?
谢谢,
我使用了以下 Spring 3 配置来逐步加载 Jetty 7
<bean class="org.eclipse.jetty.server.Server"
init-method="start" destroy-method="stop">
<property name="connectors">
<list>
<bean id="SSLConnector" class="org.eclipse.jetty.server.ssl.SslSocketConnector">
<property name="port" value="8553"/>
<property name="maxIdleTime" value="3600000"/>
<property name="soLingerTime" value="-1"/>
<property name="needClientAuth" value="true"/>
<property name="sslContext">
<ref bean="sslContext"/>
</property>
</bean>
</list>
</property>
<property name="handler">
<bean name="contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection">
<property name="handlers">
<list>
<bean class="org.eclipse.jetty.servlet.ServletContextHandler">
<property name="contextPath">
<value>/caas</value>
</property>
<property name="resourceBase" value="src/main/secure_webapp"/>
<property name="sessionHandler">
<bean class="org.eclipse.jetty.server.session.SessionHandler"/>
</property>
<property name="servletHandler">
<bean class="org.eclipse.jetty.servlet.ServletHandler">
<property name="filters">
<list>
<bean class="org.eclipse.jetty.servlet.FilterHolder">
<property name="name" value="myfilter"/>
<property name="filter">
<bean class="com.acme.MyFilter"/>
</property>
</bean>
</list>
</property>
<property name="filterMappings">
<list>
<bean class="org.eclipse.jetty.servlet.FilterMapping">
<property name="pathSpec">
<value>/*</value>
</property>
<property name="filterName"
value="myfilter"/>
</bean>
</list>
</property>
<property name="servlets">
<list>
<bean class="org.eclipse.jetty.servlet.ServletHolder">
<property name="name" value="default"/>
<property name="servlet">
<bean class="org.eclipse.jetty.servlet.DefaultServlet"/>
</property>
</bean>
</list>
</property>
<property name="servletMappings">
<list>
<bean class="org.eclipse.jetty.servlet.ServletMapping">
<property name="pathSpecs">
<list>
<value>/</value>
</list>
</property>
<property name="servletName" value="default"/>
</bean>
</list>
</property>
</bean>
</property>
</bean>
</list>
</property>
</bean>
</property>
</bean>
The filter I wrote threw ClassCastException
[Ljava.security.cert.X509Certificate; cannot be cast to java.security.cert.X509Certificate
when I tried to cast an Object extracted from the ServletRequest attribute, i.e.
public void doFilter(ServletRequest req, ServletResponse res, FilterChain filterChain) throws
IOException, ServletException
{
X509Certificate cert = (X509Certificate) req.getAttribute("javax.servlet.request.X509Certificate");
System.out.println("cert dn " + cert.getSubjectDN().toString());
filterChain.doFilter(req, res);
}
As I dug deeper I understood that exception like this was most probably caused by different classloaders though they are of same class type. How do I resolve this?
Thanks
I used the following Spring 3 configurarion to load Jetty 7 piecemeal
<bean class="org.eclipse.jetty.server.Server"
init-method="start" destroy-method="stop">
<property name="connectors">
<list>
<bean id="SSLConnector" class="org.eclipse.jetty.server.ssl.SslSocketConnector">
<property name="port" value="8553"/>
<property name="maxIdleTime" value="3600000"/>
<property name="soLingerTime" value="-1"/>
<property name="needClientAuth" value="true"/>
<property name="sslContext">
<ref bean="sslContext"/>
</property>
</bean>
</list>
</property>
<property name="handler">
<bean name="contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection">
<property name="handlers">
<list>
<bean class="org.eclipse.jetty.servlet.ServletContextHandler">
<property name="contextPath">
<value>/caas</value>
</property>
<property name="resourceBase" value="src/main/secure_webapp"/>
<property name="sessionHandler">
<bean class="org.eclipse.jetty.server.session.SessionHandler"/>
</property>
<property name="servletHandler">
<bean class="org.eclipse.jetty.servlet.ServletHandler">
<property name="filters">
<list>
<bean class="org.eclipse.jetty.servlet.FilterHolder">
<property name="name" value="myfilter"/>
<property name="filter">
<bean class="com.acme.MyFilter"/>
</property>
</bean>
</list>
</property>
<property name="filterMappings">
<list>
<bean class="org.eclipse.jetty.servlet.FilterMapping">
<property name="pathSpec">
<value>/*</value>
</property>
<property name="filterName"
value="myfilter"/>
</bean>
</list>
</property>
<property name="servlets">
<list>
<bean class="org.eclipse.jetty.servlet.ServletHolder">
<property name="name" value="default"/>
<property name="servlet">
<bean class="org.eclipse.jetty.servlet.DefaultServlet"/>
</property>
</bean>
</list>
</property>
<property name="servletMappings">
<list>
<bean class="org.eclipse.jetty.servlet.ServletMapping">
<property name="pathSpecs">
<list>
<value>/</value>
</list>
</property>
<property name="servletName" value="default"/>
</bean>
</list>
</property>
</bean>
</property>
</bean>
</list>
</property>
</bean>
</property>
</bean>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在这种情况下,我不认为这是重复的类问题,因为 X509Certificate 包含在核心 JRE 库中。据我所知,没有其他库提供这个抽象类。
我认为问题是
getAttribute()
返回一个 X509Certificate 对象数组,而您将其强制转换为单个对象。 ClassCastException消息的开头[L
表示返回的对象是一个数组。尝试转换为证书数组:
另外,我认为您应该从 getAttribute() 检索对象并使用 instanceof 检查它是否包含所需的类型,并且可能以不同的方式处理它们。
I don't think it's a duplicate class problem in this case, because X509Certificate is contained in the core JRE libraries. There is, afaik, no other library which provides this abstract class.
I think the problem is the
getAttribute()
returns an array of X509Certificate objects, whereas you cast it down to a single object. The beginning[L
of the ClassCastException message indicates that the object returned is an array.Try casting to an array of certificates:
Also, i think that you should retrieve the object from getAttribute() and use instanceof checks to see whether it contains the desired types and maybe handle them differently.