BAEL-2060 - Bean Validation in Jersey
This commit is contained in:
@@ -1,12 +1,14 @@
|
||||
package com.baeldung.jersey.server.config;
|
||||
|
||||
import org.glassfish.jersey.server.ResourceConfig;
|
||||
import org.glassfish.jersey.server.ServerProperties;
|
||||
import org.glassfish.jersey.server.mvc.freemarker.FreemarkerMvcFeature;
|
||||
|
||||
public class ViewApplicationConfig extends ResourceConfig {
|
||||
|
||||
public ViewApplicationConfig() {
|
||||
packages("com.baeldung.jersey.server");
|
||||
property(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true);
|
||||
property(FreemarkerMvcFeature.TEMPLATE_BASE_PATH, "templates/freemarker");
|
||||
register(FreemarkerMvcFeature.class);;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.baeldung.jersey.server.constraints;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.validation.Constraint;
|
||||
import javax.validation.ConstraintValidator;
|
||||
import javax.validation.ConstraintValidatorContext;
|
||||
import javax.validation.Payload;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Constraint(validatedBy = { SerialNumber.Validator.class })
|
||||
public @interface SerialNumber {
|
||||
|
||||
String message()
|
||||
|
||||
default "Fruit serial number is not valid";
|
||||
|
||||
Class<?>[] groups() default {};
|
||||
|
||||
Class<? extends Payload>[] payload() default {};
|
||||
|
||||
public class Validator implements ConstraintValidator<SerialNumber, String> {
|
||||
@Override
|
||||
public void initialize(final SerialNumber serial) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid(final String serial, final ConstraintValidatorContext constraintValidatorContext) {
|
||||
final String serialNumRegex = "^\\d{3}-\\d{3}-\\d{4}$";
|
||||
return Pattern.matches(serialNumRegex, serial);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,57 @@
|
||||
package com.baeldung.jersey.server.model;
|
||||
|
||||
import javax.validation.constraints.Min;
|
||||
import javax.validation.constraints.Size;
|
||||
import javax.xml.bind.annotation.XmlRootElement;
|
||||
|
||||
@XmlRootElement
|
||||
public class Fruit {
|
||||
|
||||
private final String name;
|
||||
private final String colour;
|
||||
@Min(value = 10, message = "Fruit weight must be 10 or greater")
|
||||
private Integer weight;
|
||||
@Size(min = 5, max = 200)
|
||||
private String name;
|
||||
@Size(min = 5, max = 200)
|
||||
private String colour;
|
||||
private String serial;
|
||||
|
||||
public Fruit() {
|
||||
}
|
||||
|
||||
public Fruit(String name, String colour) {
|
||||
this.name = name;
|
||||
this.colour = colour;
|
||||
}
|
||||
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public void setColour(String colour) {
|
||||
this.colour = colour;
|
||||
}
|
||||
|
||||
public String getColour() {
|
||||
return colour;
|
||||
}
|
||||
|
||||
public Integer getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public void setWeight(Integer weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
public String getSerial() {
|
||||
return serial;
|
||||
}
|
||||
|
||||
public void setSerial(String serial) {
|
||||
this.serial = serial;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.baeldung.jersey.server.providers;
|
||||
|
||||
import javax.validation.ConstraintViolation;
|
||||
import javax.validation.ConstraintViolationException;
|
||||
import javax.ws.rs.core.Response;
|
||||
import javax.ws.rs.ext.ExceptionMapper;
|
||||
|
||||
public class FruitExceptionMapper implements ExceptionMapper<ConstraintViolationException> {
|
||||
|
||||
@Override
|
||||
public Response toResponse(final ConstraintViolationException exception) {
|
||||
return Response.status(Response.Status.BAD_REQUEST)
|
||||
.entity(prepareMessage(exception))
|
||||
.type("text/plain")
|
||||
.build();
|
||||
}
|
||||
|
||||
private String prepareMessage(ConstraintViolationException exception) {
|
||||
final StringBuilder message = new StringBuilder();
|
||||
for (ConstraintViolation<?> cv : exception.getConstraintViolations()) {
|
||||
message.append(cv.getPropertyPath() + " " + cv.getMessage() + "\n");
|
||||
}
|
||||
return message.toString();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,7 +5,13 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.FormParam;
|
||||
import javax.ws.rs.GET;
|
||||
import javax.ws.rs.POST;
|
||||
import javax.ws.rs.PUT;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.Produces;
|
||||
@@ -15,7 +21,9 @@ import org.glassfish.jersey.server.mvc.ErrorTemplate;
|
||||
import org.glassfish.jersey.server.mvc.Template;
|
||||
import org.glassfish.jersey.server.mvc.Viewable;
|
||||
|
||||
import com.baeldung.jersey.server.constraints.SerialNumber;
|
||||
import com.baeldung.jersey.server.model.Fruit;
|
||||
import com.baeldung.jersey.service.SimpleStorageService;
|
||||
|
||||
@Path("/fruit")
|
||||
public class FruitResource {
|
||||
@@ -52,4 +60,49 @@ public class FruitResource {
|
||||
return name;
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/create")
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
public void createFruit(
|
||||
@NotNull(message = "Fruit name must not be null") @FormParam("name") String name,
|
||||
@NotNull(message = "Fruit colour must not be null") @FormParam("colour") String colour) {
|
||||
|
||||
Fruit fruit = new Fruit(name, colour);
|
||||
SimpleStorageService.storeFruit(fruit);
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("/update")
|
||||
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
|
||||
public void updateFruit(@SerialNumber @FormParam("serial") String serial) {
|
||||
Fruit fruit = new Fruit();
|
||||
fruit.setSerial(serial);
|
||||
SimpleStorageService.storeFruit(fruit);
|
||||
}
|
||||
|
||||
@POST
|
||||
@Path("/create")
|
||||
@Consumes(MediaType.APPLICATION_JSON)
|
||||
public void createFruit(@Valid Fruit fruit) {
|
||||
SimpleStorageService.storeFruit(fruit);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Valid
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/search/{name}")
|
||||
public Fruit findFruitByName(@PathParam("name") String name) {
|
||||
return SimpleStorageService.findByName(name);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Produces(MediaType.TEXT_HTML)
|
||||
@Path("/exception")
|
||||
@Valid
|
||||
public Fruit exception() {
|
||||
Fruit fruit = new Fruit();
|
||||
fruit.setName("a");
|
||||
fruit.setColour("b");
|
||||
return fruit;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.baeldung.jersey.service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.baeldung.jersey.server.model.Fruit;
|
||||
|
||||
public class SimpleStorageService {
|
||||
|
||||
private static final Map<String, Fruit> fruits = new HashMap<String, Fruit>();
|
||||
|
||||
public static void storeFruit(final Fruit fruit) {
|
||||
fruits.put(fruit.getName(), fruit);
|
||||
}
|
||||
|
||||
public static Fruit findByName(final String name) {
|
||||
return fruits.entrySet()
|
||||
.stream()
|
||||
.filter(map -> name.equals(map.getKey()))
|
||||
.map(map -> map.getValue())
|
||||
.findFirst()
|
||||
.get();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user