macOS Catalina(10.15.4)/IntelliJ IDEA 2018.3/Tomcat 9.0.33/Maven项目调试报错"Caused by: java.util.zip.ZipException: zip file is empty"

macOS Catalina(10.15.4)/IntelliJ IDEA 2018.3/Tomcat 9.0.33/Maven项目调试时报错,这个项目以前是可以正常调试的,一段时间之后,就不能正常调试之下了

继续阅读macOS Catalina(10.15.4)/IntelliJ IDEA 2018.3/Tomcat 9.0.33/Maven项目调试报错"Caused by: java.util.zip.ZipException: zip file is empty"

Ubuntu 16.04下创建IntelliJ IDEA图标快捷方式

一般在安装目录下面或者桌面上创建文件,命名为:idea.desktop
使用vim编辑该文件

内容如下:

接着给予这个文件执行权限

以后双击这个图标,就可以直接启动IntelliJ IDEA了。

IntelliJ IDEA 2016.2使用Spring 4.3.1.RELEASE,sockjs-1.1.1,stomp-1.2搭建基于Tomcat-7.0.68的WebSocket应用

接着上文IntelliJ IDEA 2016.2使用Spring 4.3.1.RELEASE搭建基于Tomcat-7.0.68的WebSocket应用

上文的最后我们说到,WebSocket是需要定时心跳的,否则会在一段时间后自动断开连接,而更重要的是,不是所有的浏览器都支持WebSocket,早期的IE 10之前的版本就是不支持的,而这一部分的设备其实是不算少的,而sockjs的出现,恰恰好来解决了这个问题。对于不支持WebSocket的浏览器,sockjs使用了多种方式来兼容这种情况,包括使用长轮询等方式,Spring更是内建支持这种方式。

下面我们看如何在上篇文章的基础上,增加对于sockjs的支持。

首先是STOMP的文档官网地址 http://stomp.github.io/
代码的地址为https://github.com/jmesnil/stomp-websocket,项目下面的lib/stomp.js就是我们想要的文件。也可以本站下载stomp.js.zip

接下来sockjs的代码地址https://github.com/sockjs/sockjs-client,项目下面的dist/sockjs-1.1.1.js就是我们想要的文件。也可以本站下载sockjs-1.1.1.js.zip

接下来我们把下载到的文件放到我们工程目录下面的web->resources->javascript目录下面,如下图:

stomp-websockjs-resources

接下来,添加我们需要的com.fasterxml.jackson.core:jackson-annotations:2.8.1,com.fasterxml.jackson.core:jackson-core:2.8.1,com.fasterxml.jackson.core:jackson-databind:2.8.1这三个jar包,增加的方式参照上一篇中对于javax.servlet:javax.servlet-api:3.1.0的操作方法。与上一篇的操作不同的是,这次添加的三个jar包,都要放到编译完成后的War包中。最后的结果如下图:
ToolsJacksonMaven

ToolsJacksonMavenWar

下面,我们开始进行代码的操作,我们在上篇文章中的src->Tools->WebSocket中新增两个源代码文件SockJsController.java,WebJsSocketConfig.java.如下图:

NewJavaSourcesForSockjs

其中的代码如下:
SockJsController.java

WebJsSocketConfig.java

然后修改WebSocket.jsp

最后,我们修改web->WEB-INF->web.xml,在其中增加

修改后的最终结果如下:

参考链接


 

使用junit测试IntelliJ IDEA 2016.2建立的maven项目

maven project项目中引入junit插件并不困难,只需要在pom.xml中配置好依赖包即可(IDE环境下,依赖项会自动生成)。另外,test类文件需要按照/src/main/java/的文件结构(main改为test)。
pom.xml

如下图:

mavenjunitpath

IntelliJ IDEA 2016.2使用Spring 4.3.1.RELEASE搭建基于Tomcat-7.0.68的WebSocket应用

先参照 IntelliJ IDEA 2016.1建立Strut2工程并使用Tomcat调试建立新的工程,一步一步操作,包括最后引用Spring框架部分。

经过上面的操作,Spring-WebSocket的包应该已经被默认引入了,如下图所示:

spring-websocket-release-lib

这就意味着我们已经不需要再进行过多的额外配置了。

