使用 Oracle 12c 和 ojdbc7 / ojdbc8 驱动程序的无效字符
Invalid characters using Oracle 12c and ojdbc7 / ojdbc8 driver
在 Oracle 12c 数据库中通过我们的 REST API 持久化数据后,从数据库中选择数据时无法识别特殊字符(它们显示为奇怪的字符)。
会不会是Oracle数据库配置?我将在此处添加所有数据:
- 甲骨文版本:12.1.0.2.0
- Java驱动版本:ojdbc7-12.1.0.1.jar(最新)
- Java 版本:JDK 8u162(最新可用)
- 应用服务器:WildFly 9.0.1
如果我们将驱动程序降级到 OJDBC6 并且它适用于数据库中已经存在的某些字符。
我们还将 orai18n.jar
驱动程序添加到 JBoss class 路径中,但没有任何改变。
Oracle 数据库 NLS 配置
POST
非常简单的 post 操作 JSON 负载:
得到
插入数据库后,我们得到了数据,但我们看不到特殊字符:
更新:我添加了另一个类型为 NVARCHAR2
的列,得到了响应:
代码
我们用简单的 REST 服务隔离了这个简单项目中的问题 class。我们认为 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;
}
}
Table DDL如下:
Name Null? Type
------ -------- --------------
ID NOT NULL VARCHAR2(20)
VALUE VARCHAR2(200)
VALUEN NVARCHAR2(200)
控制台输出如下,所以REST应该没有问题API因为数据似乎"corrupted"就在数据库接口:
甚至添加了过滤器以确保我们在 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时也出现该问题,恰好运行 on Java,使用OJDBC 8驱动连接。
您的数据库是US7ASCII 数据库。因此,您可以在 VARCHAR2 列中存储的唯一字符是 ASCII 字符。对于非 ASCII 字符,您必须使用 NVARCHAR2 列。我非常怀疑这是否适用于旧版本的 JDBC 驱动程序,或者您可能正在使用具有其他字符集(例如 UTF8)的不同数据库。
在 Oracle 12c 数据库中通过我们的 REST API 持久化数据后,从数据库中选择数据时无法识别特殊字符(它们显示为奇怪的字符)。
会不会是Oracle数据库配置?我将在此处添加所有数据:
- 甲骨文版本:12.1.0.2.0
- Java驱动版本:ojdbc7-12.1.0.1.jar(最新)
- Java 版本:JDK 8u162(最新可用)
- 应用服务器:WildFly 9.0.1
如果我们将驱动程序降级到 OJDBC6 并且它适用于数据库中已经存在的某些字符。
我们还将 orai18n.jar
驱动程序添加到 JBoss class 路径中,但没有任何改变。
Oracle 数据库 NLS 配置
POST
非常简单的 post 操作 JSON 负载:
得到
插入数据库后,我们得到了数据,但我们看不到特殊字符:
更新:我添加了另一个类型为 NVARCHAR2
的列,得到了响应:
代码
我们用简单的 REST 服务隔离了这个简单项目中的问题 class。我们认为 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;
}
}
Table DDL如下:
Name Null? Type
------ -------- --------------
ID NOT NULL VARCHAR2(20)
VALUE VARCHAR2(200)
VALUEN NVARCHAR2(200)
控制台输出如下,所以REST应该没有问题API因为数据似乎"corrupted"就在数据库接口:
甚至添加了过滤器以确保我们在 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时也出现该问题,恰好运行 on Java,使用OJDBC 8驱动连接。
您的数据库是US7ASCII 数据库。因此,您可以在 VARCHAR2 列中存储的唯一字符是 ASCII 字符。对于非 ASCII 字符,您必须使用 NVARCHAR2 列。我非常怀疑这是否适用于旧版本的 JDBC 驱动程序,或者您可能正在使用具有其他字符集(例如 UTF8)的不同数据库。