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