接下来,我们在src->Tools下面新建一个WebSocket的目录,里面创建三个Java文件。如下图:
WebSocketJavaSourceList

每个文件中的代码如下:
SystemWebSocketHandler.java

WebSocketConfig.java

WebSocketHandshakeInterceptor.java

由于我们使用了Struts2导致我们的网络请求优先被Struts2的拦截器拦截,而Struts2又处理不了websocket请求,结果直接返回了404错误。因此我们需要替换掉默认的在web.xml中定义的Struts2的拦截器,要求Struts2不处理websocket请求。
我们在src->Tools下面新建一个Filter的目录,下面创建一个名为StrutsPrepareAndExecuteFilterEx.java的源代码文件,如下图:

StrutsPrepareAndExecuteFilterEx
具体的代码如下:
StrutsPrepareAndExecuteFilterEx.java

这时候的代码是无法编译通过的,原因是依赖的javaxJar包不存在。此时,我们需要手工引入javax.servlet:javax.servlet-api:3.1.0这个Jar包。如下图:

ToolWebSocketProjectStructure

ToolWebSocketProjectStructureAddJars

ToolWebSocketProjectStructureAddJarsFromMaven

ToolWebSocketProjectStructureAddJarsFromMavenJavaxServerletApi3.1.0

ToolWebSocketProjectStructureAddJarsFromMavenJavaxServerletApi3.1.0Add

ToolWebSocketProjectStructureAddJarsFromMavenJavaxServerletApi3.1.0AddApply

还要注意,刚刚添加进入的javax.servlet:javax.servlet-api:3.1.0这个Jar包,我们只在编译期间使用,在运行时候,使用Tomcat自己实现的那个同名Jar包。也就是这个包是个Provided,而不是Compile关系,具体如下图:

ToolWebSocketProjectStructureKeepOutsideWar

接下来,修改web.xml指定Struts2的拦截器为我们定义的拦截器

修改为

经过上面的修改后,依旧是没办法进行网络访问的,原因是web.xml中的Spring拦截器并没有拦截WebSocket的数据请求。

修改为

注意增加的

下一步,配置Spring的配置文件web->WEB-INF->dispatcher-servlet.xml增加配置信息类的扫描目录包含我们刚刚创建的src->Tools->WebSocket的目录(缺少这一步会导致我们通过注解实现的配置信息类没有被自动加载,导致无法访问),修改后的内容如下:

最后,调用的页面的代码
WebSocket.jsp

最后的客户端显示效果如下图所示:
WebSocketJsp

注意:如此创建的WebSocket是会在两三分钟后主动断开连接的,原因在于WebSocket需要周期性的发送心跳报文来维持连接。后续我们会尝试使用sockjs来实现自动发送心跳的逻辑。

具体的sockjs的接入方法,参考IntelliJ IDEA 2016.2使用Spring 4.3.1.RELEASE,sockjs-1.1.1,stomp-1.2搭建基于Tomcat-7.0.68的WebSocket应用

IntelliJ IDEA2016.2使用Gradle创建Java Web应用

1.如下图,第一步很简单的,File->New->Project
20160502164417038

2.如下图,完成第一步后,会弹出这样一个窗体,然后在左边栏目找到Gradle,然后在右边勾选JavaWeb两个选项,最后点击Next
20160502164806993
3.如下图,到了输入GroupIdAcrtifactId窗口了,对于这两个名字的解释

GroupID是项目组织唯一的标识符,实际对应JAVA的包的结构,是main目录里java的目录结构。
ArtifactID就是项目的唯一的标识符,实际对应项目的名称,就是项目根目录的名称。
一般来说,包的命名习惯是域名的反过来,加个公司或者个人的名称吧,个人习惯。www.demo.com -> com.richard.demo; 那么都知道,test是项目名称,也是在最后面的,所有项目组的唯一标识符(groupId):com.richard, 项目的唯一标识符(ArtifactId)demo.

然后点击Next
20160502165336980

