Ошибка валидации даты

202
15 января 2019, 07:30

Есть такой сервис:

import ru.lanit.rest.dao.PersonDAO;
import ru.lanit.rest.dto.CarDTO;
import ru.lanit.rest.dto.PersonDTO;
import ru.lanit.rest.model.Car;
import ru.lanit.rest.model.Person;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

@RequestScoped
@Path("/")
public class PersonService {
    @Inject
    PersonDAO personDAO;
    @Path("personwithcars")
    @Produces(MediaType.APPLICATION_JSON)
    @GET
    public Response getPersonWithCars(@QueryParam("personid") String personId){
        if (!isPersonIdIsLong(personId))
            return Response.status(Response.Status.BAD_REQUEST).build();
        Long id = Long.parseLong(personId);
        Person person = personDAO.getPerson(id);
        if(person==null)
            return Response.status(Response.Status.NOT_FOUND).build();
        PersonDTO personDTO = setPersonDTO(person);
        return Response.status(Response.Status.OK).entity(personDTO).build();
    }

    @Path("person")
    @POST
    @Transactional
    @Consumes(MediaType.APPLICATION_JSON)
    public Response addPerson(Person person){
        if(!isDateValid(person.getBirthdate()) || !isPersonIdIsLong(person.getId().toString()))
            return Response.status(Response.Status.BAD_REQUEST).build();
        personDAO.addPerson(person);
        if (personDAO.getPerson(person.getId())!=null)
        return Response.status(Response.Status.OK).build();
        else{
            return Response.status(Response.Status.BAD_REQUEST).build();
        }
    }
    private PersonDTO setPersonDTO(Person person){
        Set<Car> carSet = person.getCars();
        Set<CarDTO> cars = setCarDTO(carSet);
        PersonDTO personDTO = new PersonDTO();
        personDTO.setBirthdate(person.getBirthdate());
        personDTO.setId(person.getId());
        personDTO.setName(person.getName());
        personDTO.setCars(cars);
        return personDTO;
    }
    private Set<CarDTO> setCarDTO(Set<Car> carSet){
        Set<CarDTO> cars = new HashSet<>();
        for(Car car : carSet){
            CarDTO carDTO = new CarDTO();
            carDTO.setId(car.getId());
            carDTO.setModel(car.getModel());
            carDTO.setHorsepower(car.getHorsepower());
            carDTO.setOwnerId(car.getOwnerId());
            cars.add(carDTO);
        }
        return cars;
    }
    private boolean isPersonIdIsLong(String personId){
        try{
            Long.parseLong(personId);
            return true;
        }
        catch (NumberFormatException | NullPointerException e){
            return false;
        }
    }
    private boolean isDateValid(final String date) {
        Date currentDate = new Date();
        String formatString = "dd.MM.yyyy";
        boolean isInvalidFormat;
        Date dateObj;
        try {
            SimpleDateFormat sdf = (SimpleDateFormat) DateFormat.getDateInstance();
            sdf.applyPattern(formatString);
            sdf.setLenient(false);
            dateObj = sdf.parse(date);
            if (date.equals(sdf.format(dateObj)) && dateObj.compareTo(currentDate)>0) {
                isInvalidFormat = false;
            }
            else {
                isInvalidFormat = true;
            }
        } catch (ParseException e) {
            isInvalidFormat = true;
        }
        return isInvalidFormat;
    }
}

Его проверяет такой тест: (конкретно вопрос про 29-30 строчки, где указана дата "1995.18.03")

