3
@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);
}

したがって、上記は UI 側 (Spring MVC を使用) について説明しています。

では、サービス レイヤーをどのように設計すればよいのでしょうか。この例では、ProductServiceImpl に、製品を作成してデータベースに永続化する create メソッドがあります。

ユーザーの役割などに基づいて、権限を確認する必要があります。

ユーザーが製品を作成する権限を持っているかどうかを最初に確認することで、UI レイヤーでこれを行うことができます。

if(permissionService.hasPermission(.....)) {
  newProductId = productService.create(....)
}

しかし、これはこのロジックをUIレイヤーに結び付けます。私はそれがcreateメソッド自体にあるべきだと思います:

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();
     }   
  }
}

しかし、私が理解できない問題は、ProductServiceImpl.create メソッドにパーミッション チェックを入れた場合、これを行うパーミッションがないことを UI レイヤーに報告するにはどうすればよいかということです。

例外をスローする必要があると言うと、実行する必要があるさまざまなチェックに基づいて処理する例外が非常に多くなるため、UI レイヤーは非常に雑然と見えます。

私はここで何をすべきですか?

4

1 に答える 1

2

このようなアクセス許可チェックは、CDI のインターセプターなどのメカニズムを使用して、AOP で実行する必要があります。Spring には、同じ目的を果たすメソッド インターセプターがあります ( Spring の AOP を参照)。権限が不十分な場合に例外をスローするのが正しいアプローチです。

とはいえ、問題はわかりますが、一般的な解決策は非常に単純です。UI は、ログイン後にユーザーの権限を受け取ります (または some を介してそれらを取得しますUserService)。この情報を使用して、UI で公開する操作を調整します。あなたの例では、ユーザーが許可されていない場合、新しい製品を作成するための操作を表示しません。

ただし、例外を処理し (その間にユーザーの権限がサーバー側で変更された場合など)、例外が発生した場合はエラーを表示することをお勧めします。

于 2012-05-05T19:44:52.193 に答える