分享

rest架构+跨域访问+JWT校验

 WindySky 2017-09-17

非常感谢


一套基于前后端分离架构的企业级的商户网站。为什么要采用前后端分离技术,很简单,目的是为了让后端人员专注做服务接口设计,前端人员专注用户体验设计,不像ERP系统那样禁锢与一贯的页面风格。
项目具体采用以下技术:
服务框架: jersey+mybaties     这个框架一般用的不多,但是作为rest框架而言,与SPRING只是大同小异,但是代码的规范性更强,因为是纯粹的接口框架。
登录缓存控制: JWT           JWT曾和SESSION有过不少争议。session的原理在于由服务端保存用户的sessionid,弊端就是会占用服务器大量内存,所以在大型项目当中会借用缓存工具进行存储。JWT的方式是将用户状态分散到了各个客户端,这样减轻了服务器的压力,也可不必使用缓存来处理,因为JWT的原理是通过将用户信息进行base64编码与加密签名来识别用户身份,当然JWT当中也允许加入用户的其他身份或者角色信息。具体JWT原理各位有兴趣可以去百度。

跨域访问机制:CORS       在解决跨域问题上,遇到了很大的坑,都是浏览器的同源策略害的,也是打算这次发帖的一个重要原因。
        先来分析一下跨域请求的一些机制:目前跨域请求大概有这么几种,个人觉得利弊如下:
       1、JSONP   这个方式对于我个人而言,确实没有一点P用, 客户端都是AJAX的POST请求,然后JSONP只支持GET请求方式,所以放弃使用
        2、iframe    很久以前做前端的时候,友人就告诫我能不用iframe的时候尽量少用。毕竟商户端网站后期的改造还是比较复杂,不排除会出现什么其他的坑。
       3、proxy代理   曾考虑在跨域无法访问的情况下,做一个springMvc工程作为代理跳转,不过这样做,要同时维护两个项目,在成本上不到万不得已不提倡。
       4、cors        最终选择这种方式,是因为配置上比较简单,而网上很多帖子都是通过cors实现跨域功能,但在实际调试过程中也踩过不少坑。后面慢慢介绍。
先说坑,关键字:
1、跨域功能在服务器上无法实现(本地正常)
2、nginx配置自定义header过滤(本地正常)
3、登录过滤器问题
4、jersey文件上传带参数获取

