Maven:UTF-8中的源代码无法正常工作?

sof*_*afe 37 java encoding utf-8 maven

我正在将一个项目从Ant转换为Maven,我遇到了一个处理UTF-8字符的特定单元测试的问题.问题是关于以下字符串:

String l_string = "?äÁÓý\n€????\n?????";
Run Code Online (Sandbox Code Playgroud)

问题是单元测试失败,因为String被读取如下:

?äÁÓý
€????
?????
Run Code Online (Sandbox Code Playgroud)

java类保存为UTF-8,我还在pom.xml中指定了UTF-8的构建编码.

这是我的pom.xml的摘录:

...

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

...

<build>
<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
            <source>1.6</source>
            <target>1.6</target>
            <encoding>${project.build.sourceEncoding}</encoding>
        </configuration>
    </plugin>
    <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.4</version>
        <configuration>
            <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
        </configuration>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-plugin</artifactId>
      <version>2.15</version>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-report-plugin</artifactId>
      <version>2.15</version>
    </plugin>
 </plugins>
</build>
Run Code Online (Sandbox Code Playgroud)

我错过了什么吗?如果有人能在这里帮助我,那就太好了.

更新

关于测试代码:

@Test
public void testTransformation()
{

    String l_string = "?äÁÓý\n€????\n?????";
    System.out.println( ">>> " + l_string );
     c_log.info( l_string );
    StringBuffer l_stringBuffer = new StringBuffer();
    int l_stringLength = l_string.length();

    String l_fileName = System.getProperty( "user.dir" ) + File.separator + "transformation" + File.separator + "TransformationMap.properties";
    Transformation.init( l_fileName );

    Properties l_props = Transformation.getProps();
    for ( int i = 0; i < l_stringLength; i++ )
    {
        char l_char = l_string.charAt( i );
        int l_intValue = (int) l_char;
        if ( l_intValue <= 255 )
        {
            l_stringBuffer.append( l_char );
        }
        else
        {
            l_stringBuffer.append( l_props.getProperty( String.valueOf( l_char ), "" ) );
        }
    }
    c_log.info( l_stringBuffer.toString() );
    byte[] l_bytes = l_string.getBytes();
    byte[] l_transformedBytes = Transformation.transform( l_bytes );
    assertNotNull( l_transformedBytes );

}
Run Code Online (Sandbox Code Playgroud)

以下逻辑并不真正相关(?)因为在第一个sysout之后提到了"?" 打印而不是正确的字符(因此以下测试失败).也没有使用默认平台编码.

测试根据TransformationMap.properties文件转换每个字符,该文件采用以下格式(仅作摘录):

Ý=Y
ý=y
Ž=Z
ž=z
°=.
€=EUR
Run Code Online (Sandbox Code Playgroud)

应该注意的是,当我使用Ant构建项目时,测试运行没有任何问题.

sof*_*afe 116

我自己找到了一个"解决方案":

我不得不将编码传递给maven-surefire-plugin,但通常情况下

<encoding>${project.build.sourceEncoding}</encoding>
Run Code Online (Sandbox Code Playgroud)

不工作.我仍然不知道为什么,但是当我将命令行参数传递给插件时,测试按原样运行:

<plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-plugin</artifactId>
      <version>2.15</version>
      <configuration>
        <argLine>-Dfile.encoding=UTF-8</argLine>
      </configuration>
</plugin>
Run Code Online (Sandbox Code Playgroud)

感谢您的所有回复和其他评论!

  • 也许更有弹性的解决方案是`<argLine> -Dfile.encoding = $ {project.build.sourceEncoding} </ argLine>` (8认同)
  • 这是设计的,显然是:http://jira.codehaus.org/browse/SUREFIRE-951 (7认同)
  • Windows-1252。似乎使用了OS的默认编码,但是即使在surefire插件中,pom文件中的各处编码也都设置为UTF-8。 (2认同)
  • 这仍然是开放的.在https://issues.apache.org/jira/browse/SUREFIRE-951上将问题从codehaus移至apache (2认同)

Aar*_*lla 9

  1. 在调试Unicode问题时,请确保将所有内容转换为ASCII,这样您就可以阅读并理解String内部的内容而无需猜测.这意味着你应该使用,例如,StringEscapeUtils公地lang3ä\u00e4.这样,您可以确定您看到,?因为控制台无法打印它.你可以区分""(\u0020)和""(\u00a0)

    在测试用例中,请尽早检查输入的转义版本,以确保数据实际上符合您的预期.

    所以上面的代码应该是:

    assertEquals("\u010d\u00e4\u....", escape(l_string));
    
    Run Code Online (Sandbox Code Playgroud)
  2. 确保使用正确的文件I/O编码.永远不要使用Java的默认编码,始终使用InputStreamReader/ OutputStreamWriter并指定要使用的编码.

  3. POM看起来很正确.运行mvn-X以确保它拿起正确的选项并运行使用正确的选项Java编译器.mvn help:effective-pom也许会有所帮助.

  4. 反汇编类文件以检查字符串.Java将?用来表示它无法读取某些内容.

    如果你得到了?from System.out.println( ">>> " + l_string );,这意味着代码没有用UTF-8编译,或者源文件可能用另一种Unicode编码(UTF-16或类似代码)保存.

    另一个问题来源可能是属性文件.确保它已使用ISO-8859-1保存,并且未被编译过程修改.

  5. 确保Maven实际编译您的文件.使用mvn clean强制全重新编译.


Dav*_*nka 6

我遇到了这种真正有弹性的问题并设置环境变量

MAVEN_OPTS=-Dfile.encoding=UTF-8
Run Code Online (Sandbox Code Playgroud)

为我解决了这个问题。


Eri*_*nez 5

这对我有用:

...
 <properties>
        **<project.build.sourceEncoding>ISO-8859-1</project.build.sourceEncoding>
        <project.reporting.outputEncoding>ISO-8859-1</project.reporting.outputEncoding>**
    </properties>
...
  <build>
    <finalName>Project</finalName>

    <sourceDirectory>src</sourceDirectory>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
          **<encoding>${project.build.sourceEncoding}</encoding>**
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.2</version>
        <configuration>
          <warSourceDirectory>WebContent</warSourceDirectory>
        </configuration>
      </plugin>
    </plugins>
  </build>
Run Code Online (Sandbox Code Playgroud)