2014-04-16 3 views
0

Grails는 컨트롤러가 서비스를 호출하고 컨트롤러가 다른 컨트롤러로 요청을 전달하는 것을 매우 쉽게 만듭니다.서비스 콜백 (Controller call back)?

은 그래서 당신은 어떤 컨트롤러에서 매우 쉽게 호출 할 수 있습니다 이러한

List<String> updateNames() { 
    ... 
} 

같은 서비스 방법이 있다고 가정합니다.

궁금한 점이 있다면 서비스 방법에 유효성 검사 문제가 있음을 깨닫는 경우입니다. 예외적 인 경우는 아니기 때문에 Exception을 컨트롤러에 던지기를 원하지는 않습니다. 하지만 좋은 목록 대신 래퍼 객체를 사용해야한다는 이유로 호출 한 Controller에 대한 오류 메시지를 반환 할 수 없습니다.

어쨌든이 경우 서비스가 제공 될 수 있습니다. 사용자에게 오류 응답을 반환 할 수있는 다른 컨트롤러로 서버 측을 전달 하시겠습니까?

감사합니다.

+1

이것은 예외적 인 경우를위한 이상적인 사용 사례로 보입니다. –

+0

Sèrgio와 Joshua와 동의하십시오. 모든 유효성 검사 예외는 명령 객체 또는 도메인 인스턴스 자체를 사용하여 서비스 클래스로 이동하기 전에 처리 할 수 ​​있습니다.Joshua가 관심사 분리에 대해 언급 한 것처럼 서비스는 http 호출 또는 유효성 검사 문제에 관해서는 알지 못합니다. 비즈니스 예외/시나리오에주의해야합니다. 그것은 롤백 트랜잭션을 수행하는 마지막 일 것입니다 런타임 예외 또는 서비스에서 오류를 던지고있다. 롤백을 처리하려면 ['TransactionAspectSupport'] (http://stackoverflow.com/a/17357547/2051952)를 사용해야합니다. – dmahapatro

+0

@Ian Roberts 이유는 무엇입니까? 이것은 예상 할 수있는 일이며, 사용자가 잘못된 데이터를 입력 할 수 있습니다. 실제로 시스템 자체에서 아무 것도 실제로 잘못되지 않았습니다. –

답변

1

서비스는 이러한 방식으로 웹/HTTP 요청 컨텍스트를 인식하지 못합니다. 세션이나 요청 범위가 지정된 서비스로이 회선이 어떻게 흐려 지는지는 묻지 않을 것입니다. 또한 책임을 분리하고 좋은/깨끗한 디자인을 원하기 때문에 서비스가 웹/http 요청을 처리한다는 사실을 인식하지 못하게해야합니다.

그래서 질문에 답하십시오. 이는 서비스에서 예외를 발생시키고 컨트롤러가 예외의 결과를 처리하게하는 경우와 같습니다. 인스턴스에 대한 유효성 검사 오류 인 경우 컨트롤러의 인스턴스에 대한 오류 컬렉션에 액세스 할 수 있어야합니다 (물론 해당 서비스에 대한 입력 임).

서비스의 예외에 대한 보조 노트입니다. 스택 트레이스는 많은 비용이 듭니다. Grails에서는 작업량이 많아서 더 많이 사용합니다. 이 비용을 피하기 위해 예외적으로 fillInStackTrace 메서드를 재정의하는 서비스에서 자신 만의 비즈니스 논리 예외를 발생시키려는 경우 매우 좋습니다. 여기

이 예는 다음과 같습니다 이미 콩의 검증을위한 구조를 가지고

package com.example 

class MyBusinessException extends RuntimeException { 

    List<String> argList = [] 

    public MyBusinessException (String message, List<String> args){ 
     super(message) 

     argList = args 
    } 

    public MyBusinessException (String message){ 
     super(message) 
    } 

    /** 
    * Don't fill in the stack trace because we want things to be faster. 
    **/ 
    @Override 
    public Throwable fillInStackTrace() { 
     // do nothing 
     return this 
    } 
} 
2

Grails는, Errors (오고 폼 봄)라고합니다. 당신은 파일을 업로드하는 서비스가 있다면 예를 들어, 당신은 쉽게 빈에서 유효성 검사 오류를 첨부 할 수 있습니다 :

class UploadService { 
    void doUpload(MultipartFile file, MyDomainClass domainClassInstance) { 
    if(validationsFail) { 
     domainClassInstance.errors.rejectValue("myUploadField","my.i18n.code") 
    } 
    } 
} 

을이 도메인 클래스가 아니라면, 당신은 그들이 validateable도있어 이후 command object 사용을 고려할 수 있습니다.

def upload() { 
    MyDomainClass instance = ... 
    uploadService.doUpload(request.getFile('file'), instance) 
    if(!instance.hasErrors()) { 
    //save and go on... 
    } 
} 

또 다른 옵션은 @Joshua 무어 같은 예외가 대답과 함께 작업하는 것입니다 : 인스턴스에 오류가있는 경우 컨트롤러에서

, 그냥 검사하는 METTER입니다. RuntimeException을 반드시 기억하십시오. 그렇게하지 않으면 거래가 자동으로 롤백되지 않습니다.

관련 문제