Código Java Spring Boot: repositorio de futbolistas con serialización y API REST de países

InformáticaActualizado el 8,21 KB

Resumen

El documento muestra código Java que implementa un repositorio de futbolistas persistido en un archivo mediante serialización, con operaciones de carga, guardado, consulta, alta, baja y modificación. Incluye también un controlador REST de jugadores y, con Spring Data JPA, un servicio y un controlador REST para países que devuelven códigos HTTP. Los comentarios TODO señalan pendientes como devolver códigos de retorno y HTTP correctos.

Puntos clave

  • La clase Repositorio mantiene una lista de objetos Futbolista y la guarda en el archivo futbolistas.txt mediante ObjectOutputStream.
  • Si la carga del archivo falla, el constructor añade un jugador por defecto (Cristiano Ronaldo).
  • El método modificar elimina el futbolista con el mismo id y lo vuelve a añadir.
  • El controlador de jugadores usa las anotaciones @RestController, @RequestMapping y @GetMapping, @PostMapping, @PutMapping y @DeleteMapping.
  • PaisesService convierte entre el modelo Pais y la entidad PaisEntity mediante métodos de mapeo estáticos.
  • El controlador de países devuelve ResponseEntity con HttpStatus según el resultado: OK, NOT_FOUND, CREATED, NO_CONTENT o INTERNAL_SERVER_ERROR.

Ponte a prueba

Repositorio de futbolistas con persistencia en archivo

La clase Repositorio gestiona una lista de objetos Futbolista y los persiste en un archivo mediante serialización.

public class Repositorio {
    private List<Futbolista> todos;
    private static String RUTA = "futbolistas.txt";

    public Repositorio() {
        super();
        todos = new ArrayList<Futbolista>();
        carga();
    }

    public void carga() {
        System.out.println((new File(RUTA)).getAbsolutePath());
        // Intentamos leer la lista del archivo; si no podemos, creamos un jugador en ella
        try (ObjectInputStream entrada = new ObjectInputStream(new FileInputStream(RUTA))) {
            todos = (List<Futbolista>) entrada.readObject();
        } catch (IOException | ClassNotFoundException e) {
            todos.add(new Futbolista(1, "Cristiano Ronaldo", 7, "Real Madrid", "El Bicho Suu"));
        }
    }

    public boolean guardar() {
        try (ObjectOutputStream cierre = new ObjectOutputStream(new FileOutputStream(RUTA))) {
            cierre.writeObject(todos);
            cierre.close();
            System.out.println("guardado");
        } catch (IOException e1) {
            System.err.println("ERROR GUARDANDO JUGADORES");
            return false;
        }
        return true;
    }

    public List<Futbolista> getAll() {
        return todos;
    }

    public Futbolista getOne(int id) {
        for (Futbolista f : todos) {
            if (f.getId() == id) {
                return f;
            }
        }
        return null;
    }

    public void anadir(Futbolista f) {
        todos.add(f);
        guardar();
    }

    public boolean eliminar(int id) {
        for (int i = 0; i < todos.size(); i++) {
            if (todos.get(i).getId() == id) {
                todos.remove(i);
                guardar();
                return true;
            }
        }
        // todos.remove(getOne(id));
        return false;
    }

    public boolean modificar(Futbolista f) {
        if (eliminar(f.getId())) {
            anadir(f);
            return true;
        }
        return false;
    }
}

//TODO: Devolver códigos de retorno correctos acorde con el resultado de las operaciones.

Controlador REST de jugadores

El controlador expone los endpoints CRUD sobre el recurso jugadores.

// TODO: Devolver códigos HTTP en función de si se pudo crear o no
@RestController
@RequestMapping("jugadores")
public class WebController {

    Repositorio repositorio = new Repositorio();

    @GetMapping
    public List<Futbolista> listaTodos() {
        return repositorio.getAll();
    }

    @GetMapping("{id}")
    public Futbolista lista(@PathVariable int id) {
        return repositorio.getOne(id);
    }

    @PostMapping
    public void crear(@RequestBody Futbolista f) {
        repositorio.anadir(f);
    }

    @DeleteMapping("{id}")
    public void borrar(@PathVariable int id) {
        repositorio.eliminar(id);
    }

    @PutMapping("{id}")
    public void modificar(@PathVariable int id, @RequestBody Futbolista f) {
        if (f.getId() == id) {
            repositorio.modificar(f);
        }
    }
}

Servicio de países con Spring Data JPA

La clase PaisesService encapsula la lógica de acceso a datos y la conversión entre el modelo Pais y la entidad PaisEntity.

@Service
public class PaisesService {
    @Autowired
    private PaisRepository repository;

    public List<Pais> getAll() {
        List<Pais> paises = null;
        List<PaisEntity> paisesBBDD = repository.findAll();
        if (paisesBBDD.size() > 0) {
            paises = paisesBBDD.stream().map(PaisesService::mapToPais).collect(Collectors.toList());
        }
        return paises;
    }

