Spring Boot
Diseño Web

Instalación

  1. Instalamos Spring tools
  2. start.spring.io
    • group (nombre del paquete): com.pablomonteserin.prueba
    • artifact (nombre del proyecto): PruebaPersistencia
    • Dependencies:
      • Web
      • JPA
      • MySQL
      • (Más adelante está explicado como cargar JSTL)
  3. Descargamos y descomprimimos el fichero
  4. Eclipse -> Import -> Existing Maven Project
  5. Botón derecho sobre el pom.xml Run as -> Run configurations
    • Name: Lo que quieras
    • Goals: clean install (limpia la carpeta target con los ficheros que se han ido compilando e instala las dependencias descritas el pom.xml)

Configuración para usar base de datos

Si hemos seleccionado con start.spring.io un proyecto que usa JPA y no configuramos la conexión, el proyecto no arrancará.

@Configuration
@EnableTransactionManagement
public class PruebaPersistenceConfiguration {

@Bean
public DataSource dataSource(){
	DriverManagerDataSource dataSource = new DriverManagerDataSource();
	dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
	dataSource.setUrl("jdbc:mysql://localhost:3306/libro?serverTimezone=UTC");
	dataSource.setUsername( "pm" );
	dataSource.setPassword( "pp" );
	return dataSource;
}
}

Proyecto Prueba

Vista

./src/main/webapp/index.html<form action="/createPersona">
<input type="text" name="nombre">
<input type="submit" value="Alta">
</form>

Controlador

com.pablomonteserin.prueba.controller.PersonaController@Controller // @RestController
public class PersonaController {	
	
	@Autowired
	private PersonaRepository personaRepository;
	
	@RequestMapping(path = "/createPersona", method = RequestMethod.GET)
	public String submit(@ModelAttribute("persona")Persona persona, ModelMap model) throws IOException{
		personaRepository.save(persona);
		return "redirect:index.html";
	}
}
Otros ejemplos de controlador
Recuperando datos sin asociarlos
automáticamente al bean del modelo
@RequestMapping(path = "/createPaciente", method = RequestMethod.GET) public String createPaciente(@ModelAttribute("nombre")String nombre, @ModelAttribute("apellidos")String apellidos,@ModelAttribute("fecha_alta")String fechaAlta,ModelMap model) { Paciente paciente = new Paciente(); paciente.setNombre(nombre); paciente.setApellidos(apellidos); try { Date fechaAltaDate=simpleDateFormat.parse(fechaAlta); paciente.setFecha_alta(fechaAltaDate); } catch (ParseException e) { e.printStackTrace(); System.out.println("Algo salió mal"); } pacienteRepository.save(paciente); return "redirect:index.html"; }
Yendo a una vista en la que se cargarán los datos@RequestMapping(path = "/consultaPacientes", method = RequestMethod.GET)
public ModelAndView consultaPacientes(ModelMap model) {
	Iterable<Paciente> pacientes = pacienteRepository.findAll();
	ModelAndView modelo = new ModelAndView("consulta");
	model.addAttribute("pacientes", pacientes);
	return modelo;
}

Modelo