下面我分三点把项目情况描述一下:
一、JWT用户校验
     机制是这样,用户第一次登陆系统,根据用户相关信息,生成一串BASE64编码作为用户token,返回给客户端,客户端每次请求将这个token添加到request 请求头当中,系统过滤器通过对token的校验来验证用户是否合法。这里面存在两个问题:1、用户注销系统如何操作   2、token在请求头当中如何传输。直接看代码:
      (一)、jar包引用:
        <dependency>
              <groupId>io.jsonwebtoken</groupId>
              <artifactId>jjwt</artifactId>
              <version>0.6.0</version>
        </dependency>
      (二)、登录方法:

  1. @POST  
  2.     @Path("/loginUser")  
  3.     @Produces(MediaType.APPLICATION_JSON)  
  4.     @Consumes(MediaType.APPLICATION_JSON)  
  5.     public Response loginUser(String resquestJsonBody,@Context HttpServletRequest request)  
  6.     {  
  7.         logger.info(String.format("Request IP--%s;requestJsonBody--%s", IpUtils.getIpAddr(request), resquestJsonBody));  
  8.         ZyLoginResponseVo zyLoginResponseVo = new ZyLoginResponseVo();  
  9.         String jsonRequestStr = RequestUtils.str2Json(resquestJsonBody);  
  10.         ZyLoginRequestVo zyLoginRequestVo = JSONObject.parseObject(jsonRequestStr, ZyLoginRequestVo.class);  
  11.         Map<String,Object> loginResult = zyLoginApiService.loginByUserName(zyLoginRequestVo);  
  12.         int code = Integer.parseInt(String.valueOf(loginResult.get("loginCode")));  
  13.         if (loginResult.get("loginCode").equals(Constants.AUTH_RESULT_SUCCESS))  
  14.         {  
  15.                 //查询用户信息  
  16.                ZyUserDto resultDto= zyLoginApiService.findUserByName(zyLoginRequestVo.getUser_name());  
  17.                if(null == resultDto){  
  18.                    //用户不存在  
  19.                 zyLoginResponseVo.setCode(code);  
  20.                 zyLoginResponseVo.setDesc("User is not exists!!");  
  21.                 logger.info("The responseJsonObject:" + JSONObject.toJSONString(zyLoginResponseVo));  
  22.                 return Response.status(200).entity(JSONObject.toJSONString(zyLoginResponseVo)).type(new MediaType(CommonStr.APPLICATION, CommonStr.JSON, CommonStr.UTF8)).build();  
  23.                }  
  24.                //组装缓存数据  
  25.                String userName = String.valueOf(loginResult.get("userName"));  
  26.                String mobilePhone = String.valueOf(loginResult.get("mobilePhone"));  
  27.                Map<String,Object> claims = new HashMap<String,Object>();  
  28.                claims.put("acessToken", loginResult.get("accessToken"));  
  29.                claims.put("companyname", resultDto.getCompanyname());  
  30.                if(StringUtils.isEmpty(userName)){  
  31.                claims.put("name", resultDto.getUsername());  
  32.                }else{  
  33.                    claims.put("name", userName);  
  34.                }  
  35.                if(StringUtils.isEmpty(mobilePhone)){  
  36.                    claims.put("phone", resultDto.getPhone());  
  37.                }else{  
  38.                    claims.put("phone", mobilePhone);  
  39.                }  
  40.                claims.put("status", resultDto.getStatus());  
  41.                claims.put("companykey", resultDto.getCompanykey());  
  42.                claims.put("companyid", resultDto.getCompanyid());  
  43.                claims.put("id", resultDto.getId());  
  44.             // 设置这个token的生命时间  
  45.             Date expiry = getExpiryDate(30 * 24 * 60);//30天的有效日期  
  46.             // 使用Token工具类得到token,生成的策略是利用用户的姓名,到期时间,和私钥  
  47.             // 使用Key key =MacProvider.generateKey(SignatureAlgorithm.HS512);  
  48.             // HS512签名算法,必须保存生成的这个key到硬盘上,不然下次会出错,因为是hash算法,所以会变  
  49.             String userToken = TokenUtil.getJWTString(zyLoginRequestVo.getUser_name(), expiry,KeyUtil.getKey(context),resultDto.getCompanyid(),claims);  
  50.             logger.info("login Success, Token is:" + userToken+"; user is :"+userName);  
  51.             System.err.println("token is :"+userToken);  
  52.             zyLoginResponseVo.setCode(code);  
  53.             zyLoginResponseVo.createInstanceData().setToken(userToken);  
  54.             zyLoginResponseVo.setDesc("登录成功!");  
  55.         }else{  
  56.             String desc = ResultCodeDescUtil.getResultDesc(code);  
  57.             zyLoginResponseVo.setCode(code);  
  58.             zyLoginResponseVo.setDesc(desc);  
  59.         }  
  60.         logger.info("The responseJsonObject:" + JSONObject.toJSONString(zyLoginResponseVo));  
  61.         return Response.status(200).entity(JSONObject.toJSONString(zyLoginResponseVo)).type(new MediaType(CommonStr.APPLICATION, CommonStr.JSON, CommonStr.UTF8)).build();  
  62.     }  

