java web开发问题集锦

简单

1. cannot resolve symbol Test(Junit)

以IntelliJ作为java 开发IDE,代码里写有一些方法,习惯是在当前类里面再写一个测试方法(因为并不是生产代码,习惯不好貌似不要紧),在测试方法上面添加注解@Test,但是报错cannot resolve symbol Test。感觉很莫名其妙,pom.xml文件里面已经添加JUnit的dependency啊,难道是我的IntelliJ的配置问题。智能IDE如IntelliJ,不是应该默认支持JUnit的么?后来明白,原来是在pom.xml中引入JUnit时,指定有,而我前面说过代码以及测试代码都是在src/main/java/下面。把scope去掉即可。
可是问题来的时候,一如蒙头苍蝇各种百度/google,问题的根源是什么都不知道,都没有分析一下,就去问百度/google。
总结:不要急着解决问题,要先冷静分析一下,这是不是问题。

2. mockito-core.jar & mockito-all.jar的选择问题

在写mockito的demo程序的时候,并不知道应该使用那个jar,于是把mockito-core以及mockito-all全部写入pom.xml文件中,一开始也没有什么问题。但是当用到静态方法argThat,就懵逼了,不知道应该导入哪一个jar包的类的哪个方法。
一开始报错:IncompatibleClassChangeError
http://stackoverflow.com/questions/1980452/what-causes-java-lang-incompatibleclasschangeerror
意思是changing non-static non-private fields/methods to be static or vice versa.
查看出错一行代码,argThat的原因。
应该导入下面这个静态方法,而不是上面的。
import static org.mockito.hamcrest.MockitoHamcrest.argThat;//来自mockito-core.jar

import static org.mockito.ArgumentMatchers.argThat;//来自mockito-core.jar

import static org.mockito.Matchers.argThat;//来自mockito-all.jar
通过反编译工具查看源码,mockito-all.jar基本上是由mockito-core.jar以及hamcrest-core(maven repository的介绍:This is the core API of hamcrest matcher framework to be used by third-party framework providers. This includes the a foundation set of matcher implementations for common operations.)以及另外一个没怎么听过,更没有用过的objenesis(maven repository的介绍:A library for instantiating Java objects)三个jar包组成。
使用第二个argThat则报错:
java.lang.NoSuchMethodError: org.mockito.internal.progress.ThreadSafeMockingProgress.mockingProgress()Lorg/mockito/internal/progress/MockingProgress;
以及java.lang.NoSuchMethodError: org.mockito.internal.matchers.InstanceOf.(Ljava/lang/Class;Ljava/lang/String;)V
http://stackoverflow.com/questions/31962003/mockito-test-gives-no-such-method-error-when-run-as-junit-test-but-when-jars-are
java web开发问题集锦_第1张图片
Eclipse快捷键Ctrl+ Shift +T, 发现当前classpath下面有太多jar包包含这个类ThreadSafeMockingProgress。由于生产项目使用的mockito是mockito-core,一开始在pom.xml文件中把mockito-all注释,发现导致很多unresolved symbol报错,意思是没有导入相应的jar依赖。于是转换方向,注释mockito-core,使用mockito-all。问题解决。
另外,从上面的截图,也验证mockito-all这个jar包包含mockito-core这个jar包。

3. apache poi jar包解析excel

在使用apache的poi这个jar包做excel表格的解析和生成的demo程序时。遇到报错信息:
java.lang.IllegalAccessError: tried to access method org.apache.poi.util.POILogger.log from class org.apache.poi.openxml4j.opc.ZipPackage
参考https://stackoverflow.com/questions/34630209/java-lang-illegalaccesserror-tried-to-access-method-org-apache-poi-util-poilogg
最开始pom文件只有两处使用到poi相关的dependency:


	org.apache.poi
	poi
	3.15
 

	fr.opensagres.xdocreport
	org.apache.poi.xwpf.converter.core
	1.0.6

把下面这个不明所以的的dependency注释掉,Eclipse报解析错误,意思是找不到类(cannot resolve symbol),即不能通过编译。这给我一种错觉,以为我的dependency没有搞错,需要添加org.apache.poi.xwpf.converter.core这个jar包。
因而上述答案看得不明所以。
但是多次Google以及百度给出的解释都是POI jar包版本的问题。比如这里http://blog.csdn.net/u013361445/article/details/50491815
http://stackoverflow.com/questions/33415904/apache-poi-parsing-error

