使用JavaEE进行现场验证的良好实践

使用JavaEE进行现场验证的良好实践,java,validation,jakarta-ee,Java,Validation,Jakarta Ee,我有一个项目要用JavaEE编写,但我对这项技术还不熟悉 我有依赖于从客户端前端接收的参数的EJB 目前,我正在验证EJB中的参数,例如,我在EJB中有验证参数的方法,但我认为这是一种不好的做法,因为它会导致代码重复,并给EJB增加更多的责任 我想知道执行参数验证的最佳实践是什么 编辑:客户端无法直接访问我的JavaEE后端。相反,我们有一个用Java编写的、遵循SOAP体系结构的互操作性层,它位于客户端前端和J2E后端之间 下面是我的代码示例: // Method inherited

我有一个项目要用JavaEE编写,但我对这项技术还不熟悉

我有依赖于从客户端前端接收的参数的EJB

目前,我正在验证EJB中的参数,例如,我在EJB中有验证参数的方法,但我认为这是一种不好的做法,因为它会导致代码重复,并给EJB增加更多的责任

我想知道执行参数验证的最佳实践是什么

编辑:客户端无法直接访问我的JavaEE后端。相反,我们有一个用Java编写的、遵循SOAP体系结构的互操作性层,它位于客户端前端和J2E后端之间

下面是我的代码示例:

    // Method inherited from the EJB interface
    // The eventOrganizer variable is another EJB that is injected into this very EJB
    @Override
        public boolean registerEvent(String name, int participantNumber, Calendar date, Coordinator coordinator) {

            l.log(Level.INFO, "Received request for event creation");

            if (!areParametersValid(name, participantNumber, date, coordinator)) {
                return false;
            }

            Calendar cal = Calendar.getInstance();
            cal.setTime(date.getTime());
            cal.add(Calendar.HOUR_OF_DAY, 12);

            Event event = new Event(coordinator, date.getTime(), cal.getTime(), participantNumber, name);

            return eventOrganizer.bookRoom(event);
        }

// Parameters validation methods
/**
     * Returns true if the given name is non null and
     * is not empty
     * @param name the name of the {@link Event}
     * @return true if the name semantically of the {@link Event} is valid
     */
    private boolean nameIsGood(String name) {
        return name != null && !name.trim().equals("");
    }

    /**
     * Returns true if the number of participant is strictly positive
     * @param participantNumber the number of people in the {@link Event}
     * @return true if the number of participant is valid
     */
    private boolean participantNumberIsGood(int participantNumber) {
        return participantNumber > 0;
    }

    /**
     * Checks if the given date is a date in the future,
     * and returns true if it is
     * @param date the date to check
     * @return true if the provided start date for the {@link Event} is valid
     */
    private boolean dateIsGood(Calendar date) {
        return date.after(Calendar.getInstance());
    }

    /**
     * Checks if the given {@link Coordinator} is a valid coordinator,
     * i.e., if he's not null, and returns true if he is not
     * @param coordinator the {@link Coordinator} to check
     * @return true if the {@link Coordinator} is valid
     */
    private boolean coordinatorIsGood(Coordinator coordinator) {
        return coordinator != null;
    }

    /**
     * Checks that all the parameters received for an {@link Event} creation are valid
     * and returns true if they are, or false if they're not
     * @param name the name of the {@link Event}, as a {@link String}
     * @param participantNumber the estimated number of people for the
     *                          {@link Event} as a {@link Integer}
     * @param date the date at which the {@link Event} is scheduled,
     *             as a {@link Calendar}
     * @param coordinator the {@link Coordinator} that created the {@link Event}
     * @return true if all the given parameters are valid, and the event creation shall be processed
     */
    private boolean areParametersValid(String name, int participantNumber, Calendar date, Coordinator coordinator) {
        return nameIsGood(name) && participantNumberIsGood(participantNumber) && dateIsGood(date) && coordinatorIsGood(coordinator);
    }


// Event object 
public class Event {
    private Coordinator coordinator;
    private Date startDate;
    private Date endDate;
    private int nbPeople;
    private String name;
    private List<Room> rooms;
    private List<RoomType> desiredRoomTypes;