4. 如下图,这个页面,刚进来默认选择的是Use default gradle wrapper(recommended), 我不选择这个是因为我本地有装Gradle,所有不需要是用它默认的,如果选择它,那么创建项目之后,它就会去自动下载Gradle,然后配置好,下载过 程一般都很慢,至少我在我电脑上很慢。所有我选择的是Use local gradle distribution,。然后上面还有一个勾选,就是自动创建空的根目录文件夹,如果不选择,创建完的项目会没有Java文件夹,所以勾选,让它自动创建吧,继续点击Next
20160502172330113
5. 如下图,它默认的就是ArtifactId的名字,项目的唯一标识嘛,然后module name,如果不清楚应该填什么,可以按照默认的无所谓,点击Finish,创建就这样完成了。
20160502172559648
6.创建完成之后,如果你之前没有配置Tomcat的话,是没办法运行的,所以也需要配置Tomcat,如下图, 左侧是成功创建的项目文件目录,如果之前没有勾选Create directories for empty content roots automatically, 那么就不会生成javaresource这个两个孔文件夹。这不的重点是点击Edit configuration
20160502173439340
6. 弹出如下图配置框,点击左上角加号,往下滚动找到Tomcat Server->Local,点击Local.
20160502174005936
7. 如下图,弹出配置框,默认是配置Server属性,输入这个配置的名字,name,可以取任意的名字,点击Configure选择本地Tomcat的路径,都配置好了直接点击OK就可以运行了。
20160502174445592
8.如下图,然后选择Server旁边的Deployment, 页面之后,点击加号,在弹出的页面选择名字更长的那个,也就是后面有(exploded)的那条,点击OK
20160502175547163

