diff --git a/TD4/src/main/java/fr/miage23/filestore/api/dto/InputNodeDto.java b/TD4/src/main/java/fr/miage23/filestore/api/dto/InputNodeDto.java
index d616d50266a6c2a1f4501fba6281bd259785aa7e..8ac12404e109ff1a7c28a495a2750c3fe213d47c 100644
--- a/TD4/src/main/java/fr/miage23/filestore/api/dto/InputNodeDto.java
+++ b/TD4/src/main/java/fr/miage23/filestore/api/dto/InputNodeDto.java
@@ -1,5 +1,7 @@
 package fr.miage23.filestore.api.dto;
 
+import jakarta.validation.constraints.Pattern;
+import jakarta.validation.constraints.Size;
 import jakarta.ws.rs.FormParam;
 import jakarta.ws.rs.core.MediaType;
 import org.jboss.resteasy.annotations.providers.multipart.PartType;
@@ -10,10 +12,13 @@ public class InputNodeDto {
 
     @FormParam("name")
     @PartType(MediaType.TEXT_PLAIN)
-    private String name = null;
+    @Pattern(regexp = "^[^*&%/]+$")
+    private String name;
     @FormParam("data")
     @PartType(MediaType.APPLICATION_OCTET_STREAM)
     private InputStream data = null;
+    @Size(max=2000000, message="content size is 2Mo max, for larger content use a multipart-form-data with data parameter")
+    private byte[] content;
 
     public InputNodeDto() {
         // Default constructor needed for JAX-RS
@@ -35,5 +40,13 @@ public class InputNodeDto {
         this.data = data;
     }
 
+    public byte[] getContent() {
+        return content;
+    }
+
+    public void setContent(byte[] content) {
+        this.content = content;
+    }
+
 }
 
diff --git a/TD4/src/main/java/fr/miage23/filestore/api/dto/POSTNodeDto.java b/TD4/src/main/java/fr/miage23/filestore/api/dto/POSTNodeDto.java
index ce8e8d8e0792dcb86bc56772686d3c2faf44ceb9..3ee39708caf59c335556e03f2e5159015d691f38 100644
--- a/TD4/src/main/java/fr/miage23/filestore/api/dto/POSTNodeDto.java
+++ b/TD4/src/main/java/fr/miage23/filestore/api/dto/POSTNodeDto.java
@@ -3,6 +3,7 @@ package fr.miage23.filestore.api.dto;
 import fr.miage23.filestore.TypeNode;
 
 public class POSTNodeDto {
+
     private String id = null;
     private String name = null;
     private TypeNode type = null;
diff --git a/TD4/src/main/java/fr/miage23/filestore/api/resources/NodesResource.java b/TD4/src/main/java/fr/miage23/filestore/api/resources/NodesResource.java
index ea19e4283ed2fe05eecc3fa8c037dd192f1758c1..202cb7cddb41752a8cf8ca339f55727de0546baf 100644
--- a/TD4/src/main/java/fr/miage23/filestore/api/resources/NodesResource.java
+++ b/TD4/src/main/java/fr/miage23/filestore/api/resources/NodesResource.java
@@ -79,22 +79,18 @@ public class NodesResource {
     @Produces(MediaType.APPLICATION_JSON)
     public Response content(@PathParam("id") final String id, @QueryParam("limit") @DefaultValue("10") int limit, @QueryParam("offset") @DefaultValue("0") int offset) throws NodeNotFoundException, NodeTypeException, ContentException {
         LOGGER.log(Level.INFO, "GET /api/nodes/" + id + "/content");
-        try {
-            Node node = service.get(id);
-            if (node.getType().equals(TypeNode.TREE)) {
-                CollectionDto<Node> dto = new CollectionDto(limit, offset);
-                List<Node> nodes = service.list(node.getId());
-                dto.setValues(nodes.stream().skip(offset).limit(limit).collect(Collectors.toList()));
-                dto.setSize(nodes.size());
-                return Response.ok(dto).build();
-            } else {
-                return Response.ok(service.getContent(id))
-                        .header("Content-Type", node.getMimetype())
-                        .header("Content-Length", node.getSize())
-                        .header("Content-Disposition", "attachment; filename=" + node.getName()).build();
-            }
-        } catch (NodeNotFoundException e) {
-            return Response.status(Response.Status.NOT_FOUND).entity("Node not found.").build();
+        Node node = service.get(id);
+        if (node.getType().equals(TypeNode.TREE)) {
+            CollectionDto<Node> dto = new CollectionDto(limit, offset);
+            List<Node> nodes = service.list(node.getId());
+            dto.setValues(nodes.stream().skip(offset).limit(limit).collect(Collectors.toList()));
+            dto.setSize(nodes.size());
+            return Response.ok(dto).build();
+        } else {
+            return Response.ok(service.getContent(id))
+                    .header("Content-Type", node.getMimetype())
+                    .header("Content-Length", node.getSize())
+                    .header("Content-Disposition", "attachment; filename=" + node.getName()).build();
         }
     }
 
@@ -108,20 +104,16 @@ public class NodesResource {
     @GET
     @Path("{id}")
     @Produces({MediaType.TEXT_HTML, MediaType.APPLICATION_JSON})
-    public Response getNode(@PathParam("id") String id) {
+    public Response getNode(@PathParam("id") String id) throws NodeNotFoundException {
         LOGGER.log(Level.INFO, "GET /api/nodes/" + id);
-        try{
-            Gson gson = new GsonBuilder()
-                    .registerTypeAdapter(TypeNode.class, new EnumTypeAdapter())
-                    .create();
-            Node node = service.get(id);
-            return Response.ok(gson.toJson(
-                            (new GETNodeDto(node.getType(), node.getId(), node.getParent(), node.getName(), node.getSize(), node.getCreation(), node.getModification())),
-                            GETNodeDto.class),
-                    MediaType.APPLICATION_JSON).build();
-        } catch (NodeNotFoundException e) {
-            return Response.status(Response.Status.NOT_FOUND).entity("Node not found.").build();
-        }
+        Gson gson = new GsonBuilder()
+                .registerTypeAdapter(TypeNode.class, new EnumTypeAdapter())
+                .create();
+        Node node = service.get(id);
+        return Response.ok(gson.toJson(
+                        (new GETNodeDto(node.getType(), node.getId(), node.getParent(), node.getName(), node.getSize(), node.getCreation(), node.getModification())),
+                        GETNodeDto.class),
+                MediaType.APPLICATION_JSON).build();
     }
 
     /**
@@ -135,33 +127,23 @@ public class NodesResource {
     @POST
     @Path("{id}")
     @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
-    public Response createNode(@PathParam("id") String id, @FormParam("name") String name, @Context UriInfo info) {
+    public Response createNode(@PathParam("id") String id, @FormParam("name") String name, @Context UriInfo info) throws NodeNotFoundException, NodeTypeException, NodeAlreadyExistsException {
         LOGGER.log(Level.INFO, "POST /api/nodes/" + id);
-        try {
-            String newid;
-            if (name != null) {
-                newid = service.add(id, name);
-            } else {
-                throw new IllegalArgumentException("A name must be provided");
-            }
-            Gson gson = new GsonBuilder()
-                    .registerTypeAdapter(TypeNode.class, new EnumTypeAdapter())
-                    .create();
-            Node node = service.get(newid);
-
-            return Response.ok(gson.toJson(
-                            (new POSTNodeDto(node.getId(), node.getName(), node.getType())),
-                            POSTNodeDto.class),
-                    MediaType.APPLICATION_JSON).build();
-        } catch (IllegalArgumentException e) {
-            // Transform the IllegalArgumentException into a 400 Bad Request response
-            return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
-        } catch (NodeNotFoundException e) {
-            return Response.status(Response.Status.NOT_FOUND).entity("Node not found.").build();
-        } catch (NodeTypeException | NodeAlreadyExistsException e) {
-            // Handle other exceptions as needed, possibly transforming them into different HTTP responses
-            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("An unexpected error occurred.").build();
+        String newid;
+        if (name != null) {
+            newid = service.add(id, name);
+        } else {
+            throw new IllegalArgumentException("A name must be provided");
         }
+        Gson gson = new GsonBuilder()
+                .registerTypeAdapter(TypeNode.class, new EnumTypeAdapter())
+                .create();
+        Node node = service.get(newid);
+
+        return Response.ok(gson.toJson(
+                        (new POSTNodeDto(node.getId(), node.getName(), node.getType())),
+                        POSTNodeDto.class),
+                MediaType.APPLICATION_JSON).build();
     }
 
     /**
@@ -176,37 +158,27 @@ public class NodesResource {
     @Path("{id}")
     @Produces(MediaType.TEXT_HTML)
     @Consumes(MediaType.MULTIPART_FORM_DATA)
-    public Response createView(@PathParam("id") final String id, @MultipartForm @Valid InputNodeDto dto, @Context UriInfo info) {
+    public Response createView(@PathParam("id") final String id, @MultipartForm @Valid InputNodeDto dto, @Context UriInfo info) throws NodeNotFoundException, NodeTypeException, NodeAlreadyExistsException, ContentException {
         LOGGER.log(Level.INFO, "POST /api/nodes/" + id + " (html)");
-        try {
-            String newid;
-            if (dto.getName() != null && dto.getData() != null){
-                newid = service.add(id, dto.getName(), dto.getData());
-            } else if (dto.getName() != null){
-                newid = service.add(id, dto.getName());
-            } else {
-                throw new IllegalArgumentException("A name must be provided");
-            }
-            Gson gson = new GsonBuilder()
-                    .registerTypeAdapter(TypeNode.class, new EnumTypeAdapter())
-                    .create();
-            Node node = service.get(newid);
-            return Response.ok(gson.toJson(
-                            (new POSTNodeDto(node.getId(), node.getName(), node.getType())),
-                            POSTNodeDto.class),
-                    MediaType.APPLICATION_JSON).build();
-        } catch (IllegalArgumentException e) {
-            // Transform the IllegalArgumentException into a 400 Bad Request response
-            return Response.status(Response.Status.BAD_REQUEST).entity(e.getMessage()).build();
-        } catch (NodeNotFoundException e) {
-            return Response.status(Response.Status.NOT_FOUND).entity("Node not found.").build();
-        } catch (NodeTypeException | NodeAlreadyExistsException | ContentException e) {
-            // Handle other exceptions as needed, possibly transforming them into different HTTP responses
-            return Response.status(Response.Status.INTERNAL_SERVER_ERROR).entity("An unexpected error occurred.").build();
+        String newid;
+        if (dto.getName() != null && dto.getData() != null){
+            newid = service.add(id, dto.getName(), dto.getData());
+        } else if (dto.getName() != null){
+            newid = service.add(id, dto.getName());
+        } else {
+            throw new IllegalArgumentException("A name must be provided");
         }
+        Gson gson = new GsonBuilder()
+                .registerTypeAdapter(TypeNode.class, new EnumTypeAdapter())
+                .create();
+        Node node = service.get(newid);
+        return Response.ok(gson.toJson(
+                        (new POSTNodeDto(node.getId(), node.getName(), node.getType())),
+                        POSTNodeDto.class),
+                MediaType.APPLICATION_JSON).build();
     }
 
-    // Classe EnumTypeAdapter pour la gestion de la sérialisation/désérialisation de l'énumération Node.Type
+    // Classe EnumTypeAdapter pour la gestion de la sérialisation/désérialisation de l'énumération TypeNode
     private static class EnumTypeAdapter extends TypeAdapter<TypeNode> {
         @Override
         public void write(JsonWriter out, TypeNode value) throws IOException {
diff --git a/TD4/src/main/java/fr/miage23/filestore/api/validation/Filename.java b/TD4/src/main/java/fr/miage23/filestore/api/validation/Filename.java
new file mode 100644
index 0000000000000000000000000000000000000000..c11e79e7c18c2b66681699fce14e13191560134a
--- /dev/null
+++ b/TD4/src/main/java/fr/miage23/filestore/api/validation/Filename.java
@@ -0,0 +1,21 @@
+package fr.miage23.filestore.api.validation;
+
+import jakarta.validation.Constraint;
+import jakarta.validation.Payload;
+import jakarta.validation.constraints.Pattern;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target({ElementType.FIELD, ElementType.PARAMETER})
+@Constraint(validatedBy={})
+@Retention(RetentionPolicy.RUNTIME)
+@Pattern(regexp=ValidationPattern.FILE_PATTERN)
+public @interface Filename {
+    String message() default "{invalid.filename_FR}";
+    Class<?>[] groups() default {};
+    Class<? extends Payload>[] payload() default {};
+}
+
diff --git a/TD4/src/main/java/fr/miage23/filestore/api/validation/ValidationPattern.java b/TD4/src/main/java/fr/miage23/filestore/api/validation/ValidationPattern.java
new file mode 100644
index 0000000000000000000000000000000000000000..96cbd79a07686e82f050c796455a5031068e0466
--- /dev/null
+++ b/TD4/src/main/java/fr/miage23/filestore/api/validation/ValidationPattern.java
@@ -0,0 +1,6 @@
+package fr.miage23.filestore.api.validation;
+
+public class ValidationPattern {
+    public static final String FILE_PATTERN = "^[^*&%/]+$";
+}
+