import org.json.JSONObject;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
import ru.lanit.RESTfulTest.parts.CarPost;
import ru.lanit.RESTfulTest.parts.PersonPost;
import ru.lanit.RESTfulTest.parts.PersonWithCarsGet;
import ru.lanit.RESTfulTest.tools.CarCreator;
import ru.lanit.RESTfulTest.tools.PersonCreator;
import ru.lanit.RESTfulTest.tools.Settings;
public class InvalidTest {
    @BeforeTest
    public void setup() {
        Settings.setup();
    }
    @Test
    public void beginTest(){
        //404 - request for /personwithcars
        PersonWithCarsGet.getPersonWithCarsTest("2", 404, "");
        //400 - requests
        JSONObject person1 = PersonCreator.createPerson("asd","InvalidPerson","1995.18.03");
        PersonPost.postPersonTest(person1, 400,null);
//        JSONObject car = createInvalidCar("15","BMW-X4");
//        CarPost = new CarPost(car,400,"");
//        CarPost.postCarTest();
        PersonWithCarsGet.getPersonWithCarsTest("asd", 400, null);
        person1 = PersonCreator.createPerson("1","Moja", "1995.18.03");
        PersonPost.postPersonTest(person1, 400,null);
        JSONObject car = CarCreator.createCar(15L,"To-yota-X56",200,1L);
        CarPost.postCarTest(car, 400,null);
    }
}

Класс, отвечающий за создание JSONObject person:

import org.json.JSONObject;
import java.text.SimpleDateFormat;
import java.util.Date;
public class PersonCreator {
    public static JSONObject createPerson(String id, String name, String birthdate){
        JSONObject requestBody = new JSONObject();
        requestBody.put("id", id);
        requestBody.put("name", name);
        requestBody.put("birthdate", birthdate);
        return requestBody;
    }
    public static JSONObject createPerson(Long id, String name, Date birthdate){
        final SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
        JSONObject requestBody = new JSONObject();
        requestBody.put("id", id);
        requestBody.put("name", name);
        requestBody.put("birthdate", sdf.format(birthdate));
        return requestBody;
    }
    public static JSONObject createPerson(Long id, String name, String birthdate){
        JSONObject requestBody = new JSONObject();
        requestBody.put("id", id);
        requestBody.put("name", name);
        requestBody.put("birthdate", birthdate);
        return requestBody;
    }
}

Вопрос: при отправки даты "1995.18.03" на проверку поступает дата "16.11.0009". Не могу понять, почему?