9.如下图,在右侧输入Application context的名字,这个对应就是等会儿运行时,默认路径(http://localhost:8080/demo/)中的demo, 所以如果你不配置这项,它的默认路径将会是(http://localhost:8080/)这样的。最后点击Apply, 再点击OK.
20160502180004992
10.倒数第二步了,如下图,打开index.jsp页面,长方形圈出来的是系统默认生成的,不用管,可以删掉,然后圆圈的是我自己写的。我只是为了让你知道,jsp页面长啥样子的,免得你看到它,以为是生成错文件了,点击有上角的运行按钮。
20160502180443932

11.最后一步,见证如下成果。
20160502180826574

参考链接


IntelliJ IDEA2016.1 + maven 创建java web 项目

IntelliJ IDEA 2016.1.2建立Struts2+Spring+Hibernate+H2数据库项目

前言


参照IntelliJ IDEA 2016.1建立Strut2工程并使用Tomcat调试建立了项目后,然后按照IntelliJ IDEA 2016.1.1的Struts2项目中引入Junit4.12单元测试,引入Junit到项目之后,开始引入Hibernate并且使用H2作为数据存储,完成一个比较完整的示例服务器。

简单介绍一下H2嵌入式数据库
H2是一个短小精干的嵌入式数据库引擎,主要的特性包括:

  1. 免费、开源、快速;
  2. 嵌入式的数据库服务器,支持集群;
  3. 提供JDBC,ODBC访问接口,提供基于浏览器的控制台管理程序;
  4. Java编写,可使用GCJIKVM.NET编译;
  5. 短小精干的软件,1M左右。

几个嵌入式数据库的对比:
a9d3fd1f4134970ad4b3ee3a93cad1c8a6865de7

实战


1.引入H2数据库

点击工程的"Project Structure"图标,如下图所示:

configure_project_structure

在弹出的界面中根据顺序,依次选择,选择从Maven服务器下载

new_project_library_from_maven

在弹出的界面中根据顺序依次操作,点击搜索图标之后,要等待比较长的一段时间,才能看到下面的OK按钮可以点击。目前H2最新的版本是1.4.191,因此输入"com.h2database:h2:1.4.191"。详细操作如下图:

DownloadLibraryFromMavenRepositoryH2

点击OK按钮,关闭窗口后,稍等,会发现出现一个Problems的提示,点击这个提示列表,如下图所示:

ChooseModules

ProjectStructureH2ProblemsFix

完成后点击OK按钮关闭界面。

2.引入Hibernate框架

切换工程的视图到"Project"模式下

ModelSwitchToProject

项目上面右击鼠标,选择"Add Framework Support ..."菜单,如下图:

AddFrameworkSupportMenuHibernate

在弹出的界面中选择"Hibernate",如下图所示

AddFrameworkSupportMenuHibernateDownload

点击后,出现下载进度,等待进度完成,如下图:

AddFrameworkSupportMenuHibernateDownloadWaiting

下载完成后,再次点击工程的"Project Structure"图标,如下图:

ProjectStructureForHibernate

同样在出现的界面中修复提示的Problems,如下图:

ProjectStructureForHibernateFix

增加"Hibernate"配置文件,点击工程的"Project Structure"图标,如下图:

ProjectStructureForHibernate

增加"Hibernate"配置文件,如下图:ProjectStructureForHibernateAddConfigureFile

选择文件的路径,此处我们使用默认路径,点击OK即可。

ProjectStructureForHibernateAddConfigureFilePathSelect

此时我们点击工程目录,会发现,已经新增了一个名字为hibernate.cfg.xml的配置文件,如下图:

HibernateConfigureFile

3.配置Hibernate与H2数据库通信

按下面所示的修改hibernate.cfg.xml文件,如下:

此时会提示我们,找不到Simulator.Hibernate.Model.Visitor这个类,因此我们创建这个类,如下图所示:

HibernateVisitorModel

三个文件的源代码如下:

Visitor.Java中的代码如下:

代码解释一下,@Entry,@Table的注解来告知Hibernate,这个是个数据库的表配置类,其中的每个成员变量对应数据库表的字段。
如下的注解

表示id为整个表的自增主键。

VisitorDao.Java中的代码如下,这个文件提供了访问数据的接口定义:

VisitorDaoImpl.Java中的代码如下,这个文件对VisitorDao中定义的接口进行了实现:

这部分的代码需要着重解释一下

这个语句,注意,这个语句中的"from Visitor"Visitor.Java中定义的类的名称,由Hibernate内部进行变量,表之间的对应。

如上操作之后,就可以在任意的Action中通过调用VisitorDaoImpl实现对于数据库的写入,查询了。

参考链接


Frequently Asked Questions

IntelliJ IDEA 2016.1.1的Struts2项目中引入Junit4.12单元测试

使用IntelliJ IDEA 2016.1建立Strut2工程并使用Tomcat调试建立项目后,想引入Junit进行TDD的开发,总结如下:

1.点击工程右上方的"Project Structure"图标

select_structure

2.在弹出的界面中的左侧选择"Libraries",然后如下图所示,按照编号的顺序,依次点击,输入数据。注意,如果此时"OK"按键是灰色的,那么需要点击右侧的放大镜图标,让IntelliJ IDEA去服务器上搜索一下,等他搜索完成了,那么下面的"OK"按键自然是可以点击的了。

maven_add_junit4

3.点击"OK"按键

choose_modules

4.此时发现提示存在一个"Problem",点击然后按照下图展示修复这个问题。

click_success_problems

fix_junit4_problem

fix_junit4_problem_select_menu

点击"OK",关闭这个页面。

5.在工程的"src"目录下面新建名为"test"的目录,他的子目录与源代码的目录相同即可,IntelliJ IDEA会自动把这个目录当作单元测试的目录,如下图所示:

UnitTestForder

测试代码如下:

然后右击测试文件,会出现如下图的菜单选项DebugTestFile

有时候他不会出现这些菜单,那说明还没有测试函数,添加一个空的@Test测试函数就可以了,比如下面的样子:

也可以使用JunitGenerator V2.0这个插件来自动生成单元测试代码。
打开IntelliJ IDEA工具,Alt+Ctrl+S,弹出窗口如下:IDEASettings

在文本框中输入Plugins进行插件搜索设置。

IdeaPluginsInstall

点击按钮,从插件资源库中安装新的插件。

从插件资源库中搜索JunitGenerator V2.0版本,点击右侧的Install按钮.

JunitGeneratorV2Install

安装完成后,点击"Restart IntelliJ IDEA"重启IntelliJ IDEA。

JunitGeneratorV2InstallRestartIdea

现在可通过此工具自动完成test类的生成了,在需要进行单元测试的类中Alt+Insert

AutoGeneratorJunit

生成的自动测试代码如下图所示

AutoJunitSouces

IntelliJ IDEA 2016.1建立Strut2工程并使用Tomcat调试

IntelliJ IDEA 2016.1建立Strut2工程的步骤如下:

1.从菜单中选择新建工程:

NewProjectMenu

2.在弹出的窗口中,左侧的列表中,选择"Java",在右侧的"Project SDK"中指明需要的Java SDK的版本,目前要求是1.8版本的,在下面的"Additional Libraries and Frameworks"中找到"Struts 2",并选中,同时选中"Web Application"。

NewStucts2Project

3.点击下面的"Next"按钮。

JavaEnterpriseStruct2ProjectName

4.等待IntelliJ IDEA下载完成必须的插件。点击左侧的"Project"边栏,之后可以到如下界面.

JavaEnterpriseStruct2ProjectView

点击右侧的"Project Stucture"按钮,如下图:

ProjectStuctureButton

修复存在的问题:

ProjectStuctureWindow2

点击后出现的界面如下:

ProjectStuctureWindowStruts2Lib

在弹出的菜单中,选择"Put into /Web-INF/lib"。

ProjectStuctureWindowStruts2LibMenu

配置完成后的界面如下:

ProjectStuctureWindowStruts2LibComplete

点击"OK",关闭窗口。

5.编辑配置信息"Edit Configurations"

EditConfigurations

6.在弹出的界面中点开右侧的"+"符号,也可以点击左侧顶部的"+"号。

RunDebugConfigurations

7.在弹出的界面中,一直下拉,找到"Tomcat Server",点击展开,选择"Local"

RunDebugConfigurationsAddSettings

RunDebugConfigurationsAddSettings

8.下载并安装Tomcat 9

Windows下面,建议安装 "32-bit/64-bit Windows Service Installer"

Tomcat9DownloadPage

9.安装最新的 Java SE Development Kit
目前最新的版本是8u73。保证电脑上面是最新的,如果使用JDK 7的话,会由于Tomcat的版本号太高导致在调试的时候报告如下错误:

这个错误的原因是由于JDK 1.7是默认没有包含JMS服务的,导致Idea通过JMSTomcat通信的时候失败。

10.设置Tomcat Server

RunDebugConfigurationsTomcatServerLocalSettingsFirst

RunDebugConfigurationsTomcatServerLocalSettingsSecond

RunDebugConfigurationsTomcatServerLocalSettings

配置完成后的界面显示如下:

RunDebugConfigurationsTomcatServerLocalSettingsAfterConfigure

此时底部提示"Warning No artificts configured",点击底部的"Fix"按钮。

RunDebugConfigurationsTomcatServerLocalSettingsFixButtonClick

出现的窗口中自动帮我们加入了"Tools:war exploded"项目,点击下面的"Apply"按钮后,点击"OK"关闭设置页面。

RunDebugConfigurationsFix2

11.调试,点击主界面上面的调试图标,即可进入调试,此时会在默认的浏览器上打开网页。

RunDebugConfigurationsTomcatServerLocalSettingsDebug

最后,浏览器上出现如下画面,说明设置成功。

ideaStucts2Complete

12.创建一个简单的Stucts2MVC例子----TimeConvert

(1)先创建一个Model类来存放数据

首先,在src目录上鼠标右击,选择"New"-> "Java Class"并在对话框中输入名字"Tools.Model.TimeConvertStore",点击"OK"。

NewJavaMenu

NewJavaModel

里面的代码如下:

这个Model类的public setget方法允许访问private convertTime字符串属性,Struts 2框架需要将这个对象按照JavaBean方式暴露给View(TimeConvert.jsp)

(2)创建View页面来显示Model类里存储的convertTime .

web目录上鼠标右击,选择"New"-> "File"并在对话框中输入名字"TimeConvert.jsp",点击"OK"新建一个TimeConvert.jspjsp页面.

NewJSPMenu

NewJSPWindow

代码如下:

页面中的taglib告诉Servlet容器这个页面将使用Struts 2tags并且将它们用s来表示。
s:propertytag标签返回调用TimeConvertAction controller classgetTimeConvertStore方法后的值。这个方法返回一个TimeConvertStore对象。在TimeConvertStore加上了.convertTime后,就可以告诉Struts 2框架将调用TimeConvertStoregetConvertTime方法。TimeConvertStoregetConvertTime方法返回一个字符串,然后这个字符串将被s:property标签显示。

(3)创建一个ActionTimeConvertAction.java作为Controller.
src目录上鼠标右击,选择"New"->"Java Class"并在对话框中输入名字"Tools.Controller.TimeConvertAction",点击"OK".

NewJavaMenu

NewJSPActionWindow

代码如下:

(4)增加struts配置到struts.xml文件中
建立映射关系,将TimeConvertAction类(Controller)和TimeConvert.jsp(View)映射在一起。映射后,Struts 2框架就能够知道哪个类将响应用户的actionthe URL),这个类的哪个方法将被调用,哪个View能够得到这个方法的返回String结果。

