Java 使用Oracle 12c和ojdbc7/ojdbc8驱动程序的字符无效
通过Oracle 12c数据库中的REST API持久化数据后,从数据库中选择数据时,特殊字符将无法识别(它们显示为奇怪的字符) 可能是Oracle数据库配置吗?我将在此处添加所有数据:Java 使用Oracle 12c和ojdbc7/ojdbc8驱动程序的字符无效,java,oracle,character-encoding,ojdbc,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(最新版本) 应用服务器:WildFly 9.0.1 如果我们将驱动程序降级为OJDBC 6,并且它对数据库中已经存在的某些字符有效 我们还将orai18n.ja
- Oracle版本:12.1.0.2.0
- Java驱动程序版本:ojdbc7-12.1.0.1.jar(最新版本)
- Java版本:JDK 8u162(最新版本)
- 应用服务器:WildFly 9.0.1
orai18n.jar
驱动程序添加到JBoss类路径中,但没有任何更改
Oracle数据库NLS配置
邮递
使用JSON负载进行非常简单的post操作:
得到
插入数据库后,我们获得了数据,但无法看到特殊字符:
更新:我添加了另一个类型为nvarhar2
的专栏,得到了以下回应:
代码
我们用一个简单的REST服务类隔离了这个简单项目中的问题。我们认为Hibernate可能是原因,但是我们实现了一个纯JDBCAPI,并且得到了相同的结果
@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应该没有问题,因为数据库接口上的数据似乎已“损坏”:
甚至还添加了一个过滤器,以确保我们在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开发人员
当使用SQLDeveloper时,问题也会发生,它恰好在Java上运行,并使用OJDBC8驱动程序进行连接
您的数据库是US7ASCII数据库。因此,VARCHAR2列中只能存储ASCII字符。对于非ASCII字符,必须使用NVARCHAR2列。我非常怀疑这是否适用于较旧版本的JDBC驱动程序,或者您使用的是另一个字符集(如UTF8)的不同数据库。您的数据库是US7ASCII数据库。因此,VARCHAR2列中只能存储ASCII字符。对于非ASCII字符,必须使用NVARCHAR2列。我非常怀疑这是否适用于较旧版本的JDBC驱动程序,或者您使用的是另一个字符集(如UTF8)的不同数据库。您的表使用的是
VARCHAR2
还是NVARCHAR2
?——您是否尝试调试您的代码,以查看Java代码是否看到正确的字符,即确定是客户端Java还是Java数据库导致了问题?@Andreas我在测试中添加了NVARCHAR
,请检查我的问题更新,它仍然会给出奇怪的字符。是的,我已经检查过了,问题发生在“Java数据库”中。1)最新的Java驱动程序版本是12.2.0.1,如果要匹配服务器版本,则为12.1.0.2。请参阅--2)您是否尝试指定defaultNChar
属性?参见@Andreas 1)相同的问题2)它适用于NVARCHAR2
字段,但不适用于VARCHAR2
。这是一个遗留数据库,我们无法更改字段类型,为什么它不适用于VARCHAR2
?我应该开一张甲骨文的票吗?我很惊讶它居然奏效了。您的字符集是US7ASCII
,这意味着7位ASCII,没有任何重音字符。您的表使用的是VARCHAR2
还是NVARCHAR2
您是否尝试调试您的代码,以查看Java代码是否看到正确的字符,即确定是客户端Java还是Java数据库导致了问题?@Andreas我在测试中添加了NVARCHAR
,请检查我的问题更新,它仍然会给出奇怪的字符。是的,我已经检查过了,问题发生在“Java数据库”中。1)最新的Java驱动程序版本是12.2.0.1,如果要匹配服务器版本,则为12.1.0.2。请参阅--2)您是否尝试指定defaultNChar
属性?参见@Andreas 1)相同的问题2)它适用于NVARCHAR2
字段,但不适用于VARCHAR2
。这是一个遗留数据库,我们无法更改字段类型,为什么它不适用于VARCHAR2
?我应该开一张甲骨文的票吗?我很惊讶它居然奏效了。您的字符集是US7ASCII
,这意味着7位ASCII,没有任何重音字符。现在看起来很明显。我们在运行OJDBC6测试时也犯了一个错误,因此您是正确的。我们已经联系了Oracle DBA,他将把数据库编码改为8位字符集。现在看来这很明显。我们在运行OJDBC6测试时也犯了一个错误,因此您是正确的。我们已经联系了Oracle DBA,他将把数据库编码更改为8位字符集。