Я создал REST API с конечной точкой GET
, которая должна возвращать письма, соответствующие заданным критериям. Все параметры конечной точки GET
являются необязательными и должны быть объединены AND
:
id
: идентификатор почты (автоматически генерируется при создании новой почты)
mail_from
: отправитель письма
received_before
: фильтры для писем, полученных до указанной даты
received_after
: фильтры для писем, полученных после указанной даты
rcpt_to
: массив адресов электронной почты получателя; важно, чтобы отфильтрованные письма содержали ВСЕХ получателей, заданных как значения параметров rcpt_to
Поскольку я не смог отфильтровать по диапазону дат с помощью создания запроса по именам методов, описанным в Spring Docs , я создал пользовательские запросы.
Я реализовал запрос для параметров 1-4 (см. Метод getMailByCustomQuery
) и другой запрос для параметра rcpt_to
(см. Метод getMailByRecipient
). Поскольку последний использует HAVING
, я не могу просто объединить оба запроса. Как я могу объединить оба запроса, чтобы иметь один метод / запрос для моей конечной точки GET
? Или есть альтернативный подход?
MailRepository.java
@RepositoryRestResource
public interface MailRepository extends JpaRepository<Mail, Long> {
@Query("SELECT m FROM Mail m " +
"WHERE (:id IS NULL OR m.id = :id) " +
"AND (:mailFrom IS NULL OR m.mailFrom = :mailFrom)" +
"AND ( CAST(:receivedBefore AS date) IS NULL OR m.received < :receivedBefore) " +
"AND ( CAST(:receivedAfter AS date) IS NULL OR m.received > :receivedAfter)")
List<Mail> getMailByCustomQuery(
@Param("id") Long id,
@Param("mailFrom") String mailFrom,
@Param("receivedBefore") Date receivedBefore,
@Param("receivedAfter") Date receivedAfter
);
@Query("SELECT m " +
"FROM Mail m LEFT JOIN m.rcptTo to2 " +
"WHERE to2 IN :rcptTo " +
"GROUP BY m.id " +
"HAVING COUNT(DISTINCT to2) = :rcptToLength")
List<Mail> getMailByRecipient(
@Param("rcptTo") List<String> rcptTo,
@Param("rcptToLength") Long rcptToLength
);
}
MailRestController.java
@RestController
@RequestMapping("/mailStore")
public class MailRestController {
private MailRepository repository;
@Inject
public void setRepository(MailRepository repository) {
this.repository = repository;
}
@RequestMapping(method = RequestMethod.POST)
public ResponseEntity<?> addMail(@RequestBody Mail mail) {
return new ResponseEntity<>(repository.save(mail), HttpStatus.CREATED);
}
@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<Collection<Mail>> getMail(
@RequestParam(required = false) Long id,
// Example for timestamp format: 2001-07-22T12:08:56.235-07:00
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX") Date received_before,
@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX") Date received_after,
@RequestParam(required = false) String mail_from) {
return new ResponseEntity<>(repository.getMailByCustomQuery(id, mail_from, received_before, received_after), HttpStatus.OK);
}
@RequestMapping(method = RequestMethod.GET)
public ResponseEntity<Collection<Mail>> getMail(
@RequestParam(required = false) List<String> rcpt_to) {
return new ResponseEntity<>(repository.getMailByRecipient(rcpt_to, (long) rcpt_to.size()), HttpStatus.OK);
}
}
Mail.java (метод получения и установки не указан)
@Entity
@EnableAutoConfiguration
public class Mail {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@JsonProperty("id")
private Long id;
@Column(name = "received")
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX")
@Temporal(TemporalType.TIMESTAMP)
@JsonProperty("received")
private Date received;
@JsonProperty("received_from")
private String receivedFrom;
@JsonProperty("received_by")
private String receivedBy;
@JsonProperty("mail_from")
private String mailFrom;
@JsonProperty("data")
private String data;
@ElementCollection(fetch = FetchType.EAGER, targetClass = String.class)
@CollectionTable(name = "rcptTo")
@Column(name = "Value")
@JsonProperty("rcpt_to")
private List<String> rcptTo = new ArrayList<>();
public Mail(Date received, String receivedFrom, String receivedBy, String mailFrom,
List<String> rcptTo, String data) {
this.received = received;
this.receivedFrom = receivedFrom;
this.receivedBy = receivedBy;
this.mailFrom = mailFrom;
this.rcptTo = rcptTo;
this.data = data;
}