HttpClient的作用强大,真的是十分强大.
本实例是基于v4.3.3写的,,作用是模拟登陆后进行上下班打卡,,,使用htmlparser进行解析返回的html文件
关于HttpClient的一些详细介绍可以参考: HttpClient详解
Maven的主要配置
1 <properties> 2 <jdk.version>1.6</jdk.version> 3 </properties> 4 5 <dependencies> 6 <dependency> 7 <groupId>org.htmlparser</groupId> 8 <artifactId>htmlparser</artifactId> 9 <version>1.6</version> 10 </dependency> 11 12 <!-- httpcomponents --> 13 <dependency> 14 <groupId>org.apache.httpcomponents</groupId> 15 <artifactId>httpcore</artifactId> 16 <version>4.3.2</version> 17 </dependency> 18 <dependency> 19 <groupId>org.apache.httpcomponents</groupId> 20 <artifactId>httpclient</artifactId> 21 <version>4.3.3</version> 22 </dependency> 23 </dependencies> 24 <build> 25 <finalName>ROOT</finalName> 26 <plugins> 27 <!-- compiler插件, 设定JDK版本 --> 28 <plugin> 29 <groupId>org.apache.maven.plugins</groupId> 30 <artifactId>maven-compiler-plugin</artifactId> 31 <version>3.0</version> 32 <configuration> 33 <source>${jdk.version}</source> 34 <target>${jdk.version}</target> 35 <showWarnings>true</showWarnings> 36 <encoding>UTF-8</encoding> 37 <compilerArguments> 38 <verbose /> 39 <bootclasspath>${java.home}lib t.jar</bootclasspath> 40 </compilerArguments> 41 </configuration> 42 </plugin> 43 <plugin> 44 <groupId>org.apache.maven.plugins</groupId> 45 <artifactId>maven-shade-plugin</artifactId> 46 <version>1.4</version> 47 <executions> 48 <execution> 49 <phase>package</phase> 50 <goals> 51 <goal>shade</goal> 52 </goals> 53 <configuration> 54 <transformers> 55 <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> 56 <mainClass>cn.ffcs.eis.TestEis</mainClass> 57 </transformer> 58 </transformers> 59 </configuration> 60 </execution> 61 </executions> 62 </plugin> 63 </plugins> 64 </build>
1 package cn.ffcs.clent; 2 3 import java.io.FileOutputStream; 4 import java.io.IOException; 5 import java.io.UnsupportedEncodingException; 6 import java.net.HttpURLConnection; 7 import java.net.URL; 8 import java.util.ArrayList; 9 import java.util.List; 10 import java.util.Map; 11 import java.util.Set; 12 13 import org.apache.http.Header; 14 import org.apache.http.HttpEntity; 15 import org.apache.http.HttpResponse; 16 import org.apache.http.NameValuePair; 17 import org.apache.http.ParseException; 18 import org.apache.http.client.ClientProtocolException; 19 import org.apache.http.client.CookieStore; 20 import org.apache.http.client.HttpClient; 21 import org.apache.http.client.config.CookieSpecs; 22 import org.apache.http.client.config.RequestConfig; 23 import org.apache.http.client.entity.UrlEncodedFormEntity; 24 import org.apache.http.client.methods.HttpGet; 25 import org.apache.http.client.methods.HttpPost; 26 import org.apache.http.client.methods.HttpUriRequest; 27 import org.apache.http.config.Registry; 28 import org.apache.http.config.RegistryBuilder; 29 import org.apache.http.cookie.Cookie; 30 import org.apache.http.cookie.CookieOrigin; 31 import org.apache.http.cookie.CookieSpec; 32 import org.apache.http.cookie.CookieSpecProvider; 33 import org.apache.http.cookie.MalformedCookieException; 34 import org.apache.http.impl.client.BasicCookieStore; 35 import org.apache.http.impl.client.CloseableHttpClient; 36 import org.apache.http.impl.client.HttpClients; 37 import org.apache.http.impl.cookie.BasicClientCookie; 38 import org.apache.http.impl.cookie.BestMatchSpecFactory; 39 import org.apache.http.impl.cookie.BrowserCompatSpec; 40 import org.apache.http.impl.cookie.BrowserCompatSpecFactory; 41 import org.apache.http.message.BasicNameValuePair; 42 import org.apache.http.protocol.HttpContext; 43 import org.apache.http.util.EntityUtils; 44 import org.htmlparser.Parser; 45 46 /** 47 * HttpClient使用4.3.3,Parser使用1.6 48 * @author zkongbai 49 * 50 */ 51 public class HttpUtils { 52 53 public static final String UTF_8 = "UTF-8"; 54 public static CookieStore COOKIE_STORE = new BasicCookieStore(); 55 56 public static void setCOOKIE_STORE(CookieStore cOOKIE_STORE) { 57 COOKIE_STORE = cOOKIE_STORE; 58 } 59 60 61 public static HttpPost postForm(String url,Map<String, String> params,Map<String, String> hearders){ 62 HttpPost httpPost = new HttpPost(url); 63 List<NameValuePair> nvps = new ArrayList <NameValuePair>(); 64 if(params != null){ 65 Set<String> keySet = params.keySet(); 66 for(String key : keySet) { 67 nvps.add(new BasicNameValuePair(key, params.get(key))); 68 } 69 } 70 if(hearders != null){ 71 Set<Map.Entry<String, String>> mapping = hearders.entrySet(); 72 for(Map.Entry<String, String> entry : mapping){ 73 httpPost.setHeader(entry.getKey(),entry.getValue()); 74 } 75 } 76 try { 77 httpPost.setEntity(new UrlEncodedFormEntity(nvps, UTF_8)); 78 } catch (UnsupportedEncodingException e) { 79 e.printStackTrace(); 80 } 81 return httpPost; 82 } 83 84 85 /** 86 * 使用默认的HttpClient发送Get请求 87 * @param url 88 * @return 89 */ 90 public static String get(String url) throws Exception{ 91 HttpClient httpclient = HttpClients.createDefault(); 92 String body = null; 93 HttpGet get = new HttpGet(url); 94 body = invoke(httpclient, get); 95 return body; 96 } 97 98 /** 99 * 使用自定义HttpClient发送Get请求 100 * @param client 101 * @param url 102 * @return 103 */ 104 public static String get(HttpClient client,String url) throws Exception{ 105 String body = null; 106 HttpGet get = new HttpGet(url); 107 body = invoke(client, get); 108 return body; 109 } 110 111 /** 112 * 使用自定义HttpClient发送Get请求,并返回HttpResponse 113 * @param client 114 * @param url 115 * @return 116 */ 117 public static HttpResponse getAndResponse(HttpClient client,String url) throws Exception{ 118 return sendRequest(client, new HttpGet(url)); 119 } 120 121 private static String invoke(HttpClient httpclient, HttpUriRequest httpost) throws Exception{ 122 HttpResponse response = sendRequest(httpclient, httpost); 123 String body = paseResponse(response); 124 return body; 125 } 126 127 public static HttpResponse sendRequest(HttpClient httpclient,HttpUriRequest httpost) throws Exception{ 128 HttpResponse response = null; 129 try { 130 response = httpclient.execute(httpost); 131 } catch (ClientProtocolException e) { 132 throw e; 133 } catch (IOException e) { 134 throw e; 135 } 136 return response; 137 } 138 139 public static String paseResponse(HttpResponse response) throws Exception{ 140 //listHearders(response); 141 HttpEntity entity = response.getEntity(); 142 // ContentType contentType = ContentType.getOrDefault(entity); 143 // System.out.println(contentType.toString()); 144 String body = null; 145 try { 146 body = EntityUtils.toString(entity); 147 } catch (ParseException e) { 148 throw e; 149 } catch (IOException e) { 150 throw e; 151 } finally{ 152 // if(response != null){ 153 // if(response instanceof CloseableHttpResponse){ 154 // try { 155 // ((CloseableHttpResponse) response).close(); 156 // response = null; 157 // } catch (IOException e) {} 158 // } 159 // } 160 if(response != null){ 161 try { 162 EntityUtils.consume(entity); 163 } catch (IOException e) {} 164 } 165 } 166 return body; 167 } 168 169 /** 170 * Write htmL to file. 171 * 将请求结果以二进制形式放到文件系统中保存为.html文件,便于使用浏览器在本地打开 查看结果 172 * 173 * @param entity the entity 174 * @param pathName the path name 175 * @return HttpEntity.getContentLength() != -1 时,返回true 176 * @throws Exception the exception 177 */ 178 public static boolean writeHTMLtoFile(HttpEntity entity, String pathName) throws Exception{ 179 int length = (int) entity.getContentLength(); 180 byte[] bytes = null; 181 boolean flag = true; 182 if(length != -1){ 183 bytes = EntityUtils.toByteArray(entity); 184 flag = false; 185 }else{ 186 try { 187 bytes = "has nothing to write!".getBytes(UTF_8); 188 } catch (UnsupportedEncodingException e) {throw e;} 189 } 190 FileOutputStream fos = null; 191 try { 192 fos = new FileOutputStream(pathName); 193 fos.write(bytes); 194 fos.flush(); 195 } catch (IOException e) { 196 throw e; 197 } finally{ 198 if(fos != null){ 199 try { 200 fos.close(); 201 fos = null; 202 } catch (Exception e) {} 203 } 204 } 205 return flag; 206 } 207 208 /** 209 * 将请求结果以二进制形式放到文件系统中保存为.html文件,便于使用浏览器在本地打开 查看结果 210 * @param entity 211 * @param pathName 212 * @return 213 * @throws Exception 214 */ 215 public static boolean writeString2File(String body, String pathName) throws Exception{ 216 boolean flag = false; 217 FileOutputStream fos = null; 218 try { 219 byte[] bytes = body.getBytes(UTF_8); 220 fos = new FileOutputStream(pathName); 221 fos.write(bytes); 222 fos.flush(); 223 flag = true; 224 } catch (IOException e) { 225 throw e; 226 } finally{ 227 if(fos != null){ 228 try { 229 fos.close(); 230 fos = null; 231 } catch (Exception e) {} 232 } 233 } 234 return flag; 235 } 236 237 /** 238 * 解析HttpResponse,并设置Cookie 239 * @param response 240 */ 241 @Deprecated 242 public static void setCookie(HttpResponse response){ 243 String setCookie = nvl(response.getFirstHeader("Set-Cookie").getValue()).trim(); 244 String JSESSIONID = setCookie.substring("JSESSIONID=".length(),setCookie.indexOf(";")); 245 System.out.println("JSESSIONID:" + JSESSIONID); 246 BasicClientCookie cookie = new BasicClientCookie("JSESSIONID",JSESSIONID); 247 cookie.setVersion(0); 248 cookie.setDomain("127.0.0.1"); 249 cookie.setPath("/CwlProClient"); 250 //cookieStore.addCookie(cookie); 251 } 252 253 /** 254 * 下次请求时候含有Cookie 255 * @param response 256 * @return 257 */ 258 public static CloseableHttpClient getHttpClientWithCookie() { 259 260 CookieSpecProvider easySpecProvider = new CookieSpecProvider() { 261 public CookieSpec create(HttpContext context) { 262 return new BrowserCompatSpec() { 263 @Override 264 public void validate(Cookie cookie, CookieOrigin origin) throws MalformedCookieException { 265 COOKIE_STORE.addCookie(cookie); 266 } 267 }; 268 } 269 }; 270 Registry<CookieSpecProvider> r = RegistryBuilder 271 .<CookieSpecProvider> create() 272 .register(CookieSpecs.BEST_MATCH, new BestMatchSpecFactory()) 273 .register(CookieSpecs.BROWSER_COMPATIBILITY,new BrowserCompatSpecFactory()) 274 .register("easy", easySpecProvider) 275 .build(); 276 277 RequestConfig requestConfig = RequestConfig 278 .custom() 279 .setCookieSpec("easy") 280 .setSocketTimeout(10000) 281 .setConnectTimeout(10000) 282 .build(); 283 284 CloseableHttpClient httpclient = HttpClients 285 .custom() 286 .setDefaultCookieSpecRegistry(r) 287 .setDefaultRequestConfig(requestConfig) 288 .setDefaultCookieStore(COOKIE_STORE) 289 .build(); 290 return httpclient; 291 } 292 public static CloseableHttpClient getHttpClientWithCookie2(){ 293 return HttpClients 294 .custom() 295 .setDefaultCookieStore(COOKIE_STORE) 296 .build(); 297 } 298 299 /** 300 * 遍历所有的Cookie 301 */ 302 public static void listCookie(){ 303 List<Cookie> cookies = HttpUtils.COOKIE_STORE.getCookies(); 304 if(cookies != null && !cookies.isEmpty()) 305 for(Cookie c : cookies){ 306 System.out.println("用户Cookie.... "+c); 307 } 308 else 309 System.err.println("暂时无Cookie"); 310 } 311 312 /** 313 * 遍历所有的请求头信息 314 * @param response 315 */ 316 public static void listHearders(HttpResponse response){ 317 //请求头信息 318 Header[] heards = response.getAllHeaders(); 319 for (Header s : heards) { 320 System.out.println("用户 header: " + s); 321 } 322 } 323 /** 324 * 通过string的HTML,解析HTML 325 * @param body 326 */ 327 public static Parser parseHTML(String body){ 328 Parser parser = Parser.createParser(body,UTF_8); 329 return parser; 330 } 331 332 /** 333 * 解析HTML 334 * @param url 335 * @return 336 * @throws Exception 337 */ 338 public static Parser parseHTMLByURL(String url) throws Exception{ 339 HttpURLConnection conn = (HttpURLConnection)new URL(url).openConnection(); 340 conn.setRequestProperty("Accept-Charset", "UTF-8"); 341 Parser parser = new Parser(conn); 342 return parser; 343 } 344 345 /** 346 * 空值处理,转换为默认值 347 * @param v 输入值 348 * @param defaultValue 默认值 349 * @return 非 null值 350 */ 351 public static String nvl(String v,String defaultValue){ 352 return v==null?defaultValue==null?"":defaultValue:v; 353 } 354 /** 355 * 空值处理,转换为默认值 356 * @param v 输入值 357 * @return 非 null值 358 */ 359 public static String nvl(String v){ 360 return nvl(v,null); 361 } 362 }
1 package cn.ffcs.eis; 2 3 import java.io.File; 4 import java.util.Calendar; 5 import java.util.HashMap; 6 import java.util.Map; 7 import java.util.Random; 8 9 import org.apache.http.Header; 10 import org.apache.http.HttpEntity; 11 import org.apache.http.HttpResponse; 12 import org.apache.http.client.HttpClient; 13 import org.apache.http.client.methods.HttpPost; 14 import org.apache.http.impl.client.BasicCookieStore; 15 import org.apache.http.impl.cookie.BasicClientCookie; 16 import org.apache.http.util.EntityUtils; 17 import org.htmlparser.Node; 18 import org.htmlparser.NodeFilter; 19 import org.htmlparser.Parser; 20 import org.htmlparser.filters.AndFilter; 21 import org.htmlparser.filters.HasAttributeFilter; 22 import org.htmlparser.filters.NodeClassFilter; 23 import org.htmlparser.filters.OrFilter; 24 import org.htmlparser.filters.TagNameFilter; 25 import org.htmlparser.tags.InputTag; 26 import org.htmlparser.tags.LinkTag; 27 import org.htmlparser.tags.TableColumn; 28 import org.htmlparser.tags.TableHeader; 29 import org.htmlparser.tags.TableRow; 30 import org.htmlparser.tags.TableTag; 31 import org.htmlparser.util.NodeList; 32 import org.htmlparser.util.SimpleNodeIterator; 33 34 import cn.ffcs.clent.HttpUtils; 35 import cn.ffcs.eis.constant.EisInfo; 36 import cn.ffcs.eis.constant.EisURL; 37 import cn.ffcs.eis.pojo.EisAccount; 38 import cn.ffcs.eis.utils.EisDateUtils; 39 40 public class EisWorker { 41 42 public EisWorker(){ 43 44 } 45 46 private static Map<String,String> login_param = new HashMap<String,String>(); 47 private static Map<String,String> head_param = new HashMap<String,String>(); 48 private static Map<String,String> userInfo_param = new HashMap<String,String>(); 49 50 public static Map<String, String> getLogin_param() { 51 return login_param; 52 } 53 public static Map<String, String> getHead_param() { 54 return head_param; 55 } 56 public static Map<String, String> getUserInfo_param() { 57 return userInfo_param; 58 } 59 60 /** 61 * 下班打卡需要的打卡小时数 62 */ 63 private static final String WORK_HOUR = "9"; 64 65 static { 66 login_param.put("login_submit", "on"); 67 login_param.put("login_do_redirect", "1"); 68 login_param.put("no_cert_storing", "on"); 69 login_param.put("j_authscheme", "default"); 70 71 head_param.put("Accept", "application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*"); 72 head_param.put("Accept-Encoding", "gzip, deflate"); 73 head_param.put("Accept-Language", "zh-CN"); 74 head_param.put("User-Agent", "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; InfoPath.2; .NET4.0C; .NET4.0E)"); 75 head_param.put("Referer", EisURL.URL_LOGIN); 76 head_param.put("Content-Type", "application/x-www-form-urlencoded"); 77 78 //userInfo_param.put("btnsave","%E4%BF%9D%E5%AD%98"); 79 } 80 81 /** 82 * 登录,返回带Cookie的HttpClient 83 * @param userName 84 * @param password 85 * @return 86 * @throws Exception 87 */ 88 public static HttpClient login(EisAccount account) throws Exception{ 89 HttpUtils.setCOOKIE_STORE(new BasicCookieStore()); 90 String userName = account.getUserName().trim(); 91 String password = account.getPasswd().trim(); 92 93 login_param.put("j_user", userName); 94 login_param.put("j_password", password); 95 HttpPost post = HttpUtils.postForm(EisURL.URL_LOGIN, login_param,head_param); 96 HttpClient httpclient = HttpUtils.getHttpClientWithCookie(); 97 HttpResponse response = httpclient.execute(post); //含有下次请求的Cookie: MYSAPSSO2 98 //HttpUtils.listHearders(response); 99 login_param.remove("j_user"); 100 login_param.remove("j_password"); 101 HttpEntity entity = response.getEntity(); 102 // HttpUtils.writeHTMLtoFile(entity,getSuffixName("login",userName)); 103 EntityUtils.consume(entity); 104 response = HttpUtils.getAndResponse(httpclient, EisURL.URL_JSESSION); 105 _setJSESSION(response); 106 System.out.println("===============login====分割线=================================="); 107 return _getLtpaToken(httpclient); 108 } 109 110 private static HttpClient _getLtpaToken(HttpClient clientWithCookie) throws Exception{ 111 head_param.put("Referer","http://bem.ffcs.cn:81/mis/EISTask.aspx"); 112 HttpUtils.get(clientWithCookie, EisURL.URL_LtpaToken);//使得下次请求含有LtpaToken 113 return HttpUtils.getHttpClientWithCookie(); 114 } 115 116 117 /** 118 * 获取打卡相关信息,登录后需要调用 119 * @param clientWithCookie 120 * @throws Exception 121 */ 122 public static HttpClient userWorkInfo(HttpClient clientWithCookie,String loginName) throws Exception{ 123 head_param.put("Referer","http://bem.ffcs.cn:81/mis/EISIndex.aspx"); 124 HttpPost post = HttpUtils.postForm(EisURL.URL_USERWORK_INFO,null,head_param); 125 HttpResponse response = clientWithCookie.execute(post); 126 //HttpUtils.listHearders(response); 127 _setAspNetSession(response); //注入含ASP.NET_SessionId的Cookie 128 HttpEntity entity = response.getEntity(); 129 // HttpUtils.writeHTMLtoFile(entity, "C:/userWorkInfo.html"); 130 String result = EntityUtils.toString(entity); 131 if("请登录".equals(result)){ 132 HttpUtils.writeString2File(result, getSuffixName("error", loginName)); 133 throw new Exception(loginName+"登录失败"); 134 } 135 else 136 System.out.println("---------------->"+loginName+"登录成功"); 137 EntityUtils.consume(entity); 138 parseUserInfo(result); 139 System.out.println("===============userWorkInfo====分割线=================================="); 140 return HttpUtils.getHttpClientWithCookie(); 141 } 142 143 /** 144 * 上班打卡 145 * @param clientWithCookie 146 * @throws Exception 147 */ 148 public static String submitOnWork(HttpClient clientWithCookie) throws Exception{ 149 userInfo_param.remove("ibOn"); 150 head_param.put("Referer","http://bem.ffcs.cn:81/hrs/work/UserWork.aspx"); 151 HttpPost post = HttpUtils.postForm(EisURL.URL_USERWORK_INFO, userInfo_param,head_param); 152 HttpResponse response = clientWithCookie.execute(post); 153 HttpEntity entity = response.getEntity(); 154 String result = EntityUtils.toString(entity); 155 //HttpUtils.listCookie(); 156 EntityUtils.consume(entity); 157 System.out.println("===============上班打卡====分割线=================================="); 158 return result; 159 } 160 161 /** 162 * 下班打卡 163 * @param clientWithCookie 164 * @return 165 * @throws Exception 166 */ 167 @SuppressWarnings("unused") 168 public static String submitOffWork(HttpClient clientWithCookie,String loginName) throws Exception{ 169 executeBeforeWorkOff(clientWithCookie,loginName); 170 head_param.put("Referer",EisURL.URL_USERWORK_OFF+"?userno="+userInfo_param.get("userno")+"work=1"); 171 head_param.put("Accept", "text/html, application/xhtml+xml, */*"); 172 head_param.put("Host", "bem.ffcs.cn:81"); 173 head_param.put("Connection", "Keep-Alive"); 174 head_param.put("User-Agent", "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)"); 175 // userInfo_param.put("flag", "1");//非正常时间打卡下班 176 // userInfo_param.put("date", EisDateUtils.getCurDateFormatStr());//获取当前日期 177 178 Map<String, String> submitParam = new HashMap<String,String>(); 179 String reqUri = "?"; 180 for(Map.Entry<String, String> entry : userInfo_param.entrySet()){ 181 if(!entry.getKey().startsWith("pc") && !entry.getKey().startsWith("ibOn")){ 182 submitParam.put(entry.getKey(),entry.getValue()); 183 if(!"__VIEWSTATE".equalsIgnoreCase(entry.getKey())) 184 reqUri += entry.getKey()+"="+entry.getValue()+"&"; 185 } 186 } 187 HttpPost post = HttpUtils.postForm(EisURL.URL_USERWORK_OFF, submitParam,head_param); 188 HttpResponse response = HttpUtils.getHttpClientWithCookie2().execute(post); 189 HttpEntity entity = response.getEntity(); 190 String result = EntityUtils.toString(entity); 191 // String result = HttpUtils.get(HttpUtils.getHttpClientWithCookie2(), EisURL.URL_USERWORK_OFF+reqUri);//Get请求方式 192 System.out.println("===============下班打卡====分割线=================================="); 193 return result; 194 } 195 196 /** 197 * 检查上班打卡时间 198 * @param clientWithCookie 199 * @param no 200 * @param cnName 201 * @throws Exception 202 */ 203 public static void checkWork(HttpClient clientWithCookie,String loginName) throws Exception{ 204 head_param.put("Referer","http://bem.ffcs.cn:81/hrs/work/UserWork.aspx"); 205 login_param.put("strUserNo",userInfo_param.get("pcUserno")); 206 login_param.put("strUserName",userInfo_param.get("pcUsername")); 207 HttpPost post = HttpUtils.postForm(EisURL.URL_CHECK_WORK, login_param,head_param); 208 HttpResponse response = clientWithCookie.execute(post); 209 HttpEntity entity = response.getEntity(); 210 HttpUtils.writeHTMLtoFile(entity, getSuffixName("checkWork", loginName)); 211 EntityUtils.consume(entity); 212 } 213 214 /** 215 * 下班时间检查 216 * @param clientWithCookie 217 * @param no 218 * @throws Exception 219 */ 220 public static void checkOffTime(HttpClient clientWithCookie,String loginName) throws Exception{ 221 head_param.put("Referer","http://bem.ffcs.cn:81/hrs/work/UserWork.aspx"); 222 login_param.put("strUserNo",userInfo_param.get("pcUserno")); 223 HttpPost post = HttpUtils.postForm(EisURL.URL_LOGIN, login_param,head_param); 224 HttpResponse response = clientWithCookie.execute(post); 225 HttpEntity entity = response.getEntity(); 226 HttpUtils.writeHTMLtoFile(entity, getSuffixName("checkOffTime", loginName)); 227 EntityUtils.consume(entity); 228 } 229 230 /** 231 * 解析返回的打卡信息,并检查与重置ip,将有效信息存放内存中 232 * @param body 233 * @throws Exception 234 */ 235 private static void parseUserInfo(String body) throws Exception{ 236 // String url = "http://zkongbai:8080/userWorkInfo.html"; 237 // Parser parser = HttpUtils.parseHTMLByURL(url); 238 Parser parser = HttpUtils.parseHTML(body); 239 NodeFilter filter = new AndFilter(new HasAttributeFilter ("type","hidden"),new TagNameFilter ("input")); 240 NodeFilter filter2 = new AndFilter(new HasAttributeFilter ("type","image"),new TagNameFilter ("input")); 241 // NodeList nodeList = parser.parse(null); 242 NodeList nodeList = parser.extractAllNodesThatMatch(new OrFilter(filter, filter2)); 243 SimpleNodeIterator it = nodeList.elements(); 244 Node node = null; 245 InputTag tag = null; 246 while(it.hasMoreNodes()){ 247 node = it.nextNode(); 248 // System.out.println(node.toHtml()); 249 tag = ((InputTag)node); 250 userInfo_param.put(tag.getAttribute("id"),nvl(tag.getAttribute("value"))); 251 // System.out.println(tag.getAttribute("id")+"="+tag.getAttribute("value")); 252 } 253 if("0".equals(userInfo_param.get("pcPostrand"))){ 254 if(userInfo_param.get("pcIpAddress") != null && !"".equals(userInfo_param.get("pcIpAddress"))){ 255 userInfo_param.put("pcLocalIpAddress",userInfo_param.get("pcIpAddress")); 256 }else{ 257 throw new Exception(userInfo_param.get("pcUsername")+",OA没有登记您的考勤IP,请联系信息中心。"); 258 } 259 } 260 effectiveIBON(); 261 } 262 private static void _setAspNetSession(HttpResponse response){ 263 if(response.getFirstHeader("Set-Cookie")==null) 264 return; 265 String setCookie = nvl(response.getFirstHeader("Set-Cookie").getValue()).trim(); 266 String aspSession = setCookie.substring("ASP.NET_SessionId=".length(),setCookie.indexOf(";")); 267 //System.out.println("ASP.NET_SessionId:" + aspSession); 268 BasicClientCookie cookie = new BasicClientCookie("ASP.NET_SessionId",aspSession); 269 cookie.setVersion(0); 270 cookie.setDomain("bem.ffcs.cn"); 271 cookie.setPath("/"); 272 HttpUtils.COOKIE_STORE.addCookie(cookie); 273 } 274 private static void _setJSESSION(HttpResponse response){ 275 Header[] heards = response.getAllHeaders(); 276 String setCookie = null; 277 for (Header heard : heards) { 278 if("Set-Cookie".equalsIgnoreCase(heard.getName())){ 279 setCookie = heard.getValue(); 280 if(setCookie.contains("JSESSIONID=")){ 281 String JSESSIONID = setCookie.substring("JSESSIONID=".length(),setCookie.indexOf(";")); 282 BasicClientCookie cookie = new BasicClientCookie("JSESSIONID",JSESSIONID); 283 cookie.setVersion(0); 284 cookie.setDomain(".ffcs.cn"); 285 cookie.setPath("/"); 286 HttpUtils.COOKIE_STORE.addCookie(cookie); 287 }else if(setCookie.contains("sapj2ee_*=")){ 288 String JSESSIONID = setCookie.substring("sapj2ee_*=".length(),setCookie.indexOf(";")); 289 BasicClientCookie cookie = new BasicClientCookie("sapj2ee_*",JSESSIONID); 290 cookie.setVersion(0); 291 cookie.setDomain("eis.ffcs.cn"); 292 cookie.setPath("/"); 293 HttpUtils.COOKIE_STORE.addCookie(cookie); 294 } 295 } 296 } 297 } 298 299 /** 300 * 解析上班打卡结果,判断是否成功打卡 301 * @param clientWithCookie 302 * @param othURI 303 * @param logName 304 * @throws Exception 305 */ 306 public static void parseSubmitOnWorkResult(HttpClient clientWithCookie,String othURI,String logName) throws Exception{ 307 //String othURI = "hrs/work/UserWorkList.aspx?id=12687061&flag=1#"; 308 othURI = java.net.URLDecoder.decode(othURI,HttpUtils.UTF_8); 309 String result = HttpUtils.get(clientWithCookie, EisURL.DOMAIN+othURI); 310 HttpUtils.writeString2File(result,getSuffixName("上班打卡结果",logName)); 311 Parser parser = HttpUtils.parseHTML(result); 312 NodeFilter filter = new NodeClassFilter(TableTag.class); 313 NodeList nodeList = parser.extractAllNodesThatMatch(filter); 314 for (int i = 0; i < nodeList.size(); ++i) { 315 if (nodeList.elementAt(i) instanceof TableTag) { 316 TableTag tag = (TableTag) nodeList.elementAt(i); 317 TableRow[] rows = tag.getRows(); 318 for (int j = 0; j < rows.length; ++j) { 319 TableRow row = (TableRow) rows[j]; 320 // the reason to get headers is to parse <th> tag 321 TableHeader[] headers = row.getHeaders(); 322 for (int k = 0; k < headers.length; ++k) {//标签头 323 // System.out.print("tag标签为:" + headers[k].getTagName().replaceAll("\s", "")+" "); 324 // System.out.print("标签的内容为:"+ headers[k].getStringText().replaceAll("\s", "")+" "); 325 } 326 TableColumn[] columns = row.getColumns(); 327 for (int k = 0; k < columns.length; ++k) {//标签体 328 String info = columns[k].toPlainTextString().replaceAll("\s", ""); 329 if("tdAmRemark".equalsIgnoreCase(columns[k].getAttribute("id"))){ 330 System.out.println("打卡结果:"+info); 331 if(!"正常".equals(info)){ 332 System.err.println(logName+EisDateUtils.getCurDateFormatStr()+"上班打卡失败"); 333 throw new Exception(logName+EisDateUtils.getCurDateFormatStr()+"上班打卡失败"); 334 } 335 } 336 } 337 //System.out.println(); 338 } 339 } 340 } 341 } 342 343 /** 344 * 解析上班打卡信息,据分析,body的信息只能含有一个超链接 345 * @param body 346 */ 347 public static void parseSubmitOnWork(HttpClient clientWithCookie,String body,String logName) throws Exception{ 348 Parser parser = HttpUtils.parseHTML(body); 349 NodeFilter filter = new TagNameFilter ("a"); 350 NodeList nodeList = parser.extractAllNodesThatMatch(filter); 351 SimpleNodeIterator it = nodeList.elements(); 352 Node node = null; 353 LinkTag tag = null; 354 boolean success = false; 355 String othURI = null; 356 int falg = 0; 357 while(it.hasMoreNodes()){ 358 ++falg; 359 node = it.nextNode(); 360 // System.out.println(node.toHtml()); 361 tag = ((LinkTag)node); 362 othURI = tag.getAttribute("href"); 363 if(othURI != null && othURI.contains("UserWorkList.aspx")){ 364 System.out.println("打卡结果:href:"+EisURL.DOMAIN+othURI); 365 success = true; 366 } 367 } 368 if(!success || falg>1){ 369 HttpUtils.writeString2File(body,getSuffixName("error", logName)); 370 throw new Exception("解析上班打卡信息失败,请检查代码"); 371 } 372 parseSubmitOnWorkResult(clientWithCookie,othURI,logName); 373 System.out.println("===============上班打卡结果====分割线=================================="); 374 } 375 376 /** 377 * 解析下班打卡信息 378 * @param clientWithCookie 379 * @param body 380 * @throws Exception 381 */ 382 public static void parseSubmitOffWork(HttpClient clientWithCookie,String body,String loginName) throws Exception{ 383 HttpUtils.writeString2File(body, getSuffixName("下班班打卡结果", loginName)); 384 System.out.println("===============下班打卡结果====分割线=================================="); 385 } 386 387 /** 388 * 下班打卡前,获取相关信息 389 * @param body 390 * @throws Exception 391 */ 392 private static void executeBeforeWorkOff(HttpClient clientWithCookie,String loginName) throws Exception{ 393 userInfo_param.put("work", "1"); 394 userInfo_param.put("userno",userInfo_param.get("pcUserno")); 395 396 // head_param.put("Referer",EisURL.URL_USERWORK_OFF); 397 // HttpPost post = HttpUtils.postForm(EisURL.URL_USERWORK_OFF, userInfo_param,head_param); 398 // HttpResponse response = clientWithCookie.execute(post); 399 // HttpEntity entity = response.getEntity(); 400 // String result = EntityUtils.toString(entity); 401 String result = HttpUtils.get(clientWithCookie, EisURL.URL_USERWORK_OFF+"?work=1&userno="+userInfo_param.get("userno")); 402 403 Parser parser = HttpUtils.parseHTML(result); 404 405 NodeFilter filter1 = new AndFilter(new HasAttributeFilter ("id","rownum"),new TagNameFilter ("input")); 406 NodeFilter filter2 = new AndFilter(new HasAttributeFilter ("class","cinput"),new TagNameFilter ("input")); 407 NodeFilter filter3 = new AndFilter(new HasAttributeFilter ("type","hidden"),new TagNameFilter ("input")); 408 NodeFilter filter = new OrFilter(new NodeFilter[]{filter1, filter2,filter3}); 409 // NodeList nodeList = parser.parse(null); 410 NodeList nodeList = parser.extractAllNodesThatMatch(filter); 411 SimpleNodeIterator it = nodeList.elements(); 412 Node node = null; 413 InputTag tag = null; 414 int hasXm = 0; //是否有可选的项目 415 while(it.hasMoreNodes()){ 416 node = it.nextNode(); 417 tag = (InputTag)node; 418 if("rownum".equalsIgnoreCase(tag.getAttribute("name"))){ 419 if(nvl(tag.getAttribute("value")).length()==0){ 420 userInfo_param.put(tag.getAttribute("id"),tag.getAttribute("value")); 421 HttpUtils.writeString2File(result, getSuffixName("error", loginName)); 422 throw new Exception("解析失败"); 423 } 424 }else if(tag.getAttribute("name").contains("sum-day-")){ 425 userInfo_param.put(tag.getAttribute("id"),WORK_HOUR); 426 }else if(tag.getAttribute("name").contains("item-")){ 427 userInfo_param.put(tag.getAttribute("name"),nvl(tag.getAttribute("value"))); 428 }else if (tag.getAttribute("name").contains("input-")){ 429 if(hasXm == 0) 430 userInfo_param.put(tag.getAttribute("name"),WORK_HOUR);//下班打卡的项目 431 else 432 userInfo_param.put(tag.getAttribute("name"),nvl(tag.getAttribute("value"))); 433 hasXm++; 434 }else if(tag.getAttribute("name").equalsIgnoreCase("__VIEWSTATE")){ 435 userInfo_param.put(tag.getAttribute("id"),nvl(tag.getAttribute("value"))); 436 } 437 } 438 if(hasXm==0){ 439 HttpUtils.writeString2File(result, getSuffixName("error", loginName)); 440 throw new Exception("解析失败 或 暂无可打卡的项目,请查看代码 或 联系信息中心"); 441 } 442 } 443 444 /** 445 * 空值处理,转换为默认值 446 * @param v 输入值 447 * @param defaultValue 默认值 448 * @return 非 null值 449 */ 450 public static String nvl(String v,String defaultValue){ 451 return v==null?defaultValue==null?"":defaultValue:v; 452 } 453 /** 454 * 空值处理,转换为默认值 455 * @param v 输入值 456 * @return 非 null值 457 */ 458 public static String nvl(String v){ 459 return nvl(v,null); 460 } 461 462 /** 463 * 上班图标的有效的位置 464 */ 465 private static void effectiveIBON(){ 466 Random random = new Random(); 467 userInfo_param.put("ibOn.x", String.valueOf(58+random.nextInt(6)%6-3)); 468 userInfo_param.put("ibOn.y", String.valueOf(17+random.nextInt(4)%4-2)); 469 } 470 /** 471 * 下班班图标的有效的位置 472 */ 473 @SuppressWarnings("unused") 474 private static void effectiveIBOFF(){ 475 Random random = new Random(); 476 userInfo_param.put("ibOff.x", String.valueOf(68+random.nextInt(6)%6-3)); 477 userInfo_param.put("ibOff.y", String.valueOf(17+random.nextInt(4)%4-2)); 478 } 479 480 /** 481 * 根据用户名生成对应的文件后缀名html 482 * @param fileName 文件名称.不含路径 483 * @param userName 用户 484 * @return 485 */ 486 public static String getSuffixName(String fileName,String userName,String...strings){ 487 if(userName == null || userName.length()==0) 488 userName = "anonymous"; 489 String path = EisInfo.LOG_PATH+userName+File.separator+EisDateUtils.getCurDateFormatStr(); 490 File file = new File(path); 491 if(!file.exists()){ 492 file.mkdirs(); 493 } 494 if(strings != null && strings.length>0){ 495 if("log".equals(strings[0])) 496 return path+File.separator+fileName+"."+userName+"."+EisDateUtils.getCurDateFormatStr()+".log"; 497 } 498 return path+File.separator+fileName+"."+userName+"."+EisDateUtils.getCurDateFormatStr()+"."+Calendar.getInstance().getTimeInMillis()+".html"; 499 } 500 }
1 package cn.ffcs.eis.utils; 2 3 import java.text.ParseException; 4 import java.text.SimpleDateFormat; 5 import java.util.Calendar; 6 import java.util.Date; 7 8 public class EisDateUtils { 9 10 public static final SimpleDateFormat fullDateFormat = new SimpleDateFormat("yyyy-MM-dd"); 11 public static final SimpleDateFormat fullTimeFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 12 13 public static String getCurDateFormatStr(){ 14 Calendar c = Calendar.getInstance(); 15 return fullDateFormat.format(c.getTime()); 16 } 17 18 public static String getCurTimeFormatStr(){ 19 Calendar c = Calendar.getInstance(); 20 return fullTimeFormat.format(c.getTime()); 21 } 22 23 public static String getDateFormatStr(Date date){ 24 Calendar c = Calendar.getInstance(); 25 c.setTime(date); 26 return fullDateFormat.format(c.getTime()); 27 } 28 29 /** 30 * 判断某个时间是否在某段区间内 31 * @param start 32 * @param end 33 * @param date 需要判断的时间,为空时,则为系统当前时间 34 * @return 35 */ 36 public static boolean isAtCertainTime(String start,String end,Date date,SimpleDateFormat format){ 37 if(date == null){ 38 date = Calendar.getInstance().getTime(); 39 } 40 if(format == null){ 41 format = fullTimeFormat; 42 } 43 Date StartDate = parseTime(start,format); 44 Date endDate = parseTime(end,format); 45 return date.getTime() >= StartDate.getTime() && date.getTime() <= endDate.getTime(); 46 } 47 48 /** 49 * 判断某个时间是否在某段区间内 50 * @param start 51 * @param end 52 * @param date 需要判断的时间,为空时,则为系统当前时间 53 * @return 54 */ 55 public static boolean isAtCertainTime(Date start,Date end,Date date){ 56 if(date == null){ 57 date = Calendar.getInstance().getTime(); 58 } 59 return date.getTime() >= start.getTime() && date.getTime() <= end.getTime(); 60 } 61 62 /** 63 * @param date 64 * @param format 65 * @return 66 */ 67 public static Date parseDate(String date,SimpleDateFormat format){ 68 if(format == null){ 69 format = new SimpleDateFormat("yyyy-MM-dd"); 70 } 71 try { 72 return format.parse(date); 73 } catch (ParseException e) { 74 e.printStackTrace(); 75 } 76 return null; 77 } 78 /** 79 * @param date 80 * @param format 81 * @return 82 */ 83 public static Date parseTime(String date,SimpleDateFormat format){ 84 if(format == null){ 85 format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 86 } 87 try { 88 return format.parse(date); 89 } catch (ParseException e) { 90 e.printStackTrace(); 91 } 92 return null; 93 } 94 }
1 package cn.ffcs.eis.pojo; 2 3 public class EisAccount { 4 5 private String userName; 6 private String passwd; 7 8 public String getUserName() { 9 return userName; 10 } 11 public void setUserName(String userName) { 12 this.userName = userName; 13 } 14 public String getPasswd() { 15 return passwd; 16 } 17 public void setPasswd(String passwd) { 18 this.passwd = passwd; 19 } 20 21 public EisAccount(String userName, String passwd) { 22 this(); 23 this.userName = userName; 24 this.passwd = passwd; 25 } 26 public EisAccount() { 27 } 28 public EisAccount(String userName) { 29 this(userName,"123456"); 30 } 31 32 @Override 33 public String toString() { 34 return "EisAccount [userName=" + userName + ", passwd=" + passwd + "]"; 35 } 36 37 }
1 package cn.ffcs.eis.constant; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 import java.util.ResourceBundle; 6 7 import cn.ffcs.clent.HttpUtils; 8 import cn.ffcs.eis.pojo.EisAccount; 9 10 public class EisInfo { 11 12 /** 13 * 账号 14 */ 15 private static final List<EisAccount> accounts = new ArrayList<EisAccount>(); 16 17 /** 18 * 日志路径 19 */ 20 public static final String LOG_PATH = HttpUtils.nvl(ResourceBundle.getBundle("account").getString("logPath")).trim(); 21 22 public static List<EisAccount> getAccounts() { 23 return accounts; 24 } 25 26 /** 27 * 28 */ 29 public static void setAccountFromProperties(){ 30 String loginName = HttpUtils.nvl(ResourceBundle.getBundle("account").getString("loginName")).trim(); 31 loginName = loginName.replaceFirst("loginName=", ""); 32 String[] accounts = loginName.split(";"); 33 for(String s : accounts){ 34 if(s==null || s.length()==0) 35 continue; 36 if(s.indexOf("/")<0) 37 getAccounts().add(new EisAccount(s)); 38 else 39 getAccounts().add(new EisAccount(s.split("/")[0],s.split("/")[1])); 40 } 41 42 } 43 44 static{ 45 //初始化账号信息 46 // accounts.add(new EisAccount("luth")); 47 accounts.add(new EisAccount("dingyw")); 48 accounts.add(new EisAccount("zhaoshh")); 49 // accounts.add(new EisAccount("wangwm")); 50 accounts.add(new EisAccount("chenxinfei")); 51 setAccountFromProperties(); 52 } 53 54 }
1 此处省略
1 package cn.ffcs.eis; 2 3 import java.io.File; 4 import java.io.FileOutputStream; 5 import java.io.PrintStream; 6 import java.util.List; 7 import java.util.Random; 8 9 import org.apache.http.client.HttpClient; 10 11 import cn.ffcs.eis.constant.EisInfo; 12 import cn.ffcs.eis.pojo.EisAccount; 13 import cn.ffcs.eis.utils.EisDateUtils; 14 15 /** 16 * 先参考类 EisInfo,在Eclipse使用Package打包成jar,直接成可运行jar文件 17 * @author zkongbai 18 * 19 */ 20 public class TestEis { 21 22 private static List<EisAccount> accounts = EisInfo.getAccounts(); 23 24 /** 25 * 注意打卡时间 26 * @param args 27 */ 28 public static void main(String[] args) { 29 try {//重置输出流 30 System.setOut(new PrintStream(new FileOutputStream(new File(EisWorker.getSuffixName("anonymous","out","log")),true))); 31 System.setErr(new PrintStream(new FileOutputStream(new File(EisWorker.getSuffixName("anonymous","err","log")),true))); 32 } catch (Exception e2) {} 33 34 Random random = new Random(); 35 String zero = EisDateUtils.getCurDateFormatStr()+" 07:00:00"; 36 String start = EisDateUtils.getCurDateFormatStr()+" 08:30:00"; 37 String end = EisDateUtils.getCurDateFormatStr()+" 17:30:00"; 38 String endDay = EisDateUtils.getCurDateFormatStr()+" 23:59:59"; 39 40 String result = null; 41 String userName = null; 42 43 if(!EisDateUtils.isAtCertainTime(start, end, null, null))//未在打卡时间内才允许打卡 44 for(EisAccount account : accounts){ 45 try { 46 Thread.sleep(1000L*random.nextInt(5));//10s内的任意时间 47 } catch (Exception e1) {} 48 System.out.println(account); 49 userName = account.getUserName(); 50 try { 51 HttpClient client = EisWorker.login(account); 52 client = EisWorker.userWorkInfo(client,userName); 53 //下班打卡 54 if(EisDateUtils.isAtCertainTime(end, endDay, null, null)){ 55 result = EisWorker.submitOffWork(client,userName); 56 EisWorker.parseSubmitOffWork(client,result,userName); 57 } 58 //上班打卡 59 if(EisDateUtils.isAtCertainTime(zero, start, null, null)){ 60 if("".equals(EisWorker.getUserInfo_param().get("ibOn"))){//未打卡 61 result = EisWorker.submitOnWork(client); 62 EisWorker.parseSubmitOnWork(client,result,userName); 63 }else 64 System.err.println(userName+" 已打卡"); 65 } 66 67 } catch (Exception e) { 68 System.err.println(e.getMessage()); 69 e.printStackTrace(); 70 } 71 } 72 else System.out.println("当前时间:"+EisDateUtils.getCurTimeFormatStr()+" 未到正常打卡时间"); 73 } 74 75 }
顺带说句,,,使用maven可以直接打成jar包,,将所有外部依赖的jar都添加,的确很吊
在eclipse中,使用run as-> run configuration->package命令就可以,,打成的jar文件默认在target里面,使用java -jar ROOT.jar直接运行,方便吧.
做成一个bat脚本,放在开机关机程序里面,,碉堡了
还有一个配置文件,忘了说了account.properties,放在classpath路径下
1 #1,the default password is 123456.if so ,then,you can ignore the password. 2 #2,you should have a Java SE Runtime Environment,and the version should higher than 1.7.0_60 3 #3,the Computer must access to http://eis.ffcs.cn/ 4 #4,if the Operating System is linux/unix,you must modify the logPath.such as logPath=/eis/eisWork/ 5 #eg: loginName=xshh;luth;... 6 #eg: loginName=xaoshh/123456;luth/123456 7 loginName= 8 logPath=c:/eis/eisWork/