使用Oracle 12c和ojdbc7 / ojdbc8驱动程序的字符无效

时间:2018-01-30 16:16:40

标签: java oracle character-encoding ojdbc

在Oracle 12c数据库中通过REST API保存数据后,从数据库中选择数据时,无法识别特殊字符(它们显示为奇怪的字符)。

可能是Oracle数据库配置吗?我将在这里添加所有数据:

  • Oracle版本:12.1.0.2.0
  • Java驱动程序版本:ojdbc7-12.1.0.1.jar(最新版本)
  • Java版本:JDK 8u162(最新版本)
  • Application Server:WildFly 9.0.1

如果我们将驱动程序降级到OJDBC 6,它适用于数据库中已存在的某些字符。

我们还将orai18n.jar驱动程序添加到JBoss类路径中,但没有任何更改。

Oracle数据库NLS配置

enter image description here

POST

使用JSON有效负载进行非常简单的后期操作:

enter image description here

GET

插入数据库后,我们获取数据,但我们无法看到特殊字符:

enter image description here

更新:我添加了另一个类型为NVARCHAR2的列,得到了回复:

enter image description here

代码

我们使用简单的REST服务类在这个简单的项目中隔离了问题。我们认为Hibernate可能是原因,但我们已经实现了纯JDBC API,我们得到了相同的结果。

@Path("/parameter")
@Stateless
public class ParameterResource {

    @PersistenceContext
    private EntityManager em;

    @POST
    public void post(Parameter p) throws Exception {
        System.out.println("Value on POST: " + p.getValue());
        em.persist(p);
    }

    @GET
    @Path("/{id}")
    public Parameter get(@PathParam("id") String id) throws Exception {
        Parameter p = em.find(Parameter.class, id);
        System.out.println("Value on GET: " + p.getValue());
        return p;
    }

}

表DDL如下:

Name   Null?    Type
------ -------- -------------- 
ID     NOT NULL VARCHAR2(20)   
VALUE           VARCHAR2(200)  
VALUEN          NVARCHAR2(200) 

控制台输出如下,因此REST API应该没有问题,因为数据似乎在数据库界面上“已损坏”:

enter image description here

甚至添加了一个过滤器,以确保我们在Web服务中来回使用正确的编码。

@WebFilter("myFilter")
public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
    }

}

SQL Developer

使用SQL Developer时也会出现问题,而SQL Developer恰好在Java上运行并使用OJDBC 8驱动程序进行连接。

enter image description here

1 个答案:

答案 0 :(得分:2)

您的数据库是US7ASCII数据库。因此,您可以存储在VARCHAR2列中的唯一字符是ASCII字符。对于非ASCII字符,您必须使用NVARCHAR2列。我非常怀疑这可能适用于旧版本的JDBC驱动程序,或者您使用的是另一个字符集(如UTF8)的不同数据库。