(一)、TOKEN 工具类
包含创建token,获取token附带信息。这里是把key文件保存在了项目当中,这个key文件只能生成一次,用户验证是通过这个key文件来处理,实际上是一串序列化的字符串。也可以改造成放入到数据库当中。

  1. package ichano.developer.util;/** 
  2. import io.jsonwebtoken.Claims; 
  3. import io.jsonwebtoken.Jws; 
  4. import io.jsonwebtoken.Jwts; 
  5. import io.jsonwebtoken.SignatureAlgorithm; 
  6. import java.security.Key; 
  7. import java.util.Date; 
  8. import java.util.Map; 
  9. import javax.annotation.security.PermitAll; 
  10. /**  
  11. * @ClassName: TokenUtil  
  12. * @Description: TODO(token管理工具类)  
  13. * @author lizhijun 
  14. * @date 2016年8月11日 下午12:57:44  
  15. *   
  16. */  
  17. @PermitAll  
  18. public class TokenUtil {  
  19.     public static String getJWTString(String tel,Date expires,Key key,String commpanyId,Map<String,Object> claims){  
  20.         if (tel == null) {  
  21.             throw new NullPointerException("null username is illegal");  
  22.         }  
  23.         if (expires == null) {  
  24.             throw new NullPointerException("null expires is illegal");  
  25.         }  
  26.         if (key == null) {  
  27.             throw new NullPointerException("null key is illegal");  
  28.         }  
  29.         SignatureAlgorithm signatureAlgorithm =SignatureAlgorithm.HS256;  
  30.         String jwtString = Jwts.builder()  
  31.                 .setIssuer("Jersey-Security-Basic")  
  32.                 .setSubject(tel)  
  33.                 .setAudience("user")  
  34.                 .setExpiration(expires)  
  35.                 .setClaims(claims)  
  36.                 .setIssuedAt(new Date())  
  37.                 .setId(commpanyId)  
  38.                 .signWith(signatureAlgorithm,key)  
  39.                 .compact();  
  40.         return jwtString;  
  41.     }  
  42.     public static boolean isValid(String token, Key key) {  
  43.         try {  
  44.             Jwts.parser().setSigningKey(key).parseClaimsJws(token.trim());  
  45.             return true;  
  46.         } catch (Exception e) {  
  47.             return false;  
  48.         }  
  49.     }  
  50.     public static String getName(String jwsToken, Key key) {  
  51.         if (isValid(jwsToken, key)) {  
  52.             Jws<Claims> claimsJws = Jwts.parser().setSigningKey(key).parseClaimsJws(jwsToken);  
  53.             String name = String.valueOf(claimsJws.getBody().get("name"));  
  54.             return name;  
  55.         }  
  56.         return null;  
  57.     }  
  58.     public static String[] getRoles(String jwsToken, Key key) {  
  59.         if (isValid(jwsToken, key)) {  
  60.             Jws<Claims> claimsJws = Jwts.parser().setSigningKey(key).parseClaimsJws(jwsToken);  
  61.             return claimsJws.getBody().getAudience().split(",");  
  62.         }  
  63.         return new String[]{};  
  64.     }  
  65.     public static int getVersion(String jwsToken, Key key) {  
  66.         if (isValid(jwsToken, key)) {  
  67.             Jws<Claims> claimsJws = Jwts.parser().setSigningKey(key).parseClaimsJws(jwsToken);  
  68.             return Integer.parseInt(claimsJws.getBody().getId());  
  69.         }  
  70.         return -1;  
  71.     }  
  72.     /**  
  73.     * @Title: getCompanyId  
  74.     * @Description: TODO(获取企业ID)  
  75.     * @param @param jwsToken 
  76.     * @param @param key 
  77.     * @param @return    设定文件  
  78.     * @return String    返回类型  
  79.     * @throws  
  80.     */  
  81.     public static String getCompanyId(String jwsToken, Key key) {  
  82.         if (isValid(jwsToken, key)) {  
  83.             Jws<Claims> claimsJws = Jwts.parser().setSigningKey(key).parseClaimsJws(jwsToken);  
  84.             String companyid = String.valueOf(claimsJws.getBody().get("id"));  
  85.           return companyid;  
  86.         }  
  87.         return null;  
  88.     }  
  89.     /**  
  90.     * @Title: setAcccessToken  
  91.     * @Description: TODO(存放鉴权中心token)  
  92.     * @param @param accessToken 
  93.     * @param @param key 
  94.     * @param @return    设定文件  
  95.     * @return String    返回类型  
  96.     * @throws  
  97.     */  
  98.     public static void setAcccessToken(String authToken, Key key,String accessToken) {  
  99.         if (isValid(authToken, key)) {  
  100.             Jws<Claims> claimsJws = Jwts.parser().setSigningKey(key).parseClaimsJws(authToken);  
  101.             claimsJws.getBody().put("acessToken", accessToken);  
  102.         }  
  103.     }  
  104.     /**  
  105.     * @Title: getCompanyId  
  106.     * @Description: TODO(获取鉴权中心Token)  
  107.     * @param @param jwsToken 
  108.     * @param @param key 
  109.     * @param @return    设定文件  
  110.     * @return String    返回类型  
  111.     * @throws  
  112.     */  
  113.     public static String getAccessToken(String jwsToken, Key key) {  
  114.         if (isValid(jwsToken, key)) {  
  115.             Jws<Claims> claimsJws = Jwts.parser().setSigningKey(key).parseClaimsJws(jwsToken);  
  116.             return claimsJws.getBody().getSubject();  
  117.         }  
  118.         return null;  
  119.     }  
  120. }  