    public Event(int nbPeople, String name, List<RoomType> roomTypes) {
        this.nbPeople = nbPeople;
        this.name = name;
        this.desiredRoomTypes = roomTypes;
        this.rooms = new ArrayList<>();
    }

    public Event(Coordinator coordinator, Date startDate, Date endDate, int nbPeople, String name) {
        this.coordinator = coordinator;
        this.startDate = startDate;
        this.endDate = endDate;
        this.nbPeople = nbPeople;
        this.name = name;
        this.rooms = new ArrayList<>();
    }

    public List<Room> getRooms() {
        return rooms;
    }

    public void addRooms(List<Room> rooms) {
        this.rooms.addAll(rooms);
    }

    public void addRoom(Room room) {
        this.rooms.add(room);
    }

    public Coordinator getCoordinator() {
        return coordinator;
    }

    public Date getStartDate() {
        return startDate;
    }

    public Date getEndDate() {
        return endDate;
    }

    public int getNbPeople() {
        return nbPeople;
    }

    public String getName() {
        return name;
    }
}

// Coordinator object 
public class Coordinator {
    private String firstName;
    private String lastName;
    private String email;
    private List<Event> eventsCreated;

    public Coordinator(String firstName, String lastName, String email) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.email = email;
    }

    public List<Event> getEventsCreated() {
        return eventsCreated;
    }

    public void setEventsCreated(List<Event> eventsCreated) {
        this.eventsCreated = eventsCreated;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public String getEmail() {
        return email;
    }
}
//从EJB接口继承的方法
//eventOrganizer变量是注入到这个EJB中的另一个EJB
@凌驾
public boolean registerEvent(字符串名称、int participantNumber、日历日期、协调器){
l、 日志(Level.INFO,“收到事件创建请求”);
if(!areParametersValid(姓名、参与者编号、日期、协调员)){
返回false;
}
Calendar cal=Calendar.getInstance();
cal.setTime(date.getTime());
计算添加(日历小时/天,12);
Event Event=新事件(协调人、date.getTime()、cal.getTime()、参与者编号、名称);
返回事件组织者。预订室(事件);
}
//参数验证方法
/**
*如果给定名称为非null且
*不是空的
*@param name{@link Event}的名称
*@如果{@link Event}的名称在语义上有效,则返回true
*/
私有布尔名称良好(字符串名称){
返回名称!=null&&!name.trim()等于(“”);
}
/**
*如果参与者的数量严格为正,则返回true
*@param participantNumber{@link Event}中的人数
*@如果参与者人数有效,则返回true
*/
私有布尔participantNumber良好(int participantNumber){
返回参与者编号>0;
}
/**
*检查给定日期是否为将来的日期,
*如果是,则返回true
*@param date要检查的日期
*@如果为{@link Event}提供的开始日期有效,则返回true
*/
专用布尔值dateIsGood(日历日期){
返回日期.after(Calendar.getInstance());
}
/**
*检查给定的{@link Coordinator}是否为有效的协调器,
*也就是说,如果他不是null,则返回true
*@param coordinator要检查的{@link coordinator}
*@如果{@link corporator}有效,则返回true
*/
专用布尔协调器良好(协调器){
返回协调器!=null;
}
/**
*检查为{@link Event}创建接收的所有参数是否有效
*如果是,则返回true;如果不是,则返回false
*@param name{@link Event}的名称,作为{@link String}
*@param participantNumber此活动的估计人数
*{@link Event}作为{@link Integer}
*@param date计划{@link Event}的日期,
*作为{@link Calendar}
*@param-coordinator创建{@link-Event}的{@link-coordinator}
*@如果所有给定参数都有效,则返回true,并处理事件创建
*/
私有布尔值areParametersValid(字符串名称、整数参与者编号、日历日期、协调员){
返回名称良好(名称)和参与者编号良好(参与者编号)和日期良好(日期)和协调人良好(协调人);
}
//事件对象
公开课活动{
私人协调员;
私人日期开始日期;
私人日期结束日期;
私家侦探;
私有字符串名称;
私人名单室;
私有列表所需的目录类型;
公共事件(int nbPeople、字符串名称、列表类型){
this.nbPeople=nbPeople;
this.name=名称;
this.desiredRoomTypes=房间类型;
this.rooms=new ArrayList();
}
公共事件(协调人、开始日期、结束日期、联系人、字符串名称){
this.coordinator=协调器;
this.startDate=startDate;
this.endDate=endDate;
this.nbPeople=nbPeople;
this.name=名称;
this.rooms=new ArrayList();
}
公共列表getRooms(){
返回室;
}
公共房间(列出房间){
this.rooms.addAll(房间);
}
公共休息室(房间){
此.rooms.add(房间);
}
公共协调员{
回返协调员;
}
公共日期getStartDate(){
返回起始日期;
}
公共日期getEndDate(){
返回结束日期;
}
公共int getNbPeople(){
回归民众;
}
公共字符串getName(){
返回名称;
}
}
//协调对象
公共班级协调员{
私有字符串名;
私有字符串lastName;
私人字符串电子邮件;
创建私有列表事件;
公共协调员(字符串名、字符串名、字符串电子邮件){
this.firstName=firstName;
this.lastName=lastName;
this.email=电子邮件;
}
公共列表getEventsCreated(){
返回创建的事件;
}
已创建公共void setEventsCreated(已创建列表事件){
this.eventsCreated=eventsCreated;
}
公共字符串getFirstName(){
返回名字;
}
公共字符串getLastName(){
返回姓氏;
}
公共字符串getEmail(){
回复邮件;
}
}

