java.lang.ClassCastException:[B>无法强制转换为java.lang.String

the*_*ava 9 java spring hibernate coding-style

public Login authenticate(Login login) {
        try {
            MessageDigest md = MessageDigest.getInstance("SHA-256");
            String password = login.getPassword();
            try {
                md.update(password.getBytes("UTF-16"));
                byte[] digest = md.digest();
                String query = "SELECT L FROM Login AS L WHERE L.email=? AND L.password=?";
                Object[] parameters = { login.getEmail(), digest };
                List<Login> resultsList = (getHibernateTemplate().find(query,parameters));
                 if (resultsList.isEmpty()) {
                         //error dude
                     }
                 else if (resultsList.size() > 1) {
                         //throw expections
                     }
                 else {
                       Login login1 = (Login) resultsList.get(0);
                       return login1;
                 }
            } catch (UnsupportedEncodingException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        } catch (NoSuchAlgorithmException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }                
       return null;  
    }
Run Code Online (Sandbox Code Playgroud)

例外

> java.lang.ClassCastException: [B
> cannot be cast to java.lang.String
>         at org.hibernate.type.StringType.toString(StringType.java:44)
>         at org.hibernate.type.NullableType.nullSafeToString(NullableType.java:93)
>         at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:140)
>         at org.hibernate.type.NullableType.nullSafeSet(NullableType.java:116)
>         at org.hibernate.param.PositionalParameterSpecification.bind(PositionalParameterSpecification.java:39)
>         at org.hibernate.loader.hql.QueryLoader.bindParameterValues(QueryLoader.java:491)
>         at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1563)
>         at org.hibernate.loader.Loader.doQuery(Loader.java:673)
>         at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:236)
>         at org.hibernate.loader.Loader.doList(Loader.java:2213)
>         at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2104)
>         at org.hibernate.loader.Loader.list(Loader.java:2099)
>         at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:378)
>         at org.hibernate.hql.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:338)
>         at org.hibernate.engine.query.HQLQueryPlan.performList(HQLQueryPlan.java:172)
>         at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1121)
>         at org.hibernate.impl.QueryImpl.list(QueryImpl.java:79)
>         at org.springframework.orm.hibernate3.HibernateTemplate$29.doInHibernate(HibernateTemplate.java:856)
>         at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:373)
>         at org.springframework.orm.hibernate3.HibernateTemplate.find(HibernateTemplate.java:847)
>         at com.intermedix.services.LoginService.authenticate(LoginService.java:30)
>         at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
> Method)
>         at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>         at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>         at java.lang.reflect.Method.invoke(Method.java:597)
>         at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:301)
>         at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
>         at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
>         at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
>         at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
>         at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
>         at $Proxy31.authenticate(Unknown Source)
>         at com.intermedix.ui.LoginDailog.checkLogin(LoginDailog.java:106)
>         at com.intermedix.ui.LoginDailog.access$0(LoginDailog.java:102)
>         at com.intermedix.ui.LoginDailog$2.handleAction(LoginDailog.java:88)
>         at com.vaadin.event.ActionManager.handleAction(ActionManager.java:228)
>         at com.vaadin.event.ActionManager.handleActions(ActionManager.java:198)
>         at com.vaadin.ui.Panel.changeVariables(Panel.java:345)
>         at com.vaadin.ui.Window.changeVariables(Window.java:1073)
>         at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.handleVariables(AbstractCommunicationManager.java:1094)
>         at com.vaadin.terminal.gwt.server.AbstractCommunicationManager.doHandleUidlRequest(AbstractCommunicationManager.java:590)
>         at com.vaadin.terminal.gwt.server.CommunicationManager.handleUidlRequest(CommunicationManager.java:266)
>         at com.vaadin.terminal.gwt.server.AbstractApplicationServlet.service(AbstractApplicationServlet.java:476)
>         at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
>         at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
>         at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:390)
>         at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
>         at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
>         at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
>         at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
>         at org.mortbay.jetty.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:230)
>         at org.mortbay.jetty.handler.HandlerCollection.handle(HandlerCollection.java:114)
>         at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
>         at org.mortbay.jetty.Server.handle(Server.java:326)
>         at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
>         at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:943)
>         at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)
>         at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
>         at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
>         at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:410)
>         at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
Run Code Online (Sandbox Code Playgroud)

gab*_*uzo 7

似乎数据库的密码列是一个映射为StringJava 的类型(varchar最有可能).所以hibernate无法将你的字节转换array成a String.

您可以将您的行更改为:

 String digest = new String(md.digest());
 String query = "SELECT L FROM Login AS L WHERE L.email=? AND L.password=?";
 Object[] parameters = { login.getEmail(), digest };
Run Code Online (Sandbox Code Playgroud)

但它可能无法工作,因为无论编码如何,摘要肯定都包含不能映射到字符的字节.您应该使用base64编码将二进制blob映射到String.

另一个解决方案是改变你的数据库方案,并使该password字段成为二进制而不是varchar.

在这两种情况下,您都需要知道password字段在数据库中的插入方式.

您对代码的一些评论:

我发现您通过用户名和密码从数据库中选择一行来检查密码,这一点很奇怪.我更合乎逻辑地选择仅使用用户,然后根据数据库上返回的密码验证提供的密码.

您使用哈希函数来确保您的密码不会以纯文本格式存储在数据库中.非常好.但是你的方案有一个很大的缺陷:如果几个用户拥有相同的密码,那么散列密码在数据库中是相同的.因此,如果您有权访问数据库并知道一个用户的密码,那么找到共享此密码的所有用户将非常容易.为了构建更安全的东西,您应该使用包含一些的密码编码方案.