(四)、过滤器处理
在过滤器当中需要添加一些不需要进行token校验的请求路径,可以直接访问。 在这里没有角色权限的校验,有需要的可以自行设计。

  1. package ichano.developer.sys.filter;/** 
  2. import ichano.developer.biz.service.ZyLoginService; 
  3. import ichano.developer.dto.ZyUserDto; 
  4. import ichano.developer.util.KeyUtil; 
  5. import ichano.developer.util.TokenUtil; 
  6. import java.io.IOException; 
  7. import java.security.Key; 
  8. import javax.annotation.Priority; 
  9. import javax.inject.Inject; 
  10. import javax.servlet.ServletContext; 
  11. import javax.ws.rs.Priorities; 
  12. import javax.ws.rs.WebApplicationException; 
  13. import javax.ws.rs.container.ContainerRequestContext; 
  14. import javax.ws.rs.container.ContainerRequestFilter; 
  15. import javax.ws.rs.container.PreMatching; 
  16. import javax.ws.rs.core.Context; 
  17. import javax.ws.rs.core.MultivaluedMap; 
  18. import javax.ws.rs.core.Response; 
  19. import javax.ws.rs.core.UriInfo; 
  20. import javax.ws.rs.ext.Provider; 
  21. import org.apache.log4j.LogManager; 
  22. import org.apache.log4j.Logger; 
  23. import org.glassfish.jersey.server.ContainerRequest; 
  24. import org.springframework.beans.factory.annotation.Autowired; 
  25. /**  
  26. * @ClassName: JWTSecurityFilter  
  27. * @Description: TODO(权限验证过滤器)  
  28. * @author lizhijun 
  29. * @date 2016年8月11日 下午1:18:52  
  30. *   
  31. */  
  32. @Provider  
  33. @Priority(Priorities.AUTHENTICATION)//优先级最高  
  34. //实现该拦截器借口  
  35. //@Provider可以自动注册  
  36. @PreMatching         //这个必须添加,否则无法拦截请求  
  37. public class JWTSecurityFilter implements ContainerRequestFilter{  
  38.     final static Logger logger = LogManager.getLogger(JWTSecurityFilter.class.getName());  
  39.     @Autowired  
  40.     ZyLoginService zyLoginService;  
  41.    
  42.     @Context  
  43.     ServletContext context;  
  44.    
  45.     @Inject  
  46.     javax.inject.Provider<UriInfo> uriInfo;  
  47.     public static String extractJwtTokenFromAuthorizationHeader(String auth) {  
  48.         //Replacing "Bearer Token" to "Token" directly  
  49.         return auth.replaceFirst("[B|b][E|e][A|a][R|r][E|e][R|r] ", "").replace(" ", "");  
  50.     }  
  51.   //重写验证过滤器  
  52.     @Override  
  53.     public void filter(ContainerRequestContext containerRequestContext) throws IOException {  
  54.         //获取本地的私钥  
  55.         Key key= KeyUtil.getKey(context);  
  56.         //得到访问的方法 例如GET,POST  
  57.         String method = containerRequestContext.getMethod().toLowerCase();  
  58.         //预校验请求处理  
  59.         if(method.equals("options")){  
  60.             containerRequestContext.setSecurityContext(new SecurityContextAuthorizer(uriInfo,new AuthorPricinple("pass"), new String[]{"pass"}));  
  61.             return;  
  62.         }  
  63.         //得到访问路径  
  64.         String path = ((ContainerRequest) containerRequestContext).getPath(true).toLowerCase();  
  65.    
  66.         System.err.println("authorizationHeader path is :"+path);  
  67.         //不需要验证,post验证过滤,注册过滤。  
  68.         if ("post".equals(method) && "developer/loginuser".equals(path)  
  69.                 || "developer/registeruser".equals(path)  
  70.                 || "developer/sendverifcode".equals(path)  
  71.                 || "developer/updatepwd".equals(path)   
  72.                 ||"license/uploadfilecheck".equals(path)  
  73.                 ||"product/uploadproductimg".equals(path)) {  
  74.             containerRequestContext.setSecurityContext(new SecurityContextAuthorizer(uriInfo,new AuthorPricinple("pass"), new String[]{"pass"}));  
  75.             return;  
  76.         }  
  77.         //获取头信息中的token  
  78.         MultivaluedMap<String, String> testToken = ((ContainerRequest) containerRequestContext).getHeaders();  
  79.         String authorizationHeader = ((ContainerRequest) containerRequestContext).getHeaderString("auth_token");  
  80.         //如果token为空抛出  
  81.         if (authorizationHeader == null) {  
  82.             throw new WebApplicationException(Response.Status.UNAUTHORIZED);//抛出未认证的错误  
  83.         }  
  84.         //把Bear Token换成Token  
  85.         String strToken=extractJwtTokenFromAuthorizationHeader(authorizationHeader);  
  86.         if (TokenUtil.isValid(strToken,key)){  
  87.             String name=TokenUtil.getName(strToken,key);//反解出Name  
  88. //            String[] roles=TokenUtil.getRoles(strToken,key);//反解出角色  
  89.             if(name !=null){  
  90.                 ZyUserDto user=zyLoginService.findUserByName(name);  
  91.                 if(user!=null){  
  92.                     containerRequestContext.setSecurityContext(new SecurityContextAuthorizer(uriInfo,new AuthorPricinple(name), new String[]{"user"}));  
  93.                     return;  
  94.                 }  
  95.                 else{  
  96.                     logger.info("User not found " + name);  
  97.                 }  
  98.             }  
  99.             else {  
  100.                 logger.info("name, roles or version missing from token");  
  101.             }  
  102.         }  
  103.         else {  
  104.             logger.info("token is invalid");  
  105.         }  
  106.         throw new WebApplicationException(Response.Status.UNAUTHORIZED);  
  107.     }  
  108. }  