避免混乱的一种方法是将未验证(可变)对象与t分离
UserFeedbackObject validate(UserFeedbackObject f){
  if (name.length == 0) f = f.badField("username","expected a username");
  if (date.after(Calendar.getInstance()) == 0) f = f.badField("username","date needs to be in the future");
  return  f;
}
@AroundInvoke
public Object intercept(InvocationContext ctx) throws Exception {
    Object[] parameters = ctx.getParameters();

    // loops through the parameters of the method
    for (Object parameter : parameters) {
        if (parameter == null) {
            throw new InvalidRequestParametersException("One or more parameters of type String in the request are null!");
        }

        // if the parameter is of type String
        if (parameter.getClass().getName().equals(String.class.getName())) {
            // if the string is invalid
            if (!FieldsValidator.isStringValid((String) parameter)) {
                throw new InvalidRequestParametersException("One or more parameters of type String in the request are invalid!");
            }
        }
    }
    return ctx.proceed();
}
/**
 * A static helper class used to validate fields within the EJBs
 *
 * @author Maxime Flament (maxime.flament@etu.unice.fr)
 */
public class FieldsValidator {

    /**
     * Returns true if the given string is non null and
     * is not empty
     *
     * @param str the string to validate
     * @return true if the string is semantically correct
     */
    public static boolean isStringValid(String str) {
        return str != null && !str.equals("");
    }

    /**
     * Returns true if the given value is strictly positive
     *
     * @param value the number to check
     * @return true if the value is strictly positive
     */
    public static boolean isStrictlyPositive(int value) {
        return value > 0;
    }

    /**
     * Checks if the given date is a date in the future,
     * and returns true if it is
     *
     * @param date the date to check
     * @return true if the provided start date is valid
     */
    public static boolean dateIsGood(Calendar date) {
        return date.after(Calendar.getInstance());
    }

    /**
     * Checks if the given {@link Object} is a valid object,
     * i.e., if he's not null, and returns true if he is not
     * @param object the {@link Object} to check
     * @return true if the {@link Object} is valid
     */
    public static boolean isObjectNotNull(Object object) {
        return object != null;
    }

    /**
     * Checks that the provided email is correct, and returns true if it is,
     * or false otherwise
     *
     * @implNote this method doesn't check that the provided email
     *           actually exists, but it only checks if the email
     *           is valid according to the RFC
     *
     * <a href="https://stackoverflow.com/a/26687649/5710894">Inspired by this</a>
     *
     * @param email the email to check
     * @return true if the given email is valid
     */
    public static boolean isValidEmail(String email) {
        return EmailValidator.getInstance().isValid(email);
    }
}
@Interceptors({InterceptorStringVerifier.class /* Add more interceptors here */})
Event registerEvent(String name, int participantNumber, Calendar date, Coordinator coordinator)