使用java反射机制遇到的问题

在一个项目中,写外部调用接口的时候,需要使用到Java的反射机制,在使用中发现了反射机制中的一个问题,记录一下,避免再次踩坑。

上代码:

  1 /**
  2  * 用于外部接口调用
  3  * @author 
  4  *
  5  */
  6 public class HttpLinkServlet extends HttpServlet {
  7 
  8     /**
  9      * 
 10      */
 11     private static final long serialVersionUID = -8408900345034346763L;
 12     
 13     private final static String XML_SERVICE_PATH = "Service";
 14     private final static String XML_SERVICE_NAME = "name";
 15     private final static String XML_SERVICE_CLASS = "class";
 16     private final static String XML_SEPARATOR = "_";
 17     private final static String XML_METHOD_PATH = "Method";
 18     private final static String XML_METHOD_CODE = "code";
 19     private Map<String,WSBean> serviceMap = new HashMap<String,WSBean>();
 20     private Map<String,String> methodMap = new HashMap<String,String>();
 21 
 22     private String wsfile = "/ws/ws.xml";
 23     
 24     private Logger log = Logger.getLogger(getClass());
 25     
 26     @Override
 27     public void init() throws ServletException {
 28         super.init();
 29         //读取配置文件
 30         File file = new File(this.getClass().getResource(wsfile).getPath());
 31         XMLHandler xmlHandler = new XMLHandler(file,"UTF-8");
 32         Element rootElement = xmlHandler.getRootElement();
 33         List<?> xList = rootElement.elements(XML_SERVICE_PATH);
 34         //放入ws map文件;
 35         for (Object serviceObj :xList) {// 获取所有对外公布的service
 36             Element serviceElement = (Element) serviceObj;
 37             String serviceName = serviceElement.attributeValue(XML_SERVICE_NAME);
 38             if (serviceName == null || serviceName.equals("")) {
 39                 throw new RuntimeException("Invalid bean definition in " + wsfile + ".");
 40             } else if (serviceMap.get(serviceName) != null) {
 41                 throw new RuntimeException("Duplicate webservice beans definition : " + serviceName + ".");
 42             }
 43             String className = serviceElement.attributeValue(XML_SERVICE_CLASS);
 44             if (className == null || className.trim().equals("")) {
 45                 return;
 46             }
 47             WSBean beanDef = new WSBean();
 48             beanDef.setName(serviceName);
 49             beanDef.setClassName(className);
 50             serviceMap.put(serviceName, beanDef);
 51             // 将方法对应的方法放入methodMap中
 52             for (Object methodObj :serviceElement.elements(XML_METHOD_PATH)) {
 53                 Element methodElement = (Element) methodObj;
 54                 String methodCode = methodElement.attributeValue(XML_METHOD_CODE);
 55             }
 56         }
 57     }
 58     
 59     
 60     @Override
 61     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
 62             throws ServletException, IOException {
 63         doPost(req, resp);
 64     }
 65 
 66     @Override
 67     protected void doPost(HttpServletRequest req, HttpServletResponse resp)
 68             throws ServletException, IOException {
 69         System.out.println("======欢迎调用servlet======"+req.getRequestURI() + ":" +req.getContextPath());
 70         String reqPath = req.getRequestURI();
 71         reqPath = reqPath.substring(reqPath.lastIndexOf("/")+1);
 72         String userId = req.getHeader("userId");
 73         String password = req.getHeader("password");
 74         String appVersion = req.getHeader("appVersion");
 75         String contentType = req.getHeader("Content-type");
 76         String acceptEncoding = req.getHeader("accept-encoding");
 77         String token = req.getHeader("token");
 78         String sessionId = req.getHeader("easycare.session.id");
 79         String clientIMEI = req.getHeader("client-IMEI");
 80         String clientType = req.getHeader("Client-Type");
 81         
 82         List<Dict> label = DictUtils.getDictList("apk_version");
 83         
 84         if (!"loginService".equals(reqPath) && StringUtils.isNotBlank(userId)) {
 85             // FIXME:如果包含用户id,且无登录者信息,重新登录
 86             Principal p = UserUtils.getPrincipal();
 87             if (p == null) {
 88                 UserDao userDao = SpringContextHolder.getBean(UserDao.class);
 89                 User u = userDao.get(userId);
 90                 String host = StringUtils.getRemoteAddr(req);
 91                 Subject subject = SecurityUtils.getSubject();
 92                 UsernamePasswordToken shiroToken = new UsernamePasswordToken(u.getLoginName(), 
 93                         password.toCharArray(), false, host, null, true);
 94                 subject.login(shiroToken);
 95             }
 96         }
 97 
 98         ReturnBO returnBO = new ReturnBO();
 99         try {
100             String reqJson = acceptJSON(req);//得到requestContext
101             RequestBO requestBO = (RequestBO)JsonMapper.fromJsonString(reqJson, RequestBO.class);
102 //            JSONObject jsonObj = JSONObject.parseObject(reqJson);//转换成JSONObject
103             if (requestBO == null) {
104                 returnBO.setResultStr("请求参数为空,请联系管理员! ");
105             } else {
106                 String action = requestBO.getAction();// 请求方法
107                 if(StringUtils.isNotBlank(action)){
108                     if(methodMap.keySet()!=null&&methodMap.keySet().size()>0){
109                         if(methodMap.keySet().contains(reqPath + XML_SEPARATOR + action)){
110                             String beanName = methodMap.get(reqPath + XML_SEPARATOR + action);
111                             if (beanName != null && !beanName.trim().equals("")) {
112                                 WSBean wsBean =((WSBean)serviceMap.get(beanName));
113                                 Object bean=SpringContextHolder.getBean(wsBean.getName());
114                                 
115                                 if (bean != null) {
116                                     @SuppressWarnings("rawtypes")
117                                     Class clazz = bean.getClass();
118                                     // 遍历所有方法
119                                     // 获取方法
120                                     Method[] allMethods = clazz.getMethods();
121                                     Method method = null;
122                                     for (Method _method : allMethods) {
123                                         if (_method.getName().equals(action)) {
124                                             method = _method;
125                                             break;
126                                         }
127                                     }
128                                     if (null == method) {
129                                         throw new RuntimeException("【"+ clazz.getName() + "】中不存在方法:【" + action +"】");
130                                     }
131                                     // 参数转换,将json转化为对象
132                                     Object[] parameter = null;
133                                     Class<?>[] parameterTypes = method.getParameterTypes();
134                                     Class<?> methodParameterType = null;
135                                     if (null != parameterTypes && parameterTypes.length > 0) {
136                                         parameter = new Object[parameterTypes.length];
137                                         //解决乱码问题
138                                         String data = new String(requestBO.getParam().getBytes("UTF-8"),"UTF-8");
139                                         JSONArray dataArray = JSONArray.parseArray(data);
140                                         for (int i = 0; i < parameterTypes.length; i++) {
141                                             methodParameterType = parameterTypes[i];
142                                             JSONObject tmpObj = dataArray.getJSONObject(i);
143                                             parameter[i] = JSONUtils.toBean(tmpObj.toJSONString(), methodParameterType);
144                                         }
145                                     }
146                                     // 方法调用
147                                     Object returnObj = null;
148                                     if (null != methodParameterType) {// 参数不为空时
149                                         returnObj = ReflectionUtils.invokeMethod(method, bean, parameter);
150                                     } else {
151                                         returnObj = method.invoke(bean);
152                                     }
153                                     returnBO.setFlag(Global.TRUE);
154                                     returnBO.setResultStr(JsonMapper.toJsonString(returnObj));
155                                 }
156                             }
157                         } else {
158                             returnBO.setResultStr("action【 "+action+"】服务已停止,请联系管理员! ");
159                         }
160                     }
161                 } else {
162                     returnBO.setResultStr("action 参数为空,请联系管理员!");
163                 }
164             }
165             
166         } catch (Exception e) {
167             returnBO.setResultStr(e.getMessage());
168             log.error(e.getMessage());
169         }
170         log.info("return json: "+JsonMapper.toJsonString(returnBO));
171         // 输出返回JSON字符串
172         resp.reset();
173         resp.setContentType("application/json");
174         resp.setCharacterEncoding("UTF-8");
175         resp.getWriter().println(JsonMapper.toJsonString(returnBO));
176         resp.addIntHeader("result-code", returnBO.getResultCode());
177         resp.setHeader("apkVesion", label.get(0).getValue());
178     }
179 
180     /**
181      * 接收客户端Json参数
182      * @param request
183      * @return
184      */
185     public String acceptJSON(HttpServletRequest request) {
186         String acceptjson = "";
187         try {
188             BufferedReader br = new BufferedReader(
189                     new InputStreamReader((ServletInputStream) request.getInputStream(), "utf-8"));
190             StringBuffer sb = new StringBuffer("");
191             String temp;
192             while ((temp = br.readLine()) != null) {
193                 sb.append(temp);
194             }
195             br.close();
196             acceptjson = sb.toString();
197             System.out.println(acceptjson);
198         } catch (Exception e) {
199             e.printStackTrace();
200         }
201         return acceptjson;
202     }
203     
204 }

在标红处,一直得不到正确的参数类型,要么是一个Object,要嘛是其他类型的参数。

原因是:因为我要获得的参数是个对象,而这个对象A又继承了另一个对象B,另一个对象B又继承于另一个对象C,这样的话,你得到的参数类型应该会出现4种(Object、A、B、C)

解决方法是:在写一个方法去调用原方法(相当于写一个接口),明确参数的类型

例:

1 public List<Leasecredit> findList(Leasecredit leasecredit) {
2         //加入过滤数据范围
3         leasecredit.getSqlMap().put("dsf", dataScopeFilter(UserUtils.getUser(), "o", "u"));
4         return super.findList(leasecredit);
5     }
6     
7     public List<Leasecredit> findListInterface(Leasecredit leasecredit) {
8         return findList(leasecredit);
9     }

 

posted @ 2018-01-10 10:04  hongqingfu  阅读(885)  评论(0编辑  收藏  举报