{"record":{"id":"129cc697ae646214","repo":"dromara/Sa-Token","slug":"e-getmessage","errorCode":null,"errorMessage":"转换失败: {e.getMessage()}","messagePattern":"转换失败: \\{e\\.getMessage\\(\\)\\}","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"sa-token-core/src/main/java/cn/dev33/satoken/util/SaFoxUtil.java","lineNumber":405,"sourceCode":"\tpublic static <T> T mapToObject(Map<String, Object> map, Class<T> clazz) {\n\t\tif(map == null) {\n\t\t\treturn null;\n\t\t}\n\t\tif(clazz == Map.class) {\n\t\t\treturn (T) map;\n\t\t}\n\t\ttry {\n\t\t\tT obj = clazz.getDeclaredConstructor().newInstance();\n\t\t\tfor (Field field : clazz.getDeclaredFields()) {\n\t\t\t\tString fieldName = field.getName();\n\t\t\t\tif (map.containsKey(fieldName)) {\n\t\t\t\t\tfield.setAccessible(true);\n\t\t\t\t\tfield.set(obj, map.get(fieldName));\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn obj;\n\t\t} catch (Exception e) {\n\t\t\tthrow new RuntimeException(\"转换失败: \" + e.getMessage(), e);\n\t\t}\n\t}\n\n\n\t/**\n\t * 在url上拼接上kv参数并返回\n\t * @param url url\n\t * @param paramStr 参数, 例如 id=1001\n\t * @return 拼接后的url字符串\n\t */\n\tpublic static String joinParam(String url, String paramStr) {\n\t\t// 如果参数为空, 直接返回\n\t\tif(paramStr == null || paramStr.length() == 0) {\n\t\t\treturn url;\n\t\t}\n\t\tif(url == null) {\n\t\t\turl = \"\";\n\t\t}","sourceCodeStart":387,"sourceCodeEnd":423,"githubUrl":"https://github.com/dromara/Sa-Token/blob/ac2c7f6e94a78573cf0bcb932dd8b04e68fad189/sa-token-core/src/main/java/cn/dev33/satoken/util/SaFoxUtil.java#L387-L423","documentation":"SaFoxUtil has a reflection-based helper (used by paths like search/session data -> object mapping) that instantiates the target class via getDeclaredConstructor().newInstance() and copies map entries into declared fields. Any failure during instantiation or field.set (security manager, non-instantiable class, wrong field type, inaccessible constructor) is wrapped in a RuntimeException with message '转换失败: <cause>'. The original exception is preserved as the cause, so its message is the real diagnosis.","triggerScenarios":"Passing a class with no no-arg constructor, a non-public class, an abstract class/interface, or a map value whose type does not match the target field (e.g. Integer into a String field without a converter).","commonSituations":"Using sa-token session-object APIs where the entity lost its no-arg constructor after adding Lombok @Builder without @NoArgsConstructor; mapping JSON-parsed maps (numbers as Integer/Long) into typed models; JDK 17+ module access restrictions blocking reflection.","solutions":["Read e.getCause() from the thrown RuntimeException to find the real failure (InstantiationException vs IllegalAccessException vs IllegalArgumentException)","Ensure the target class is public, concrete, and has a public/protected no-arg constructor (add @NoArgsConstructor alongside @Builder)","Match map value types to field types or convert values before calling (e.g. String.valueOf for numeric map values)","Prefer manual mapping or a dedicated mapper (Jackson/Gson) for complex objects instead of this reflection helper"],"exampleFix":"// before\n@Data @Builder\npublic class UserInfo { ... }  // no no-arg ctor -> 转换失败: InstantiationException\n\n// after\n@Data @Builder @NoArgsConstructor @AllArgsConstructor\npublic class UserInfo { ... }","handlingStrategy":"try-catch","validationCode":"if (clazz.isInterface()\n        || Modifier.isAbstract(clazz.getModifiers())) {\n    throw new IllegalArgumentException(\"target must be concrete\");\n}\ntry { clazz.getDeclaredConstructor(); }\ncatch (NoSuchMethodException e) { /* add no-arg ctor */ }","typeGuard":null,"tryCatchPattern":"try {\n    T obj = SaFoxUtil.mapToModel(map, clazz);\n} catch (RuntimeException e) {\n    Throwable root = e.getCause();\n    if (root instanceof InstantiationException) { /* missing no-arg ctor */ }\n    else if (root instanceof IllegalAccessException) { /* access/module issue */ }\n    else if (root instanceof IllegalArgumentException) { /* type mismatch on a field */ }\n}","preventionTips":["Give mapped models a public no-arg constructor (mind Lombok @Builder)","Match map value types to field types before converting","For complex models use a real mapper (Jackson) instead of reflection helpers"],"tags":["sa-token","reflection","type-conversion","utilities"],"backgroundTag":null,"analyzedSha":"ac2c7f6e94a78573cf0bcb932dd8b04e68fad189","analyzedAt":"2026-08-14T14:36:10.271Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}