安卓开发版本不同代码不兼容,安卓原生开发java.io.FileNotFoundException:

1.这个错误在网上看到别人有好多说的,但是要不就是说,获取服务器响应的时候没有,关闭流

之类的,后来发现我自己的情况,都不是这样的.

说一下我这边的情况,因为请求的时候,后台我是用springcloud中验证是否可以请求,但是我这里不是验证的token,而是我自己设计的一种验证方式:

public static String getUserInfo(String phone,String yysId) { // 请求url String server_ip = GetConfigValue.getConfigProperties("server_ip"); //String url = "http://172.19.128.53:8080/api/mdd/user/getUserInfo"; String url = server_ip "/api/mdd/user/getUserInfo"; try { Map<String, Object> map = new HashMap<>(); map.put("cell",phone); map.put("managerId",yysId); String param = GsonUtils.toJson(map); String result = HttpUtil.post(url, "application/json", param); //String result = HttpUtil.post(url, "application/x-www-form-urlencoded", param); System.out.println(result); return result; } catch (Exception e) { e.printStackTrace(); } return null; }

安卓开发版本不同代码不兼容,安卓原生开发java.io.FileNotFoundException:(1)

上面是我发送的一个请求:

package com.baidu.idl.face.main.utils; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.Map; /** * http 工具类 */ public class HttpUtil { public static String baidupost(String requestUrl, String accessToken, String params) throws Exception { String contentType = "application/x-www-form-urlencoded"; return HttpUtil.post(requestUrl, accessToken, contentType, params); } //1.自动门店登录用 public static String post(String requestUrl, String params) throws Exception { String contentType = "application/x-www-form-urlencoded"; return HttpUtil.post(requestUrl, contentType, params); } public static String baidupost(String requestUrl, String accessToken, String contentType, String params) throws Exception { String encoding = "UTF-8"; if (requestUrl.contains("nlp")) { encoding = "GBK"; } return HttpUtil.baidupost(requestUrl, accessToken, contentType, params, encoding); } public static String post(String requestUrl, String contentType, String params) throws Exception { String encoding = "UTF-8"; if (requestUrl.contains("nlp")) { encoding = "GBK"; } return HttpUtil.post(requestUrl, contentType, params, encoding); } public static String baidupost(String requestUrl, String accessToken, String contentType, String params, String encoding) throws Exception { String url = requestUrl "?access_token=" accessToken; return HttpUtil.postGeneralUrl(url, contentType, params, encoding); } public static String post(String requestUrl, String contentType, String params, String encoding) throws Exception { String url = requestUrl; return HttpUtil.postGeneralUrl(url, contentType, params, encoding); } //1.--->这里报错的地方是在 public static synchronized String postGeneralUrl(String generalUrl, String contentType, String params, String encoding) throws Exception { URL url = new URL(generalUrl); // 打开和URL之间的连接 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); // 设置通用的请求属性 connection.setRequestProperty("Content-Type", contentType); connection.setRequestProperty("Connection", "Keep-Alive"); connection.setUseCaches(false); connection.setDoOutput(true); connection.setDoInput(true); //添加请求头部 appkey appsecret String APPKEY = "xxxxx";//自己定义的 String APPDATE =""; SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); APPDATE = dateFormat.format(new Date()); String SECRETBEFORE = APPKEY YdCommonUtils.reverseString(APPDATE) APPKEY.toUpperCase(); String APPSECRET = YdCommonUtils.getMD5Str(SECRETBEFORE); connection.setRequestProperty("appkey",APPKEY); connection.setRequestProperty("appdate",APPDATE); connection.setRequestProperty("appsecret",APPSECRET); // 得到请求的输出流对象 DataOutputStream out = new DataOutputStream(connection.getOutputStream()); out.write(params.getBytes(encoding)); out.flush(); out.close(); // 建立实际的连接 connection.connect(); // 获取所有响应头字段 Map<String, List<String>> headers = connection.getHeaderFields(); // 遍历所有的响应头字段 for (String key : headers.keySet()) { System.err.println(key "--->" headers.get(key)); } // 定义 BufferedReader输入流来读取URL的响应 BufferedReader in = null; in = new BufferedReader( new InputStreamReader(connection.getInputStream(), encoding)); String result = ""; String getLine; while ((getLine = in.readLine()) != null) { result = getLine; } in.close(); System.err.println("result:" result); return result; } }

安卓开发版本不同代码不兼容,安卓原生开发java.io.FileNotFoundException:(2)

可以看到请求是经过上面的这个工具类发出去的,但是,报错就在

// 定义 BufferedReader输入流来读取URL的响应 BufferedReader in = null; in = new BufferedReader( new InputStreamReader(connection.getInputStream(), encoding)); String result = ""; String getLine; while ((getLine = in.readLine()) != null) { result = getLine; }

安卓开发版本不同代码不兼容,安卓原生开发java.io.FileNotFoundException:(3)

上面代码的这个部分,其实就是,连接是已经连接上了,主要是读取,服务器返回数据的时候,报错了

报的错误就是:java.io.FileNotFoundException: http://172.19.128.53:8080/ 这样的情况

什么原因呢?

我们再去看看我服务器验证部分的代码,对于所有的接口,服务器端都有验证,会验证合法的接口

才会允许访问:看看服务器端的代码:

package com.company.project.core.filter; import com.company.project.core.constant.ConstantKey; import com.company.project.core.exception.TokenException; import io.jsonwebtoken.*; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.www.BasicAuthenticationFilter; import org.springframework.util.DigestUtils; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList; /** * token的校验 * 该类继承自BasicAuthenticationFilter,在doFilterInternal方法中, * 从http头的Authorization 项读取token数据,然后用Jwts包提供的方法校验token的合法性。 * 如果校验通过,就认为这是一个取得授权的合法请求 * @author LiuWenhao on 2018/05/27. */ public class AuthenticationFilter extends BasicAuthenticationFilter { private static final Logger logger = LoggerFactory.getLogger(AuthenticationFilter.class); public AuthenticationFilter(AuthenticationManager authenticationManager) { super(authenticationManager); } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { String time = request.getHeader("APPDATE"); String key = request.getHeader("APPKEY"); String md5 = request.getHeader("APPSECRET"); //兼容websocket传参 // if(header == null || header.length()==0){ // header = request.getParameter("Authorization"); // } // if (header == null || !header.startsWith("Bearer ")) { // chain.doFilter(request, response); // return; // } if(time == null || key == null|| md5 == null){ chain.doFilter(request, response); }else{ UsernamePasswordAuthenticationToken authentication = getAuthentication(request); SecurityContextHolder.getContext().setAuthentication(authentication); chain.doFilter(request, response); } } private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest request) { try{ String time = request.getHeader("APPDATE"); String key = request.getHeader("APPKEY"); String md5 = request.getHeader("APPSECRET"); String secret = key; for(int i=time.length()-1; i>=0; i--){ secret = time.charAt(i); } secret = "XXXXXX"; String cuMd5 = DigestUtils.md5DigestAsHex(secret.getBytes()); if (cuMd5.equals(md5)){ return new UsernamePasswordAuthenticationToken(cuMd5, null, new ArrayList<>()); }else{ System.out.println("cuMd5:" cuMd5 "reqMd5:" md5); } }catch (Exception e){ e.printStackTrace(); } return null; } }

安卓开发版本不同代码不兼容,安卓原生开发java.io.FileNotFoundException:(4)

可以看到上面其实就是利用的spingsecurity的filter,拦截器来进行实现的,拦截所有的请求,在请求

头部获取,来的字符串,根据自己设计的规则,去生成一个md5字符串,看看这个md5字符串和,发过来的md5字符串是否一致,就可以验证是否合法.

而这里的问题就在于:

if (cuMd5.equals(md5)){ return new UsernamePasswordAuthenticationToken(cuMd5, null, new ArrayList<>()); }else{ System.out.println("cuMd5:" cuMd5 "reqMd5:" md5); }

安卓开发版本不同代码不兼容,安卓原生开发java.io.FileNotFoundException:(5)

偶尔有时候,cuMd5,自己在后台计算的md5字符串,和发过来的md5字符串,不一样,这个时候,验证

失败,这个请求就不会放行,这个时候,就出现了上面的异常.

后来发现,因为这个cuMd5的计算是一个人做的,在android端的md5是另一个人做的,所以,

虽然都是对同样的字符串,进行md5加密,但是在android端md5加密字符串的那个人,加密出的

加密串,偶尔会首部,缺少一个字母...

public static String getMD5Str(String string) { if (StringUtils.isEmpty(string)) { return ""; } MessageDigest md5 = null; try { md5 = MessageDigest.getInstance("MD5"); byte[] bytes = md5.digest(string.getBytes()); String result = ""; for (byte b : bytes) { String temp = Integer.toHexString(b & 0xff); if (temp.length() == 1) { temp = "0" temp; } result = temp; } return result; } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; }

安卓开发版本不同代码不兼容,安卓原生开发java.io.FileNotFoundException:(6)

安卓开发版本不同代码不兼容,安卓原生开发java.io.FileNotFoundException:(7)

两遍都用上面这个加密方式的话是没问题的.

可以看到上面服务器端用的是:

secret = "XXXX"; String cuMd5 = DigestUtils.md5DigestAsHex(secret.getBytes()); 这个也是没问题的

但是之前android端用的:

public static String getMD5StrBack(String str) { byte[] digest = null; try { MessageDigest md5 = MessageDigest.getInstance("md5"); digest = md5.digest(str.getBytes("utf-8")); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } //16是表示转换为16进制数 String md5Str = new BigInteger(1, digest).toString(16); return md5Str; }

安卓开发版本不同代码不兼容,安卓原生开发java.io.FileNotFoundException:(8)

安卓开发版本不同代码不兼容,安卓原生开发java.io.FileNotFoundException:(9)

安卓开发版本不同代码不兼容,安卓原生开发java.io.FileNotFoundException:(10)

这个是有问题的.

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页