org.apache.poi.xwpf.converter.core注释掉,然后添加


    org.apache.poi
    poi-ooxml
    3.15


    org.apache.poi
    poi-ooxml-schemas
    3.15

发现没有错误,没有cannot resolve symbol,可以正常编译。

当然,上面两个poi个jar包有可能有冗余的情况,即有可能没有使用到某个jar;就比如使用spring时添加dependency一样,也是乱加一气。

但是运行代码之后还是报错:java.lang.NoClassDefFoundError: org/openxmlformats/schemas/wordprocessingml/x2006/main/impl/CTTcImpl$1PList,

多次百度才发现还需要添加一个jar的dependency:


    org.apache.poi
    ooxml-schemas
    1.3

ooxml-schemas和poi-ooxml-schemas是两个不同的jar包。
最后需要使用的apeche的poi jar包如下:


	org.apache.poi
	poi
	3.15



	org.apache.poi
	poi-ooxml
	3.15



	org.apache.poi
	poi-ooxml-schemas
	3.15



	org.apache.poi
	ooxml-schemas
	1.3

至此,问题得以解决。

4.try……catch……finally的改进

相信你我一定写过很多次这种重复的“无意义”的代码:

BufferedOutputStream bos = null;
BufferedInputStream bis = null;
try {
    bos = new BufferedOutputStream(new FileOutputStream(storefile));
    bis = new BufferedInputStream(inputStream);
    int c;
    while((c= bis.read())!=-1){
        bos.write(c);
        bos.flush();
    }
} catch (IOException e) {
    e.printStackTrace();
}finally{
    bos.close();
    bis.close();
}

事实上,上面的代码还没有足够完善,即对异常的处理还不够。比如bos.close的方法调用也可能会出错,所以我们需要在finally字句里面做try{}catch{}判断。想想都要疯掉。
借助于IntelliJ IDEA智能IDE的提示:
这里写图片描述
敲下IDEA最强大的快捷键:Alt + Enter
变成这样:

try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(storefile));
     BufferedInputStream bis = new BufferedInputStream(inputStream)) {
    int c;
    while ((c = bis.read()) != -1) {
        bos.write(c);
        bos.flush();
    }
} catch (IOException e) {
    e.printStackTrace();
}

看起来清爽许多。

5. 报错java.sql.SQLNonTransientConnectionException: CLIENT_PLUGIN_AUTH is required

在连接本地Mysql时候的一个报错:

Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
2017-07-02 10:30:44.145 [main] ERROR sql.or.MysqlConnection - CLIENT_PLUGIN_AUTH is required
java.sql.SQLNonTransientConnectionException: CLIENT_PLUGIN_AUTH is required
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:526)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:513)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:505)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:479)
	at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:489)
	at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:72)
	at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:1606)
	at com.mysql.cj.jdbc.ConnectionImpl.(ConnectionImpl.java:633)
	at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:347)
	at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:219)
	at java.sql.DriverManager.getConnection(Unknown Source)
	at java.sql.DriverManager.getConnection(Unknown Source)
	at sql.or.MysqlConnection.setConnection(MysqlConnection.java:45)
	at sql.or.test.OpenReplicatorTest.main(OpenReplicatorTest.java:34)
