最近,对之前写的项目进行了比较大的改动,进行了代码重构和优化。为了符合阿里开发规范,把字段注入都改成了构造方法注入,但是在注入的时候遇到一点小问题。
其中提取了一个公共的controller类BaseController
/**
* 公共的controller
*/
public class BaseController {
/**
* 文件上传根路径
*/
@Value("${uploads.path}")
protected String root;
private HttpSession session;
public BaseController() {}
@Autowired
public BaseController(HttpSession session) {
this.session = session;
}
/**
* 获取session对象
* @return HttpSession
*/
protected HttpSession getSession() {
return session;
}
/**
* 获取登录的管理员信息
* @return Admin
*/
protected Admin getUserInfo() {
Object object = session.getAttribute("admin");
if (object == null) {
throw new ServiceException(ResponseCode.NOT_FOUND, "获取登录信息失败,当前没有管理员登录");
}
return (Admin) object;
}
/**
* 图片上传
* @param file MultipartFile对象
* @param directory 文件上传目录
* @return JsonResult<String>
*/
public JsonResult<String> upload(MultipartFile file, String directory) throws IOException {
// 获取文件名
String fileName = StringUtils.getFileName(file);
// 创建目标对象
File targetFile = new File(root + directory, fileName);
// 保存文件
file.transferTo(targetFile);
return JsonResult.success(null, directory + fileName);
}
}
在用户登录的方法中,getSession()方法返回的是null,登录时发生了NPE。
@RestController
@RequestMapping(path = "/admin", produces="application/json; charset=utf-8")
public class AdminController extends BaseController {
private final IAdminService service;
@Autowired
public AdminController(IAdminService service) {
this.service = service;
}
/**
* 登录认证
* @param adminLoginDTO 管理员登录信息
* @return JsonResult<Void>
*/
@RequestMapping(value = "/login", method = RequestMethod.POST)
public JsonResult<Void> login(AdminLoginDTO adminLoginDTO) {
Admin admin = service.login(adminLoginDTO);
getSession().setAttribute("admin", admin); // 发生NullPointerException
return JsonResult.success();
}
}
这里发生NPE原因很简单,没有调用BaseController的有参构造方法对session进行初始化,而是默认调用的无参构造方法,需要在AdminController类上调用BaseController(HttpSession session),但是,我的初衷把创建/注入HttpSession对象的工作放在BaseController。
最佳的方法是将构造方法注入改为字段注入,问题完美解决。
/**
* 公共的controller
*/
public class BaseController {
/**
* 文件上传根路径
*/
@Value("${uploads.path}")
protected String root;
@Autowired
private HttpSession session;
/**
* 获取session对象
* @return HttpSession
*/
protected HttpSession getSession() {
return session;
}
}