Category Archives: Java

Java导出含有多个工作表(sheet)的excel文件

最近碰到一个需求,后台有个台账导出的功能,以前所有数据都是导出到excel的一个sheet中集中显示的,这次的需求是要根据列表中的签单机构名称来分sheet导出,即签单机构相同的台账在同一个sheet中显示。把完成这个需求的核心代码去掉业务逻辑后就变成了下面这样的代码。需要说明的一点是,像这样的需求不可以真的是根据“名称”来分sheet导出的,你应该根据id这种不会重复的字段来作为分类依据,“名称”理论上是存在同名的可能性的。Talk is cheap, show you the code right now:

 

Spring Web MVC系列

接下来会翻译一下spring官方的一些文档,此次为Spring Web MVC系列的内容。Spring Web MVC是建立在Servlet API之上的web框架,Spring框架很早就包含了Spring Web MVC。“Spring Web MVC”这个正式名称来源于其源模块“spring-webmvc”,但是它被大家所熟悉的叫法是“Spring MVC”。

目录:

  1. DispatcherServlet
  2. Filters(过滤器)
  3. Annotated Controllers(注释的控制器)
  4. URI链接
  5. Exception Handling(对意外的处理)
  6. Async Requests(异步请求)
  7. CORS(跨域资源分享)
  8. Web Security(网络安全)
  9. HTTP Caching(HTTP缓存)
  10. MVC Config(MVC配置)
  11. View Techonologies(视图技术)
  12. HTTP/2支持

参考资料:

  • https://docs.spring.io/spring/docs/current/spring-framework-reference/web.html#mvc

MAC Pro下使用IntelliJ IDEA创建maven spring mvc项目

为了接下来能比较容易上手后端项目,结合目前所做项目的后端开发们使用的是spring mvc而非spring boot。决定先把基本的java开发环境配置好,先跑一个本地服务能看到页面再说。我是按着http://www.cnblogs.com/Sinte-Beuve/p/5730553.html这篇文章的教程来的,所以内容大体一致,再写一遍主要是为了加深自己的印象。

最最基础的,你需要先装好java、maven和tomcat(tomcat选装,如果用jetty等其他web容器,就用不到tomcat了,不过tomcat还是用的最广泛的,出于学习的目的,还是装下比较好),这部分内容之前有写过文章《Macbook Pro安装Maven 3 》。然后开始下面的流程:

一、预备信息

因为软件什么的更新频率还是蛮快的,我先亮一下我用的软件相关信息,咱们的工具越像的话,这篇文章的参考价值会越高:

关于IDEA:

其他信息:

二、用maven创建webapp骨架

首先,菜单栏:File=>New=>Project…,然后按下面这样操作:

  1. 选择Maven;
  2. 勾选Create from archetype;
  3. 选择org.apache.maven.archetypes:maven-archetype-webapp;
  4. 点Next。

然后填写GroupId、ArtifactId,版本号默认1.0-SNAPSHOT就行:

再一个然后,选择maven相关设置(/Users/yakima/.m2/settings.xml这个文件我本地还没有,截图里这个是默认的路径,我用maven中央仓库速度就挺好的了,这种demo项目也不涉及私有架包,所以感觉目前也没必要写一个setting.xml文件,都用默认的就好了),这里选一下Maven home directory里的东西就可以了。

然后填写项目名和项目地址,最后点击Finish按钮:

三、完善项目目录结构

下面是最终的目录结构(如果按上面的步骤走到这里,你的目录结构肯定跟这里是有差异的,先放出来是为了让大家有个大概的轮廓在脑子里,而且下面单独说文件的时候也不至于出现不知道我说的文件该放在哪个位置的问题)。

src/main/java:开发目录(程序源码,Sources Root)

src/main/java目录本来是没有的,是我们手动添加的目录,请注意java目录的图标是有特别的颜色的(截图里是蓝色),这是我将其标记为Sources Root目录的结果,只有将文件夹标记为Sources Root后,才能通过IDEA右键该文件夹后通过菜单直接在其下创建package和class。要将一个目录标记为Sources Root,只需要鼠标右键该文件夹=>Mark Directory as=>Sources Root。将src/main/java目录标记为Sources Root后在其下创建com.example.controller包,并在controller同级位置创建dao、pojo和service三个微笑(就叫微笑吧,我不知道这个该叫啥,下面一个文件都没有,不知道算不算包-_-)。

src/main/resources:资源目录(Resources Root)

资源目录下的文件是会被编译到输出目录下的。跟上面标记src/main/java目录的方法类似,若src/main/resources目录尚未被标记为Resources Root则需要手动将其标记为Resources Root。不过好像这个文件夹默认就已经被标注为Resources Root了。

src/test:单元测试目录

下面的开发目录为src/test/java,资源目录为src/test/resources。

四、配置Maven的pom.xml