Caused by: com.mysql.cj.core.exceptions.UnableToConnectException: CLIENT_PLUGIN_AUTH is required
...
context: AbstractTransport.Context[threadId=5,scramble=@hmiJr"L<'L**6oMt}

参考https://stackoverflow.com/questions/37348572/new-mysql-driver-causes-java-sql-sqlnontransientconnectionexception-client-plug
大意是使用的mysql-jdbc的版本不对,本地安装的Mysql是5.1.50,在pom文件里面引用的mysql-jdbc版本是最新的6.0.6,换成5.1.41,报错消失。

6. IDEA提示web.xml文件listener-class is not allowed here

在使用IDEA开发web项目时,有时候web.xml文件中会有很多标签被标为红色的字体,提示listener-class is not allowed here。比如:


contextConfigLocation
classpath: (不是系统默认WEB-INF时,需用classpath*:)

替换实例引用模板信息:


然后不再报错,但我不晓得为什么version="3.1"就出校验出错;
解答:Servlet3.0是J2EE6.0规范的一部分,跟随J2EE6.0一起发布,并且Tomcat7.0已经完全支持Servlet3.0;
平时,一般使用tomcat6.0,是不能够使用servelt3.0的,tomcat6.0还不能支持那些规范;
至于为什么不能使用listener-class,是因为在web-app_3_0.xsd结构定义文件中,根本就不提倡这些配置,因为Servlet3.0已经支持注解形式;

解决方法:(不推荐换版本号,推荐使用3.0以上版本,然后使用注解形式,当然不用注解而是使用web.xml等配置文件也是没有问题的。)
将web.xml头部内容


替换为


7. springboot集成swagger,添加单元测试之后报错

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'documentationPluginsBootstrapper' defined in URL [jar:file:/C:/Users/johnn/.m2/repository/io/springfox/springfox-spring-web/2.7.0/springfox-spring-web-2.7.0.jar!/springfox/documentation/spring/web/plugins/DocumentationPluginsBootstrapper.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webMvcRequestHandlerProvider' defined in URL [jar:file:/C:/Users/johnn/.m2/repository/io/springfox/springfox-spring-web/2.7.0/springfox-spring-web-2.7.0.jar!/springfox/documentation/spring/web/plugins/WebMvcRequestHandlerProvider.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.util.List' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:189)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1193)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1095)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:761)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:543)
	at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:139)
	at org.springframework.context.support.ClassPathXmlApplicationContext.(ClassPathXmlApplicationContext.java:83)
	at mybatis.service.EmployeeServiceTest.setup(EmployeeServiceTest.java:21)
	……
com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'webMvcRequestHandlerProvider' defined in URL [jar:file:/C:/Users/johnn/.m2/repository/io/springfox/springfox-spring-web/2.7.0/springfox-spring-web-2.7.0.jar!/springfox/documentation/spring/web/plugins/WebMvcRequestHandlerProvider.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.util.List' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
	at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:189)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1193)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1095)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:513)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:208)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.addCandidateEntry(DefaultListableBeanFactory.java:1316)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1282)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveMultipleBeans(DefaultListableBeanFactory.java:1180)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1096)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835)
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
	... 38 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.util.List' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1493)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1104)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)
	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835)
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
	... 55 more

很是莫名其妙啊,一开始看到bean的create failure,最怕这个spring bean相关的报错,一直都不是很清楚bean。Google之后,没有看明白的;然后换个关键字documentationPluginsBootstrapperGoogle,有说需要升级springfox,即swagger的版本的,尝试不管用!
答案在这里
1.把swagger的类注解@Configuration移除,是为方法一,不可取。swagger还是想要保留的。
2.

8. springboot集成JSP访问Controller页面报错404

关于springboot如何集成JSP,不多讲,网上的资源太多太多,唯一需要注意的就是文章的发表时间以及文章的质量,不是粘帖复制,而是事实上的运行起来。
在遍寻百度无果之后,无奈只能一字字去阅读google的信息。(心气浮躁)
主要看这里。值得注意的是,这个很早之前学习并编写的demo是可以跑以来的,后来在这个添加集成apidoc功能时,发现报错404!!!

    1. 切换spring-boot-starter-parent的版本的,试过,不管用;
    1. 类的注解@Controller换成@RestController,不行;
    1. 添加@ResponseBody,不行;
    1. maven dependency的使用的,不行;
    1. maven dependency的provided注释等,不行;
    1. 有说application.properties文件的spring.mvc.view.prefix字段的更新,某个版本之前是spring.view.prefix,试过还是不行;
  • 。。。
    1. 甚至有考虑到main/resources/webapp的文件结构的,但是还是不行;
      最后的方法是添加war,并且必须要先mvn install生成war包,然后执行命令java -jar springboot_jsp-0.0.1-SNAPSHOT.war

WTF!!!

9. 非法字符:“\ufeff”

IDEA导入 eclipse 项目,使用 tomcat 部署应用,在启动 tomcat 时,报错:
java web开发问题集锦_第2张图片
主要原因是: Eclipse可以自动把UTF-8+BOM文件转为普通的UTF-8文件。现在需要转换一下格式:
步骤:
点击 IDEA 右下角的 UTF-8,转换成 GBK,然后再换回 UTF-8,即可解决问题。

10. java.lang.UnsupportedClassVersionError版本不一致出错