(五)、前端请求代码
采用ajax post请求方式。
 // 发送登陆请求

  1. $.ajax({  
  2.                 url: "http://192.168.0.55:8080/developer/developer/loginUser",  
  3.                 type: "POST",  
  4.                 dataType: "json",  
  5.                 contentType: "application/json",      <span style="color: #FF0000;">    //注意:如果有post data参数的时候,必须加这段,否则请求获取不到参数</span>        
  6.                 data: {  
  7.                     user_name: userName,  
  8.                     password: userPwd,  
  9.                     type: type  
  10.                 },  
  11.                 success: function(data) {  
  12.                     console.log(data);  
  13.                     if (data.code == 1000) {  
  14.                         $.cookie('token', data.data.token);  
  15.                         console.log(1);  
  16.                         parent.location.reload();  
  17.                     } else if (data.code == 2006) {  
  18.                         layer.msg("用户名密码错误");  
  19.                     } else {  
  20.                         layer.msg("登陆异常");  
  21.                     }  
  22.                 }  
  23.             });  

//访问接口请求

  1. $.ajax({  
  2.            url: "http://192.168.0.181:9102/developer/developer/checkLogin",  
  3.            type: 'POST',  
  4.            dataType: 'json',  
  5.            beforeSend: function(request) {                       //添加请求响应头中的自定义token  
  6.                request.setRequestHeader("auth_token", token);  
  7.            },  
  8.            success: function(data) {  
  9.                if (data.code == 1000) {  
  10.                    var html = [];  
  11.                    html.push(Mustache.render(userNameTemp, data.data));  
  12.                    $userNameCon.html(html.join(''));  
  13.                } else {  
  14.                    window.location.href = "index.html"  
  15.                }  
  16.            }  
  17.        })  
