需求:通过dos的方式运行可以在IDE(这里使用的是IntelliJ IDEA)中正常运行的java程序。
程序如下:MyHttpClient.java(文件名)
//package com.yf.service;在IDE下就要加上这个,不然会提示丢失包的错误 在dos下运行就需
//要注释这个 为什么要注释这里,我下面有说明 当然在生产环境下是不允许注释的 如何带包//运行,我下面也给出了方法说明
importorg.apache.http.HttpEntity;
importorg.apache.http.HttpResponse;
importorg.apache.http.NameValuePair;
importorg.apache.http.client.HttpClient;
importorg.apache.http.client.entity.UrlEncodedFormEntity;
importorg.apache.http.client.methods.HttpPost;
importorg.apache.http.impl.client.DefaultHttpClient;
importorg.apache.http.message.BasicNameValuePair;
importorg.apache.http.util.EntityUtils;
importorg.slf4j.Logger;
importorg.slf4j.LoggerFactory;
importjavax.swing.text.html.parser.Entity;
importjava.io.IOException;
importjava.io.UnsupportedEncodingException;
importjava.util.ArrayList;
importjava.util.List;
public classMyHttpClient {
/*通过slf4j的LoggerFactory工厂方法获取日志对象*/
private Logger logger= LoggerFactory.getLogger(MyHttpClient.class);
public static void main(String[] args) {
//创建httpClient对象
HttpClient httpClient =newDefaultHttpClient();
//使用post请求方式
HttpPost httpPost =newHttpPost("http://131.129.212.164:8007/statisticsService/count!getUserCareerDate.do");
//创建parms集合 添加参数
List parms =newArrayList();
parms.add(newBasicNameValuePair("accessToken","18682009779"));
UrlEncodedFormEntity entity =null;
try{
//将Parma封装成使用utf8编码格式的实体
entity =newUrlEncodedFormEntity(parms,"utf-8");
}catch(UnsupportedEncodingException e) {
e.printStackTrace();
}
//Post提交格式独有的设置参数的方式
httpPost.setEntity(entity);
try{
//获取httpResponse
HttpResponse httpResponse = httpClient.execute(httpPost);
//如果状态码正常则输出响应成功并输出内容
if(200== httpResponse.getStatusLine().getStatusCode()) {
System.out.println("post方式请求响应成功");
HttpEntity entity1 = httpResponse.getEntity();
String response = EntityUtils.toString(entity1);
System.out.println(response);
}
}catch(IOException e) {
e.printStackTrace();
}
}
}
本机的JDK的位置为:E:\Jdk8
程序的位置为:D:\develop_practice\test_20170705\src\main\java\com\yf\service
本来以为这还不简单,配置好java环境变量(以下会介绍如何配置),直接在dos下编译(javac),运行(java)不就ok了嘛!!!So easy!
结果我艹首先编译的过程就懵逼了.提示乱码错误!(如下图所示)
原因是:IDE中采用的是UTF-8的编码格式,而这里默认采用的是GBK的编码解析,当然会乱码!最简单的解决方案是采用带选项编译(不清楚可以通过javac Enter查看),如下:
好了,现在应该编译没问题了吧,不就一个编码问题嘛,就是干!结果如下:
我屮艸芔茻...Double Kill!!!提示一大堆的各种包找不到(25个找不到)!原因是因为在IDE中通过maven配置的方式,IDE会自动到本地仓库(maven中配置的)去找从远程仓库(remote repository)下载下来的jar包。而没有了IDE,系统就会到配置好的JDK路径下去找,更具体一点是到安装的JDK下面的jre下面的lib下的ext路径下去找(本机是E:\Jdk8\jre\lib\ext这个路径)。所以上面问题本质是在默认路径下找不到包!默认路径下!包!
通过我的阿拉丁神灯(阴险表情),终于让我找到了答案。解决方案有两个:1.直接通过带选项编译,比如我的其中一个jar包路径在C:\Users\ClearWang\.m2\repository\commons-logging\commons-logging\1.1.1(其实这种方式找运行所需的jar包很SB,如果对maven比较熟悉的话,可以通过maven打包,之后会生成一个war包,这个war包放在tomcat服务器的webapps下会自动部署成对应的应用(可以理解为解压的过程),前提是tomcat是打开的亲,这个应用下的\WEB-INF\lib目录下就是工程所需要的所有jar包,这样找你会发现so easy!),那么我编译的时候写法如下图所示:
你会发现,还是会有问题,只不过问题要少了一些(25个变成了14个),如下图所示。
说明这个方法是管用的,我只要把所有的jar路径全部添加上去不就欧了么!但是!但是!但是!我缺了那么多包(具体来说,我这里是4个jar包),我总不至于一个一个的添加上去吧(傻X啊),于是老子又求了一下阿拉丁,她(嗯,你没没错,就是她)给出了一种更加简单的方法:2.将需要的jar包拷贝到默认的路径下(E:\Jdk8\jre\lib\ext上面红色字体部分的思路,既然已经有了默认路径,不就是缺包么,那么老子给你不就得了),于是:
编译成功后会在当前目录下生成一个.class的字节码文件。
好了,我的太阳(太阳:日,啧啧我的太阳即:我。。咳咳发泄一下),现在编译ok了 ,应该就不会有问题了吧,于是直接java MyHttpClient(或者java MyHttpClient.java),结果如下:
恩,恩好......好....好简单!(硬气装逼!)
对了,最上面那个为什么在dos下运行要注释包的问题,原因是如果不注释的话,运行的时候(java MyHttpClient)(编译没有问题)就会提示找不到或者无法下载主类的问题(当然,如果你的这个程序里面本来就没有主类的话也会提示这个错误),如下图所示:
====================================环境变量=============================
恩,问题解决了,现在说一下如何配置环境变量,以及为什么要配置环境变量,先来说下为什么要配置环境变量吧:这里通过不配置环境变量运行编译和运行以上程序来体会配置环境变量的好处(自己体会):
在不配置任何环境变量(Java_Home,ClassPath)的情况下,编译和运行该程序(直接上图):
关键点:1.进入jdk的javac环境
2.带选项编译和运行(如果不清楚选项的作用可以直接javac回车或者java回车查看)
通过以上对比,也深刻体会了配置环境变量的好处了!最后想说句,我擦嘞,就是干!!!
那如何配置呢?很简单,直接上图:
在系统变量那里直接添加上JDK下的bin路径即可。当然也可以使用其它的方式配置环境变量,比如说在系统变量(注意一定是系统变量那里新建,不能建错了,建在用户变量那里)新建一个JAVA_HOME(个人认为大小写都可以,我习惯大写),然后添加到系统变量中Path中去,比如这里的JAVA_HOME如果配置的路径为:E:\Jdk8那么Path中就应该写成:%JAVA_HOME%\bin(%括起来表示引用这个路径)
对于CLASSPATH,如果不配置的话默认会从当前路径加载字节码文件(本机就没配置,当然,网上有说最好配置的,因为有的IDE可能会需要之类的,这个看个人情况处理),如果配置的话配置方法为:.;D:\develop_practice\test_20170705\src\main\java\com\yf\service或者D:\develop_practice\test_20170705\src\main\java\com\yf\service;.(直接配置在系统变量那里就好了,不需要再添加到Path路径,点写在前面表示先在当前目录查找.class文件,找不到再在配置的路径下查找,反之,点加在后面表示先在配置的路径下查找找不到再在当前目录下查找)
最后,配好了可以在dos下,使用echo命令查看配置的环境变量的路径,比如说要查看配好的JAVA_HOME路径可以这样写:echo %JAVA_HOME%。
最后对Path和CLASSPATH做个比较:
Path:Path环境变量记录的是可执行文件,例如:.exe。对可执行文件,先在当前路径去找,如果没找到就到配置的路径下去查找。
CLASSPATH:CLASSPATH里配置的是java的运行文件所在路径(即.class的字节码文件)。
然而,然而,然而(重要的事情说三遍):生产环境下不允许先打开源代码,然后注释掉其中的包(类似于package com.yf.service),这时候怎么办呢?
方法如下:
编译的时候使用带-d选项编译(会根据程序中的包名在-d后指定的文件夹下生成指定的带包的文件),然后运行的时候一定要以带包的形式访问,如下图所示:
不带包运行就会出现“找不到或无法加载主类MyHttpClient”这样的错误。如下所示:
然而,然而,然而(重要的事情再说三遍):生产环境下,你不能指望我每次都将对应的第三方jar包全部拷贝到jdk下面的ext目录下吧?(我的机子是E:\Jdk8\jre\lib\ext)
处理方式:如下图
这种方式显然很不好,我这里有4个jar包都已经这么长了,如果我有更多的外在依赖jar包,岂不是很长??那怎么办呢,在jdk 1.6之后(也就是说如果你是之前的版本,就不支持这种方式了),提供了一种新的方式(如下图):
其中-Djava.ext.dirs=jar包的存放路径
这样的话,不管我外在依赖的jia包是多少个,我只需要将它放在对应的目录下就OK了(我这里是D:\develop_practice\test_20170705\lib目录,一般生产环境下打出的war包自动部署之后都会有一个lib目录专门存放这些程序依赖的第三方jar包的)
注意:javac的常用选项及其作用:
1》-classpath+路径(.表示当前路径): 指定当前工程的classpath路径 (这里为什么不说是当前类的classpath路径,因为如果以javac -classpath c:\ClearWang\Develop Demo.java就会在指定的c:\ClearWang\Develop下对指定的当前类Demo.java生成对应的class字节码文件,但是如果是javac -classpath c:\ClearWang\Develop *.java就会对所有的类同时生成字节码文件 所以说成当前工程要更准确)
2》-d+路径:在指定的路径下将生成的字节码文件以带包名的形式存放,要求运行时要带包运行。
3》-encoding+编码类型(例如utf8、gbk等):以指定的编码格式编译文件。当调用javac命令时,会把源文件进行一次编码转换,如果没有指定字符集,就从操作系统默认的字符集(Windows默认是GBK)转换成Java内部默认的unicode字符集,然后再将源文件编译成class文件,并且以unicode的编码形式保存到硬盘上。
4》-cp+jar包路径:以指定的jar包运行当前的类(如果当前类只需要依赖一两个jar,可以使用这种方式运行)
补充下dos下对一个应用打成war包的命令(虽然不常用,因为很多工具都可以帮我们自动完成这个功能,比如maven):
jar -cvf yftech.war yftech
将yftech打成yftech.war包(对,你没看错,如果你写成jar -cvf yftech yftech.war)就写错了,因为老外的脑袋被驴踢过,想法总是反正来,简直了。。。我的太阳!)
=================================OVER欢迎吐槽=========================