    public Pais getPais(String id) {
        Pais resultado = new Pais();
        PaisEntity pE = repository.findById(id).get();
        if (pE == null) return null;
        return mapToPais(pE);
        // return null;
    }

    public boolean save(Pais pais) {
        PaisEntity res = repository.save(mapToPaisEntity(pais));
        if (res == null) return false;
        else return true;
    }

    public boolean update(String id, Pais pais) {
        boolean result = false;
        System.out.println(id + ":" + pais.getId());
        if (id != null && (pais.getId() == null || id.equals(pais.getId())) && repository.existsById(id)) {
            repository.save(mapToPaisEntity(pais));
            result = true;
        }
        return result;
    }

    public boolean delete(@PathVariable String id) {
        boolean result = false;
        if (id != null && repository.existsById(id)) {
            repository.deleteById(id);
            result = true;
        }
        return result;
    }

    private static Pais mapToPais(PaisEntity entity) {
        Pais pais = new Pais();
        pais.setId(entity.getId());
        pais.setNombre(entity.getName());
        pais.setDescripcion(entity.getDescripcion());
        pais.setRutaFoto(entity.getRutaFoto());
        return pais;
    }

    private static PaisEntity mapToPaisEntity(Pais pais) {
        PaisEntity paisEntity = new PaisEntity();
        paisEntity.setId(pais.getId());
        paisEntity.setNombre(pais.getName());
        paisEntity.setDescripcion(pais.getDescripcion());
        paisEntity.setRutaFoto(pais.getRutaFoto());
        return paisEntity;
    }
}

Controlador REST de países

El controlador de países devuelve objetos ResponseEntity con el código HTTP adecuado a cada operación.

@RestController
@RequestMapping("paises")
public class PaisesController {
    @Autowired
    private PaisesService service;

    @GetMapping
    public ResponseEntity<?> getAll() {
        ResponseEntity<?> response;
        try {
            List<Pais> todosLosPaises = service.getAll();
            if (todosLosPaises.size() > 0) {
                response = new ResponseEntity<List<Pais>>(todosLosPaises, HttpStatus.OK);
            } else {
                response = new ResponseEntity<Void>(HttpStatus.NOT_FOUND);
            }
        } catch (Exception e) {
            response = new ResponseEntity<Void>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return response;
    }

    @GetMapping("{id}")
    public ResponseEntity<?> getPais(@PathVariable String id) {
        ResponseEntity<?> response;
        try {
            Pais pais = service.getPais(id); // DONE: el método del servicio está sin terminar.
            if (pais != null) {
                response = new ResponseEntity<Pais>(pais, HttpStatus.OK);
            } else {
                response = new ResponseEntity<Void>(HttpStatus.NOT_FOUND);
            }
        } catch (Exception e) {
            response = new ResponseEntity<Void>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
        return response;
    }

    @PostMapping
    public ResponseEntity<?> save(@RequestBody Pais pais) {
        // DONE: implementar POST, implementando en el servicio el método save e invocándolo desde aquí.
        if (service.save(pais)) {
            return new ResponseEntity<Void>(HttpStatus.CREATED); // void --> no va nada
        } else {
            return new ResponseEntity<Void>(HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

    @PutMapping("{id}")
    public ResponseEntity<?> update(@RequestBody Pais pais) {
        if (service.update(pais.getId(), pais)) {
            return new ResponseEntity<Void>(HttpStatus.NO_CONTENT);
        } else {
            // TODO: buscar código de error en caso fallido
            return new ResponseEntity<Void>(HttpStatus.NOT_FOUND);
        }
    }

    @DeleteMapping("{id}")
    public ResponseEntity<?> delete(@PathVariable String id) {
        if (service.delete(id)) {
            return new ResponseEntity<Void>(HttpStatus.NO_CONTENT);
        }
        // TODO: buscar código de error en caso fallido
        return null;
    }
}

Descargar

PDF Word HTML

Preguntas frecuentes

¿Cómo se guardan los futbolistas en este código?

La clase Repositorio serializa la lista completa de objetos Futbolista en el archivo futbolistas.txt usando ObjectOutputStream. El método guardar() devuelve true si la escritura tiene éxito y false si se produce un IOException.

¿Qué ocurre si el archivo de futbolistas no existe o no se puede leer?

El método carga() captura la excepción IOException o ClassNotFoundException y añade un futbolista de ejemplo, Cristiano Ronaldo, a la lista.

Ponte a prueba

Tarjetas de repaso

Pulsa una tarjeta para ver la respuesta.

Test

1. ¿En qué archivo guarda sus datos la clase Repositorio?
2. ¿Qué mecanismo usa Repositorio para persistir la lista?
3. ¿Qué hace el método modificar de Repositorio?
4. ¿Qué código HTTP devuelve el controlador de países cuando guarda un país correctamente?
5. ¿Qué devuelve PaisesService.getAll() si no hay países en la base de datos?

Preguntas generadas con IA a partir del documento: comprueba las respuestas con el texto.