代码运行抛错:
java.lang.UnsupportedClassVersionError: org/apache/lucene/store/Directory : Unsupported major.minor version 51.0
或者在使用 java 写出的工具时,比如 eclipse、dbeaver、FIST(第一家公司自己研发的一款集成测试工具),在打开工具时抛出类似这种UnsupportedClassVersionError:Unsupported major.minor version 51.0
错误非常显眼,百度即可找到问题根源在于 JDK 的版本;JDK不同版本,编译出的 class 文件不同。通过查看分析class文件前几个字节,可以找到对应的关系,参考wikipedia:

major version number of the class file format being used. minor version number of the class file format being used.
Java SE 11 = 55 (0x37 hex),
Java SE 10 = 54 (0x36 hex),[3]
Java SE 9 = 53 (0x35 hex),[4]
Java SE 8 = 52 (0x34 hex),
Java SE 7 = 51 (0x33 hex),
Java SE 6.0 = 50 (0x32 hex),
Java SE 5.0 = 49 (0x31 hex),
JDK 1.4 = 48 (0x30 hex),
JDK 1.3 = 47 (0x2F hex),
JDK 1.2 = 46 (0x2E hex),
JDK 1.1 = 45 (0x2D hex).

知道原因之后,解决方法就很简单,修改 JDK 版本即可。

11. NoClassDefFoundError和ClassNotFoundException异常

ClassNotFoundException通常是由jar包缺失造成的,导致编译通不过;而java.lang.NoClassDefFoundError是有可能编译通过的。

中级

SSH 框架报错 AnnotationConfigBeanDefinitionParser are only available on JDK 1.5 and high

一个很老旧的基于SSH框架的项目在启动过程中报错:
org.springframework.beans.factory.BeanDefinitionStoreException: Unexpected exception parsing XML document from class path resource [beans.xml]; nested exception is java.lang.IllegalStateException: Context namespace element 'annotation-config' and its parser class [org.springframework.context.annotation.AnnotationConfigBeanDefinitionParser] are only available on JDK 1.5 and higher Caused by: java.lang.IllegalStateException: Context namespace element 'annotation-config' and its parser class [org.springframework.context.annotation.AnnotationConfigBeanDefinitionParser] are only available on JDK 1.5 and higher
报错的详细堆栈stacktrace,应该基本上说清楚问题,是版本不匹配导致的。
具体来说,我本地开发项目用的是JDK 1.8,但是SSH 项目居然没有使用maven来管理项目依赖,只导入一个spring.jar。那怎么查看这个spring.jar 包的版本呢?两个方法:

  1. 下载安装jd翻译工具,我个人比较习惯使用jd-gui 这个版本。把jar 包拖进去,打开MANIFEST.MF文件,即可发现spring是2.5.6版本。
  2. 使用360压缩软件,但是不推荐,一点都不Geek。
    解决问题:
    源码是org.springframework.context.annotation.AnnotationConfigBeanDefinitionParser自动检测,jdk版本检测时需要jre1.5以上版本,但是JdkVersion只检查到1.7,jre1.8 时不匹配任何jdk,按如下方法处理,可以解决问题。
    1、在项目中创建一个package为org.springframework.core
    2、在该package下面新建JdkVersion.java,内容如下:
package org.springframework.core;

public abstract class JdkVersion {
    public static final int JAVA_13 = 0;
    public static final int JAVA_14 = 1;
    public static final int JAVA_15 = 2;
    public static final int JAVA_16 = 3;
    public static final int JAVA_17 = 4;
    //for jre 1.8
    public static final int JAVA_18 = 5;
    private static final String javaVersion = System
            .getProperty("java.version");
    private static final int majorJavaVersion;
    public static String getJavaVersion() {
        return javaVersion;
    }
    public static int getMajorJavaVersion() {
        return majorJavaVersion;
    }
    public static boolean isAtLeastJava14() {
        return true;
    }
    public static boolean isAtLeastJava15() {
        return getMajorJavaVersion() >= 2;
    }
    public static boolean isAtLeastJava16() {
        return getMajorJavaVersion() >= 3;
    }
    static {
        //for jre 1.8
        if (javaVersion.indexOf("1.8.") != -1) {
            majorJavaVersion = 5;
        }else if (javaVersion.indexOf("1.7.") != -1) {
            majorJavaVersion = 4;
        } else if (javaVersion.indexOf("1.6.") != -1) {
            majorJavaVersion = 3;
        } else if (javaVersion.indexOf("1.5.") != -1) {
            majorJavaVersion = 2;
        } else {
            majorJavaVersion = 1;
        }
    }
}

重启项目即可。

你可能感兴趣的:(java)