【发布时间】:2018-01-30 16:16:39
【问题描述】:
通过我们的 REST API 在 Oracle 12c 数据库中持久化数据后,在从数据库中选择数据时无法识别特殊字符(它们显示为奇怪的字符)。
可能是 Oracle 数据库配置吗?我将在此处添加所有数据:
- Oracle 版本:12.1.0.2.0
- Java 驱动程序版本:ojdbc7-12.1.0.1.jar(最新可用)
- Java 版本:JDK 8u162(最新可用)
- 应用服务器:WildFly 9.0.1
如果我们将驱动程序降级到 OJDBC 6 并且它适用于数据库中已经存在的某些字符。
我们还在 JBoss 类路径中添加了 orai18n.jar 驱动程序,但没有任何改变。
Oracle 数据库 NLS 配置
发布
使用 JSON 有效负载的非常简单的后期操作:
获取
插入数据库后,我们得到了数据,但我们看不到特殊字符:
更新:我添加了另一个类型为 NVARCHAR2 的列,得到了回复:
代码
我们用一个简单的 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 应该没有问题,因为数据似乎在数据库接口处“损坏”了:
甚至添加了一个过滤器来确保我们在 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 开发人员
使用 SQL Developer 时也会出现该问题,该程序恰好在 Java 上运行并使用 OJDBC 8 驱动程序进行连接。
【问题讨论】:
-
您的表使用的是
VARCHAR2还是NVARCHAR2? --- 您是否尝试调试代码以查看 Java 代码是否看到正确的字符,即确定是客户端 Java 还是导致问题的 Java 数据库? -
@Andreas 我已将
NVARCHAR添加到测试中,请检查我的问题更新,它仍然给出奇怪的字符。是的,我已经检查过了,问题发生在“Java 数据库”中。 -
1) 最新的 Java 驱动程序版本是 12.2.0.1,如果要匹配服务器版本,则为 12.1.0.2。请参阅oracle.com/technetwork/database/features/jdbc/index-091264.html --- 2) 您是否尝试过指定
defaultNChar属性?见docs.oracle.com/cd/E18283_01/java.112/e16548/… -
@Andreas 1) 同样的问题 2) 它适用于
NVARCHAR2字段,但不适用于VARCHAR2。这是一个遗留数据库,我们无法更改字段类型,为什么它不适用于VARCHAR2?我应该打开 Oracle 票证吗? -
我很惊讶它曾经奏效过。您的字符集是
US7ASCII,表示 7 位 ASCII,没有 任何 重音字符。
标签: java oracle character-encoding ojdbc