完整的配置文件贴于此:

更新完pom.xml后,IDEA应该会自动下载相应的jar包,如果没有自动下载,请手动右键pom.xml文件,选择Maven=>Reimport来手下载相应的jar包。

五、配置web.xml

maven项目默认生成的2.3版。覆盖为以下内容:

其中DispatcherServlet是分发http请求用的。

六、配置contextConfigLocation

在刚才的web.xml文件中,可以看到contextConfigLocation这个param name,其值为classpath:spring/spring-mvc.xml。我们在src/main/resources下新建一个spring目录,并在其下新建一个spring-mvc.xml文件。spring-mvc.xml文件的内容如下:

七、配置log4j.properties

日志文件是debug中一个不可缺少的工具,因此添加log4j日志包。在src/main/resources下新建log4j.properties文件,该配置文件内容如下:

八、controller和view的编写

在src/main/java/com.example.controller下新建HomeController文件,内容如下:

在src/main/webapp/WEB-INF/views下新建index.jsp文件,内容如下:

至此,基本的代码编写工作就完成了。

九、servlet容器的配置和运行

servlet容器有两种配置方式:

  1. 配置本地的tomcat服务器;
  2. 配置maven插件;

下面分别介绍(要跑服务的话,只要配一个就可以了,当然你配两个选一个来跑也是可以的)。

方法一:配置本地的tomcat服务器

菜单栏=>Run=>Edit Configurations…,然后按下图操作:

请注意,上图3处的Update classes and resources选项一开始是没有的,一开始只有一个Restart Server选项。需要点击Server选项卡旁边的Deployment选项卡,点击+号=>Artifact…来添加war exploded,然后再切换回Server选项卡,这时候就有Update classes and resources这个选项可以选来。

方法二:配置maven插件

maven插件有tomcat和jetty等,两者都是servlet容器。jetty插件的配置我们已经在pom.xml文件中完成了。现在在IDEA中配置jetty。

菜单栏=>Run=>Edit Configurations…,然后按下图操作:

十、运行程序

选择jetty或tomcat然后点击Run按钮即可,示例如图(选择了tomcat):

Macbook Pro安装Maven 3

可能是xcode还是什么鬼,反正我本子里已经装好了java:

不过JAVA_HOME环境变量尚未设置,需要设置。在这之前,我从maven官方网站下载了一个apache-maven-3.5.0-bin.zip压缩包并将其解压到了/usr/local/apache-maven-3.5.0目录上。

准备工作做好后,打开~/.bash_profile文件(若没有则新建之):

保存并退出文件(esc两次后输入:wq!并回车)。执行下面的命令,mvn命令马上就可以用了,

然后我发现一个坑,就是每次我重启终端或者重启电脑后mvn变量又不能用了,这显然是不行的。我用的是zsh,参考网上的资料,打开~/.zshrc文件并在末尾添加上面那句话并重启终端后mvn命令就可以用了(每次启动终端前,会自动运行一次~/.zshrc里的命令,不需要手动去source了)。

修改完以上内容后可以查看对应的变量名的值来确认下:

这时候maven已经装好了:

 

400 bad request: Required request part ‘file’ is not present

最近碰到一个更新用户个人头像的需求,允许用户选择APP内置的几张示例图片作为头像,也允许用户拍照上传个人头像(不论是选择示例图片作为个人头像还是用户自己拍照作为个人头像,均会在文件字段之外再传其他参数,比如图片名,不只是一个文件字段)。计划中的接口是一个,拍照上传头像是由iOS和android开发在壳的层面上负责完成的,选择示例图片作为用户个人头像是在React Native层面予以实现的。因为是同一个接口,出于统一的目的,请求头中的Content-Type都使用“multipart/form-data; boundary=分隔符“这样的值(比如:Content-Type: multipart/form-data; boundary=”bac9aebd-d9ff-40ef-bcf3-4fffdd1b2c00″)。壳发的上传图片请求能正常地被服务器端处理,但是RN发的文件为空的请求就没法正常被处理,只知道报错信息为:400 bad request: Required request part ‘file’ is not present,跟后端交涉后被告知以前没有处理过不传文件的情况,还说他们写的是中间件,请求进不了断点的话他们也处理不了。。。

然而Spring、Tomcat这些东西毕竟不是才出来的新生事物,肯定不会有这么致命的问题在的。。。

结合看完即忘的一点java印象,在网上查了下资料,最后觉得可定是通过注解RequestParam来取参时出了问题(当然,因为没看过后端代码,全是猜的)。根据Spring官方文档https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestParam.html猜测通过@RequestParam(value = “file”, required = false)这种方式来取参的话,file字段就是可选的了。

第二天一上班就来找后端同事让他试试,后面不知道他们是不是通过这种方式解决这个问题的,反正最后请求可以进后端的断点了。That’s enough.