2017-12-25 19 views
2

私は、コードのこの部分がありますJava - JSONの日付検証を行うには?

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") 
    protected Date statusDate; 

を何とかするために、それはのような日付形式受け入れ -

"statusDate": "2017-13-27" 

または

"statusDate": "201823-12-12" 

が要求内のフォーマットを検証することが可能ですが(手動ではない)?

+1

それは、要求内の形式を検証することは可能ですか?あなたは詳細を教えていただけますか?ペイロードに日付を送信している間にクライアント側で検証を意味しますか? – Abhijeet

+0

良い点 - いいえ、データを取得する前に検証の問題がある場合は例外をスローします。 – Dvir

+0

後者は有効な日付です(将来はちょっと) – Henry

答えて

1

データを傍受しているときに受け取った日付形式が期待通りでない場合は、カスタム日付直列化/逆シリアル化クラスを作成してカスタム例外をスローする必要があります。

This答えは正しい方法を教えてくれます。

また、コードにバリデーターを入れてペイロードを検証し、単純な状態にしておくことができます。

1

はい、できます。詳細を表示させてください。

まず、plsは以下のようにすべての要求フィルタリングするベースコントローラ作成:コード上から

package com.letv.address.controller; 

import com.letv.address.utils.ConstantCode; 
import com.letv.address.utils.ResponseWrapper; 
import com.letv.xice.core.controller.GlobalController; 
import org.springframework.validation.BindingResult; 
import org.springframework.validation.FieldError; 
import org.springframework.validation.ObjectError; 

import java.util.ArrayList; 
import java.util.List; 

/** 
* Created by shichaoyang on 2017/1/10. 
*/ 
public class BaseController extends GlobalController { 

public ResponseWrapper requestCheckAndPost(BindingResult result) { 

    if (result.hasErrors()) { 

     List<Object> errorList = new ArrayList<>(); 

     StringBuilder sBuilder = new StringBuilder(); 

     for (ObjectError error : result.getAllErrors()) { 

      String fieldName = ((FieldError) error).getField(); 
      String fieldMessage = error.getDefaultMessage(); 

      sBuilder.append(fieldName) 
        .append(" ") 
        .append(getMessage(fieldMessage)) 
        .append(";"); 

      errorList.add(fieldName); 
     } 

     return new ResponseWrapper(
        ConstantCode.FAILING_WITH_ERROR_PARAM_CODE 
       , errorList.toArray() 
       , "" 
       , sBuilder.toString() 
       ); 
    } 
    return null; 
    } 
} 

をBindingResultは@NotBlank、@Patternなどのように、@JsonFormatまたは他の構成要素のヘッダをチェックしますに。彼らがルールにヒットした場合、BindingResultによってキャッチされ、エラーが発生します。以下は、私が使用しDTOオブジェクトである、あなたはより多くの細部を得ることができるようにただのuにそれを示しています

package com.letv.address.controller.dto; 

import com.letv.address.utils.ConstantCode; 
import org.hibernate.validator.constraints.NotBlank; 

/** 
* Created by shichaoyang on 2016/12/23. 
*/ 
public class ChildrenAreaSelectRequest{ 

@NotBlank(message = ConstantCode.REQUEST_VALIDATE_NOT_EMPTY) 
private String areaIds; 

public String getAreaIds() { 
    return areaIds; 
} 

public void setAreaIds(String areaIds) { 
    this.areaIds = areaIds; 
    } 
} 

は、その後私たちのビジネス・ロジック・コントローラでは、我々はベースコントローラを拡張して、以下のようなコードを記述する必要があります。

package com.letv.address.controller; 

import com.letv.address.controller.dto.ChildrenAreaSelectRequest; 
import com.letv.address.controller.dto.ParentAreaSelectReqeust; 
import com.letv.address.domain.Area; 
import com.letv.address.service.ChildAreaService; 
import com.letv.address.utils.ConstantCode; 
import com.letv.address.utils.ResponseWrapper; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.validation.BindingResult; 
import org.springframework.web.bind.annotation.*; 
import javax.validation.Valid; 
import java.util.ArrayList; 
import java.util.List; 

/** 
* Created by shichaoyang on 2016/12/12. 
*/ 
@RestController("areaController") 
public class AreaController extends BaseController { 

@Autowired 
protected ChildAreaService childAreaService; 

/** 
* get area info by parent id 
* 
* @param areaReqeust 
* @param result 
*/ 
@ResponseBody 
@RequestMapping(value = ConstantCode.CHILD_AREA_PATH, method = {RequestMethod.POST}) 
public ResponseWrapper childArea(@RequestBody @Valid ParentAreaSelectReqeust areaReqeust, BindingResult result) { 

    ResponseWrapper validationWrapper = requestCheckAndPost(result); 
    if (validationWrapper != null) { 
     return validationWrapper; 
    } 

    List<Area> areaList = childAreaService.selectByParentId(areaReqeust.getParentId()); 
    if (areaList == null || areaList.size() == 0) { 
     return new ResponseWrapper(ConstantCode.SUCCESS_WITH_EMPTY_DATA_CODE, new ArrayList<>()); 
    } else { 
     return new ResponseWrapper(ConstantCode.SUCCESS_WITH_FILL_DATA_CODE, areaList); 
    } 
    } 
} 

上記の方法を使用すると、要求内でフィールドを簡単に検証できます。これはこれを達成するための美しい方法です。

希望に役立ちます。

EDIT:

、誰もがそれをテストする必要がありますように、実際のコードで画像を交換してください。

+0

コードを回答に貼り付けてください。コピーペーストしたい人もいます。 –

+0

@ OleV.V。のソース。更新しました。 Plsは確認し、確認します。私に助けを送るのが便利だと感じるだけです。 – CharlieShi

+0

すごくいいですね、ありがとう(私はまだテストしていません)。 –

1

@JsonFormatは、statusDateをレスポンスとして返すときに、出力形式を設定するために使用されます。

文字列statusDateを受け入れ、コントローラのDate形式に変換するDTOオブジェクトを作成する方がよいでしょう。

は、文字列の形式で日付を検証するには、あなたが@Pattern使用することができます

public class StatusDateDto { 

    @NotNull(message="Status date is a required field")  
    @Pattern(regexp = "^\\d{4}-\\d{2}-\\d{2}", message="Invalid status date") 
    private String statusDate; 

    //Getter and setter 
} 

public ResponseEntity<?> postStatusDate(@Valid @RequestBody StatusDateDto dateDto, BindingResult result) { 

     if (result.hasFieldErrors()) { 
      String errors = result.getFieldErrors().stream() 
       .map(p -> p.getDefaultMessage()).collect(Collectors.joining("\n")); 

      return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(errors); 
     } 

     // Convert the String to Date after validation 

     return ResponseEntity.ok().build(); 
    }