com.pablomonteserin.prueba.persistence.repository.Persona;public interface PersonaRepository extends CrudRepository<Persona, Integer> {

}
com.pablomonteserin.prueba.config.PruebaConfiguration
(configuración del acceso a la base de datos)@Configuration @EnableJpaRepositories(basePackages = "com.pablomonteserin.prueba.persistence.repository") @EnableTransactionManagement public class PruebaConfiguration { @Bean public PlatformTransactionManager transactionManager(EntityManagerFactory emf) { JpaTransactionManager transactionManager = new JpaTransactionManager(); transactionManager.setEntityManagerFactory(emf); return transactionManager; } @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); em.setDataSource(dataSource()); em.setPackagesToScan("com.pablomonteserin.prueba.persistence.model"); JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); em.setJpaVendorAdapter(vendorAdapter); em.setJpaProperties(additionalProperties()); return em; } @Bean public DataSource dataSource(){ DriverManagerDataSource dataSource = new DriverManagerDataSource(); dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver"); dataSource.setUrl("jdbc:mysql://localhost:3306/persona?serverTimezone=UTC"); dataSource.setUsername( "pm" ); dataSource.setPassword( "pp" ); return dataSource; } private Properties additionalProperties() { Properties properties = new Properties(); properties.setProperty("hibernate.hbm2ddl.auto", "create"); properties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect"); return properties; } }

Aplicación

Este fichero se coloca habitualmente en la raíz del árbol de directorios del proyecto. Este fichero es el que se lanza cuando hacemos run as.

com.pablomonteserin.PruebaApplication@SpringBootApplication
public class PruebaApplication {

	public static void main(String[] args) {
		SpringApplication.run(PruebaApplication.class, args);
	}

}

Cargar JSTL

Debemos definir en el pom.xml que el empaquetado de la aplicación será war, puesto que es una aplicación web.

pom.xml<packaging>war</packaging>

También en el pom.xml debemos cargar las dependencias para usar JSTL.

<!--  Para Usar JSTL -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
</dependency>
		
<!--  Para Usar JSTL con Spring -->
<dependency>
	<groupId>org.apache.tomcat.embed</groupId>
	<artifactId>tomcat-embed-jasper</artifactId>
	<scope>provided</scope>
</dependency>

Los ficheros JSP serán almacenados en la ruta:

./src/main/webapp/WEB-INF/jsp/consulta.jsp

Modificaremos el application properties para que use lo que hay en esa ruta:

./src/main/resources/application.propertiesspring.mvc.view.prefix=/WEB-INF/jsp/
spring.mvc.view.suffix=.jsp

Enrutamiento automático

@Configuration
@EnableWebMvc
public class WebConfiguration implements WebMvcConfigurer  {
	@Override
	public void addViewControllers(ViewControllerRegistry registry) {
		registry.addViewController("/").setViewName("index");
		// Obtiene el nombre de la vista en base a la url.
		// Ejemplo: /view/cosas -> /weapp/WEB-INF/cosas.jsp    
		registry.addViewController("/view/**");   
	}
}

Ejercicios Spring Boot

Ejercicio - invitados

Hacer una página web para una lista de invitados con 4 secciones. Una para consultar los invitados, otra para dar de alta un nuevo invitado y otra para darlo de baja.La tabla que usaremos tendrá dos campos: nombre (VARCHAR) e ID (INT, AUTOINCREMENT, PK).

Cada uno de los siguientes pantallazos representa una página diferente.

menu aplicación con spring boot y mysql alta con spring boot y mysql baja con spring boot y mysql baja con spring boot y mysql

Patrones de diseño

Patrones arquitectónicos

Modelo de tres capas

Ejercicio hospital

ejercicio crud hospital con spring boot

Para evitar que en spring la fecha se guarde correctamente sin poner un día de menos:

SimpleDateFormar fADate = new SimpleDateFormat("yyyy-MM-dd");
fADate.setTimeZone(TimeZone.getTimeZone("PST"));

Ejercicio mensajería

Para acceder a la sesión desde el controlador:@RequestMapping(path = "/createMensajes", method = RequestMethod.GET)
public ModelAndView createMensaje(@ModelAttribute("mensaje")String mensaje,@ModelAttribute("ids[]")String ids[],HttpServletRequest request,ModelMap model) {
	HttpSession session = request.getSession();

Enviar y recoger un array de datos al servidor utilizando Spring Boot

<c:forEach var="usuario" items="${usuarios}"  varStatus="status">
	<li><input name="ids[${status.index}]" type="checkbox" value="${usuario.id}">
	<c:out value="${usuario.nombre}" /></li>
</c:forEach>
Arrays.stream(mensaje.getIds()).filter(id -> id!=null).forEach(id->{
	//El código que procesa la petición
});
@Entity
public class Mensaje {
	...
	@Transient
	Integer ids[];
request.getParameterValues("ids")

Recoger un array de datos del servidor utilizando SpringBoot

También hubiera sido posible recoger los datos dándoles a todas las checkboxes el mismo name y utilizando en el controlador el método:

Petición Rest

@Controller
public class MensajeController {

@RequestMapping(value = "/findAll",method=RequestMethod.GET)
public Iterable<Equipo> findAll(){
	Iterable<Equipo> equipos = equipoRepository.findAll();
	return equipos;
}

Enable CORS

com.pablomonteserin.proyecto.configuration.WebConfiguration@Configuration
@EnableWebMvc
public class WebConfiguration implements WebMvcConfigurer  {	
	@Override
	public void addCorsMappings(CorsRegistry registry) {
		registry.addMapping("/**").allowedMethods("GET","POST").allowedOrigins("*");
	}
}
icono de mandar un mailSOPORTE Usuarios Premium
Pablo Monteserín
contacta conmigoPablo
Monteserín

Para dudas técnicas sobre los ejercicios de mis cursos es necesario tener una cuenta premium activa. Para cualquier otra cosa, puedes usar el formulario de la página de contacto.