(5)在index.jsp中增加链接

首先在jsp页面顶部增加taglib说明

然后在body标签后增加p标签

修改后的代码如下:

点击调试后,运行效果如下图:

TimeConvertIndex

点击超链接后显示如下:

TimeConvertAction

13.增加多语言支持i18n

需要注意的是,对于index.jsp中读取全局配置文件,需要先增加Spring框架,否则是无法通过在struts.xml中增加

来实现的。如下图所示:

struts.custom.i18n.resources

在跟"TimeConvertAction.java"相同的目录下面建立英文语言文件TimeConvertAction_en.properties,中文语言文件TimeConvertAction_zh.properties,注意,中文只能是Unicode编码的格式,否则会出现乱码。格式类似\u65f6\u95f4\u8f6c\u6362这样的格式。
Struts2i18n
其中TimeConvertAction_en.properties中的内容如下:

TimeConvertAction_cn.properties中的内容如下:

然后修改TimeConvert.jsp,在Title中引用我们定义的语言。修改

为:

修改后的TimeConvert.jsp文件如下:

点击调试后,打开的页面中,会看到网页的Title变成了中文的"时间转换"。

14.Strut2增加对Json的支持

默认情况下Struts2不支持直接返回JSON,比较方便的方式是使用struts2-json-plugin来支持。