二、CORS跨域访问     
        使用cors进行跨域配置其实很简单,只需要引用jar包,然后添加过滤器即可。但是有些细节还是要注意。
       (一)、jar包引用
         <dependency>
            <groupId>com.thetransactioncompany</groupId>
            <artifactId>cors-filter</artifactId>
            <version>2.5</version>
        </dependency>

        <!-- https:///artifact/com.thetransactioncompany/java-property-utils -->
        <dependency>
            <groupId>com.thetransactioncompany</groupId>
            <artifactId>java-property-utils</artifactId>
            <version>1.9.1</version>
        </dependency>
(二)、过滤器实现
         web.xml配置:

  1. <filter>  
  2.    <filter-name>cros</filter-name>  
  3.    <filter-class>ichano.developer.sys.filter.CorsFilter</filter-class>  
  4.  </filter>  
  5.  <filter-mapping>  
  6.    <filter-name>cros</filter-name>  
  7.    <url-pattern>/*</url-pattern>  
  8.  </filter-mapping>  
过滤器中可以配置允许访问的请求方,允许访问的请求方式以及允许通过的请求头信息

  1. package ichano.developer.sys.filter;/** 
  2. import java.io.IOException; 
  3. import javax.servlet.FilterChain; 
  4. import javax.servlet.ServletException; 
  5. import javax.servlet.http.HttpServletRequest; 
  6. import javax.servlet.http.HttpServletResponse; 
  7. import org.springframework.web.filter.OncePerRequestFilter; 
  8. /**  
  9. * @ClassName: CorsFilter  
  10. * @Description: TODO(设置其他IP地址的机器可以直接访问本项目Url--工具filter)  
  11. * @author lizhijun 
  12. * @date 2016年8月15日 下午2:25:25  
  13. *   
  14. */  
  15. public class CorsFilter extends OncePerRequestFilter {  
  16.     @Override  
  17.     protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {  
  18.         response.addHeader("Access-Control-Allow-Origin", "*");      //为安全起见,可配置允许访问的请求方地址。这里配置成*号,是允许所有访问。  
  19.         response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");        //为安全起见,也可配置成只允许POST请求  
  20.         response.addHeader("Access-Control-Allow-Headers", "Content-Type,auth_token");      //这里要注意,auth_token是我自定义的请求头当中带的token,在这里必须添加,否则你永远获取不到。  
  21.         response.addHeader("Access-Control-Max-Age", "1800");//30 min  
  22.         filterChain.doFilter(request, response);  
  23.     }  
  24. }  