Answer 1
  1. изменил сервис PersonService: убрал проверку валидности даты.
  2. изменил сущность Person: добавил проверку валидности даты в метод setBirthdate(String birthdate().

Изменённый класс PersonService:

import ru.lanit.rest.dao.PersonDAO;
import ru.lanit.rest.dto.CarDTO;
import ru.lanit.rest.dto.PersonDTO;
import ru.lanit.rest.model.Car;
import ru.lanit.rest.model.Person;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

@RequestScoped
@Path("/")
public class PersonService {
    @Inject
    PersonDAO personDAO;
    @Path("personwithcars")
    @Produces(MediaType.APPLICATION_JSON)
    @GET
    public Response getPersonWithCars(@QueryParam("personid") String personId){
        if (!isPersonIdIsLong(personId))
            return Response.status(Response.Status.BAD_REQUEST).build();
        Long id = Long.parseLong(personId);
        Person person = personDAO.getPerson(id);
        if(person==null)
            return Response.status(Response.Status.NOT_FOUND).build();
        PersonDTO personDTO = setPersonDTO(person);
        return Response.status(Response.Status.OK).entity(personDTO).build();
    }

    @Path("person")
    @POST
    @Transactional
    @Consumes(MediaType.APPLICATION_JSON)
    public Response addPerson(Person person){
//        !isDateValid(person.getBirthdate()) ||        add this to "if" if necessary
        if(!isPersonIdIsLong(person.getId().toString()))
            return Response.status(Response.Status.BAD_REQUEST).build();
        personDAO.addPerson(person);
        if (personDAO.getPerson(person.getId())!=null)
        return Response.status(Response.Status.OK).build();
        else{
            return Response.status(Response.Status.BAD_REQUEST).build();
        }
    }
    private PersonDTO setPersonDTO(Person person){
        Set<Car> carSet = person.getCars();
        Set<CarDTO> cars = setCarDTO(carSet);
        PersonDTO personDTO = new PersonDTO();
        personDTO.setBirthdate(person.getBirthdate());
        personDTO.setId(person.getId());
        personDTO.setName(person.getName());
        personDTO.setCars(cars);
        return personDTO;
    }
    private Set<CarDTO> setCarDTO(Set<Car> carSet){
        Set<CarDTO> cars = new HashSet<>();
        for(Car car : carSet){
            CarDTO carDTO = new CarDTO();
            carDTO.setId(car.getId());
            carDTO.setModel(car.getModel());
            carDTO.setHorsepower(car.getHorsepower());
            carDTO.setOwnerId(car.getOwnerId());
            cars.add(carDTO);
        }
        return cars;
    }
    private boolean isPersonIdIsLong(String personId){
        try{
            Long.parseLong(personId);
            return true;
        }
        catch (NumberFormatException | NullPointerException e){
            return false;
        }
    }
//    private boolean isDateValid(final String date) {
//        Date currentDate = new Date();
//        String formatString = "dd.MM.yyyy";
//        boolean isInvalidFormat;
//        Date dateObj;
//        try {
//            SimpleDateFormat sdf = (SimpleDateFormat) DateFormat.getDateInstance();
//            sdf.applyPattern(formatString);
//            sdf.setLenient(false);
//            dateObj = sdf.parse(date);
//            if (date.equals(sdf.format(dateObj)) && dateObj.compareTo(currentDate)>0) {
//                isInvalidFormat = false;
//            }
//            else {
//                isInvalidFormat = true;
//            }
//        } catch (ParseException e) {
//            isInvalidFormat = true;
//        }
//        return isInvalidFormat;
//    }
}

Изменённый класс Person:

import org.codehaus.jackson.annotate.JsonBackReference;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Set;
@Entity
@Table(name="person")
public class Person implements Serializable {
    @Id
    @NotNull
    private Long id;
    @Column(name="name")
    @NotNull
    private String name;
    @Column(name="birthdate")
    @NotNull
    private Date birthdate;
    @JsonBackReference
    @OneToMany(mappedBy = "owner", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    private Set<Car> cars;

    public Person(){}
    public Person(Long id, String name, String birthdate){
        setId(id);
        setName(name);
        try {
            setBirthdate(birthdate);
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
    public Person(Long id){
        setId(id);
    }
    public void setCars(Set<Car> cars) {
        this.cars = cars;
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getBirthdate() {
        SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
        return sdf.format(this.birthdate);
    }
    public void setBirthdate(String birthdate) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy");
        if(isDateValid(birthdate))
        this.birthdate = sdf.parse(birthdate);
    }
    public Set<Car> getCars() {
        return cars;
    }

    private boolean isDateValid(final String date) {
        Date currentDate = new Date();
        String formatString = "dd.MM.yyyy";
        boolean isFormatValid;
        Date dateObj;
        try {
            SimpleDateFormat sdf = (SimpleDateFormat) DateFormat.getDateInstance();
            sdf.applyPattern(formatString);
            sdf.setLenient(false);
            dateObj = sdf.parse(date);
            if (date.equals(sdf.format(dateObj)) && dateObj.compareTo(currentDate)<0) {
                isFormatValid = true;
            }
            else {
                isFormatValid = false;
            }
        } catch (ParseException e) {
            isFormatValid = false;
        }
        return isFormatValid;
    }
}
READ ALSO
Как реализовать такую лампочку на css ?

Как реализовать такую лампочку на css ?

Подскажите, можно ли средствами CSS создать копию такой картинки ? Это некий фонарик который должен иметь два состояния - включённый и выключенный

158
Как развернуть React Native с Expo?

Как развернуть React Native с Expo?

Выполнил команду npm install expПапка node_modules создалась и Получил: Потом написал команду: `exp init Application

178
Возможно ли проверить если внутри li блок ul на js?

Возможно ли проверить если внутри li блок ul на js?

мне нужно проверить если ли внутри блока li блок ul и если его нету то выполнить действие

167
skype api создание чата между 2 пользователями

skype api создание чата между 2 пользователями

как можно по нажатию на кнопку(ссылка которая выводится для конкретного пользователя) создавать чат в скайпе и подключиться к этому чату...

140