1

私はサーブレットと REST サービスの作成にかなり慣れていませんが、正しく行っているかどうかわからないという問題に直面しています。私のサービスは次のようになります。

@POST
@Produces ("application/json")
@Path ("/register")
public String register(
    @FormParam("name") String name,
    @FormParam("username") String username,
    @FormParam("password") String password,
    @Context HttpServletResponse servletResponse) throws IOException {

    if( this.user_taken(username) ) return "USERNAME_TAKEN";
    User user = new User(name,username,password);

    .....

    return mapper.writeValueAsString(user);

}

ご覧のServiceとおり、 がバックエンド (データベースとユーザーの作成) を処理するServlet一方で、 がフォームからのリクエストを取得し、適切に検証して に渡しますService。サーブレット コード:

... validate user input form ...

ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
WebResource service = client.resource("http://localhost/Jaba");

String map = mapper.writeValueAsString(request.getParameterMap());
MultivaluedMap<String, String> obj = mapper.readValue(map, MultivaluedMap.class);

String result = 
    service.path("api").path("register")
        .accept("application/json")
        .post(String.class, obj);

ご覧のとおり、クライアント (サーブレット) は、サービスにデータを渡すために、多くの厄介な作業を行う必要があります。これをどのように変更/改善/最適化するか、またはより良いリファクタリングを行うことができますか? 私はベストプラクティスとそれが実際の例でどのようになるかに従うようにしています.

4

1 に答える 1

2

これが私ができることです:

する代わりに

String result = 
    service.path("api").path("register")
        .accept("application/json")
        .post(String.class, obj);

DTO オブジェクトを作成し、入力してからサービスに渡すようなことをします。これは、JSR の検証と注釈と共にアスペクトを適用する場合です (これは、所有しているものに対して行うことができますが、それほど素晴らしいものではありません)。

例:

@Aspect
public class DtoValidator {

    private Validator validator;

    public DtoValidator() {
    }

    public DtoValidator(Validator validator) {
        this.validator = validator;
    }

    public void doValidation(JoinPoint jp){
        for( Object arg : jp.getArgs() ){
            if (arg != null) {
                Set<ConstraintViolation<Object>> violations = validator.validate(arg);
                if( violations.size() > 0 ){
                    throw buildError(violations);
                }
            }
        }
    }

    private static BadRequestException buildError( Set<ConstraintViolation<Object>> violations ){
        Map<String, String> errorMap = new HashMap<String, String>();
        for( ConstraintViolation error : violations ){
            errorMap.put(error.getPropertyPath().toString(), error.getMessage());
        }
        return new BadRequestException(errorMap);
    }
}

アスペクトをアノテーションで宣言するか、構成で行うことができます(再利用可能にします)。そのような:

<aop:config proxy-target-class="true">
    <aop:aspect id="dtoValidator" ref="dtoValidator" order="10">
        <aop:before method="doValidation" pointcut="execution(public * com.mycompany.client.*.*(..))"/>
    </aop:aspect>
</aop:config>

これで、次のような DTO を作成できます。

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement
public class LoginRequest extends AbstractDto{

    @NotNull
    private String userName;

    @NotNull
    private String password;

    private LoginRequest() {
    }

    public LoginRequest(String userName, String password) {
        this.userName = userName;
        this.password = password;
    }

    public String getUserName() {
        return userName;
    }

    public String getPassword() {
        return password;
    }

}

これらのチェックに失敗する@NotNullと、次のような結果が得られます。

{
   "message":"{username=must not be null",
   "httpStatusCode":400,
   "httpMessage":"Bad Request",
   "details":{
      "username":"must not be null"
   }
}

次に、RestOperation クライアントをそのまま使用します

org.springframework.web.client.RestOperations restClient ...
restClient.postForObject(URL,new Dto(...),args);  

この周りにアスペクトを配置するrestClientと、あなたは金色になります (そして、実際には、サービス呼び出しでも)。

于 2013-04-19T21:46:54.110 に答える