这里处理了三个坑,
一是在本地调试的时候可以跨域访问,但是部署到服务器之后,访问失败。解决方法:请求地址后面加上端口号就可以访问。  这个问题就需要在nignx里面进行端口配置。
二是CROS这种传输方式传输的数据到后端接收已不是JSON格式,而是类似于XXX=123&FFFF=384这样的格式,需要对所有请求的入参进行一下转换成json格式。
三是请求头中的自定义字段auth_token在服务器上接收不到,这里需要对ngnix进行配置,允许自定义属性的header配置。
[b]


三、补充点   jersey框架文件上传方式,包含带有参数上传[/b]
       通过form表单提交方式进行图片上传
     (一)、页面

  1. <div class="header" style="background-color:#14C2FF;width:400px,height:800px; border:1px red solid;">  
  2.             <form action="http://localhost:8080/ichanoDeveloper/product/uploadProductImg" method="post" enctype="multipart/form-data">    
  3.                 <p>    
  4.                                      <input type="file"  class="sys_input"     name ="productLogo"  id="productLogo"   />  
  5.                         剩productId:<input type="text" name="productId" value="20" id="productId"/><br />    
  6.                 </p>    
  7.                 <input type="submit" value="上传" />    
  8.           </form>   
  9.         </div>  
(二)处理代码

  1.          /**  
  2.     * @Title: uploadFileCheck  
  3.     * @Description: TODO(这里用一句话描述这个方法的作用)  
  4.     * @param @param fileInputStream 
  5.     * @param @param disposition 
  6.     * @param @param request 
  7.     * @param @return    设定文件  
  8.     * @return String    返回类型  
  9.     * @throws  
  10.     */  
  11.     @POST  
  12.     @Path("/uploadFileCheck")  
  13.     @Consumes(MediaType.MULTIPART_FORM_DATA)  
  14.     @Produces(MediaType.TEXT_PLAIN)  
  15.     public Response uploadTemp( @FormDataParam("updateLicense") final InputStream uploadedInputStream,  
  16.             @FormDataParam("updateLicense") final FormDataContentDisposition fileDetail,  
  17.             @FormDataParam( "surplusCount") final List<FormDataBodyPart> keywordObjs,@Context HttpServletRequest request ) {  
  18.         String fileName = Calendar.getInstance().getTimeInMillis()+ fileDetail.getFileName();    
  19.         ZyUploadLicenseFileResponseVo zyUploadLicenseFileResponseVo = new ZyUploadLicenseFileResponseVo();  
  20.         ZyUploadLicenseFileRequestVo zyUploadLicenseFileRequestVo = new ZyUploadLicenseFileRequestVo();  
  21.         if (keywordObjs != null && ! keywordObjs.isEmpty()) {  
  22.            for (FormDataBodyPart keywordObj : keywordObjs) {  
  23.                String keyName = keywordObj.getName();  
  24.                if("surplusCount".equals(keyName)){  
  25.                    zyUploadLicenseFileRequestVo.setSurplusCount(keywordObj.getValueAs(String.class));  
  26.                    break;  
  27.                }  
  28.            }  
  29.         }  
  30.         String accessToken = TokenUtil.getAccessToken(request.getHeader("auth_token"),KeyUtil.getKey(context));  
  31.         Key key= KeyUtil.getKey(context);  
  32.         if (TokenUtil.isValid(accessToken,key)){  
  33.             zyUploadLicenseFileRequestVo.setInputStream(uploadedInputStream);  
  34.             zyUploadLicenseFileRequestVo.setFileName(fileName);  
  35.             zyUploadLicenseFileResponseVo= zyLicenseApiService.uploadBatchExcel(zyUploadLicenseFileRequestVo);  
  36.         }else{  
  37.             zyUploadLicenseFileResponseVo.setCode(Constants.AUTH_RESULT_FILE_SESSIONOUT);  
  38.             zyUploadLicenseFileResponseVo.setDesc("Session is out!");  
  39.         }  
  40.         logger.info("The responseJsonObject:" + JSONObject.toJSONString(zyUploadLicenseFileResponseVo));  
  41.         return Response.status(200).entity(JSONObject.toJSONString(zyUploadLicenseFileResponseVo)).type(new MediaType(CommonStr.APPLICATION, CommonStr.JSON, CommonStr.UTF8)).build();  
  42.     }  
  43.    
  44.    
  45.    
  46. @Override  
  47.     public ZyUploadLicenseFileResponseVo uploadBatchExcel(ZyUploadLicenseFileRequestVo zyUploadLicenseFileRequestVo) {  
  48.         ZyUploadLicenseFileResponseVo zyUploadLicenseFileResponseVo = new ZyUploadLicenseFileResponseVo();  
  49. //  参数有误  
  50.         if (!zyUploadLicenseFileRequestVo.isValid()) {  
  51.                 logger.error("The argument is null!");  
  52.                 zyUploadLicenseFileResponseVo.setCode(Constants.AUTH_RESULT_FILE_2001);  
  53.                 zyUploadLicenseFileResponseVo.setDesc("The argument is invalid!!");  
  54.                 return zyUploadLicenseFileResponseVo;  
  55.         }  
  56.         String fileName = zyUploadLicenseFileRequestVo.getFileName();  
  57.         List licenseInfo = new ArrayList<String>();  
  58.         if(!fileName.contains("xls")){  
  59.             logger.error("The fileName[{}]  is error!", fileName);  
  60.             zyUploadLicenseFileResponseVo.setCode(Constants.UPLOAD_FAILE_9002);  
  61.             zyUploadLicenseFileResponseVo.setDesc("The file fomart is faile!!");  
  62.             return zyUploadLicenseFileResponseVo;  
  63.         }  
  64.         try {  
  65.             workbook = new XSSFWorkbook(zyUploadLicenseFileRequestVo.getInputStream());  
  66.             XSSFSheet sheet = workbook.getSheetAt(0);   //获取第一个sheet  
  67.             int rows = sheet.getPhysicalNumberOfRows();//行数  
  68.             int cols = sheet.getRow(1).getPhysicalNumberOfCells();//列数  
  69.             if(cols != 2){  
  70.                 logger.error("The file fomart is faile!");  
  71.                 zyUploadLicenseFileResponseVo.setCode(Constants.UPLOAD_FAILE_9002);  
  72.                 zyUploadLicenseFileResponseVo.setDesc("文件格式错误!!");  
  73.                 return zyUploadLicenseFileResponseVo;  
  74.             }  
  75.             //校验上传的excel是否为标准模版  
  76.             if(rows>0){  
  77.                 //有数据  
  78.                 for(int i=3;i<rows;i++){  
  79.                     //从第四行开始检索  
  80.                     String tempLicense = String.valueOf(sheet.getRow(i).getCell(1));  
  81.                     if(tempLicense.length()<=32){  
  82.                         licenseInfo.add(tempLicense);  
  83.                     }  
  84.                 }  
  85.             }  
  86.             int surplusLicenseInt = Integer.parseInt(zyUploadLicenseFileRequestVo.getSurplusCount());  
  87.             zyUploadLicenseFileResponseVo.setCode(Constants.AUTH_RESULT_SUCCESS);  
  88.             zyUploadLicenseFileResponseVo.setDesc("Upload File Success!");  
  89.             zyUploadLicenseFileResponseVo.createInstanceData().setLicenseList(licenseInfo);  
  90.             return zyUploadLicenseFileResponseVo;  
  91.         } catch (IOException e) {  
  92.             e.printStackTrace();  
  93.             logger.error("解析上传文件失败!");  
  94.             zyUploadLicenseFileResponseVo.setCode(Constants.UPLOAD_FAILE_9002);  
  95.             zyUploadLicenseFileResponseVo.setDesc("解析上传文件失败!");  
  96.             return zyUploadLicenseFileResponseVo;  
  97.         }   
  98.     }  


       






    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多