@RequestMapping(value = "/products/create", method = RequestMethod.POST)
public ModelAndView create(@Valid ProductForm productForm, BindingResult bindingResult,
HttpServletRequest request) {
SessionContext sessionContext = (SessionContext) request.getAttribute("sessionContext");
ModelAndView mav = new ModelAndView("products/new");
mav.addObject("errors", bindingResult.getAllErrors());
mav.addObject("productForm", productForm);
int newProductId = -1;
if (!bindingResult.hasErrors()) {
List<Product> products = productService.find...(...);
if (products != null...) {
bindingResult.addError(new ObjectError("Products", "..."));
}
// only try and create if no errors so far
if (!bindingResult.hasErrors()) {
newProductId = productService.create(..., productForm);
if (newProductId <= 0) {
bindingResult.addError(new ObjectError("Products", "..."));
}
}
}
if (bindingResult.hasErrors()) {
return mav;
}
return new ModelAndView("redirect:/products/show/" + newProductId);
}
So the above describes the UI side of things (using Spring MVC).
Now, how should I be designing the service layer, so in this example the ProductServiceImpl has a create method that will will create the product and persist it in the database.
I have to check for permissions, based on the users role etc.
I could to this in the UI layer by first checking if the user has permissions to create a product:
if(permissionService.hasPermission(.....)) {
newProductId = productService.create(....)
}
But this ties this logic into the UI layer, I think it should be in the create method itself:
public class ProductServiceImpl implements ProductService {
@Autowired
PermissionService permissionService;
..
@Override
public int create(...., final ProductForm productForm) {
boolean canCreateProduct = productService.hasPermissions(.....);
if(canCreateProduct) {
Product product = ..... (productForm);
productDao.save(product);
return product.getId();
}
}
}
But the problem I can't understand is if I put the permission check in ProductServiceImpl.create method, how do I report back to the UI layer that you don't have permissions to do this?
If you say I should throw an exception, then my UI layer looks very cluttered as I will have so many exceptions to handle based on the various checks I need to perform.
What should I be doing here?
Permission checks like this should/could be done with AOP, through means of a mechanism like CDI's interceptors. Spring has method interceptors serving the same purpose (see AOP in Spring). Throwing an exception in case of insufficient rights is the correct approach.
That said, I see your problem, but the common solution is quite simple: Your UI receives the rights of its user post-login (or retrieves them through some UserService). Using this info, you adjust the operations you expose in the UI. In your example, you do not display the operation for creating a new product if the user is not allowed to do so.
You will probably still want to handle the exception though (let's say in case a user's rights are modified server-side in the meantime) and display an error if it occurs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With