(1)增加spring框架,由于struts2-json-plugin需要调用spring框架,因此需要增加spring框架。右击工程,选择"Add Framework Support..."。

AddFrameworkSupport

在弹出的窗口中,选择"Spring","Spring MVC"两项,同时在点击"Spring"的时候,勾选"Create emtpy spring-config.xml"。

SpringSelectOptions

然后点击"OK",等待需要的Jar包下载完成。成功下载完成后,可以在lib目录下看到非常多的Jar文件被添加进来了。在web目录下的WEB-INF目录下多出来了applicationContext.xml,dispatcher-servlet.xml这两个文件。SpringFrameworkAddComplete

SpringFrameworkAddCompleteWebInf

完成后点击界面上侧的"Project Structure"图标,解决提示的Jar包导出问题。

SpringFrameworkProjectStructure

SpringFrameworkFix

都选择第一项"Add 'xxxxxxxxxxx' to the artifact".

SpringFrameworkFixMenu

(2)确认项目使用的Struts2的版本。点击界面上侧的"Project Structure"图标

SpringFrameworkProjectStructure

StrutsVersion2-2.3.20.1

从上图可以看到我们的Struts2的版本是2.3.20.1

(3)手工去下载struts2-json-plugin插件,选择与我们的Struts2的版本相同的版本的插件。之所以需要手工下载而不是要求IntelliJ IDEA Maven中自动下载原因在于,由于我们建立项目的时候没有使用Maven,因此我们项目Lib目录下的Struts2Jar包是没有带版本号的。而如果要求Maven自动下载的话,会由于找不到带版本号的Struts2Jar包,而自动引入一堆的带版本号的Struts2Jar包。导致Struts2Jar包出现两份,一份是有版本号的,一份是我们现在的样子。导致无法编译通过,因此还是手工引入即可。

由于我们的Struts2的版本是2.3.20.1,因此,我们下载2.3.20.1版本的struts2-json-plugin.Struts2JSONPlugin

下载完成后放到项目的lib目录下,然后右击struts2-json-plugin-2.3.20.1.jar,选择"Add As Library".

AddasLibrary

AddasLibraryWindow

点击OK后关闭。

继续点击界面右上侧的"Project Structure"图标

SpringFrameworkProjectStructure

AddStruts2-json-plugin-2.3.20.1totheartifact

修改src目录下的struts.xml。调整部分如下图所示。

ActionJsonResp

action的返回类型为json时的可配置参数详解:

15.参考链接