lunes, 26 de agosto de 2019

Spring Boot Web Protos

Spring Boot Web Protos


https://github.com/jalbertomr/springBootWebProtos.git

Spring initializr
Logger

Se agregan Capas
Repository  --  Lenguaje Orientado a Datos.
Service        -- Lenguaje Orientado a Negocio.

En Repository se agrega Interface IPersonaRepo y su Clase que la implementa para desacoplar.

En Service se agrega Interface IPersonaService y su Clase que la implementa.

La instanciación de las clases PersonaRepoImpl y PersonaServiceImpl por el momento se implementan manualmente con new. (la desventaja de esto es que por cada cliente se creará una instanciación de estas clases).

Estructura del Proyecto.

Al ejecutar podemos ver los mensajes de log.

2019-08-23 19:47:07.722  INFO 13010 --- [           main] com.bext.SpringBootWebApplication        : Logging en SpringBoot.
2019-08-23 19:47:07.722  INFO 13010 --- [           main] com.bext.SpringBootWebApplication        : Service Alta Persona: Juan Perez
2019-08-23 19:47:07.723  INFO 13010 --- [           main] com.bext.SpringBootWebApplication        : Repository Persistiendo Persona: Juan Perez
2019-08-23 19:47:20.316  INFO 13010 --- [on(2)-127.0.0.1] inMXBeanRegistrar$SpringApplicationAdmin : Application shutdown requested.
2019-08-23 19:47:20.319  INFO 13010 --- [on(2)-127.0.0.1] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'

Usando Estereotipos para instanciar Clases.


   Para no hacer la instanciación manual, nos apoyamos de spring framework con estereotipos como  @Repository (@Bean para el nivel Repository) , @Service (@Bean para el nivel Service) , tambien existe @Component o el mismo @Bean.

  Eliminamos la instanciación manual con new y las clases se califican con @Repository y @Service y con @Autowired se le indica al framework que se encarge de manejar su instanciación.

   Al ejecutarlo el resultado es el mismo. Incluso si utilizamos indistintamente los estereotipos  @Service, @Repository, @Component.

https://github.com/jalbertomr/springBootWebProtos/commit/f34b2bef0c962354227847fd1af7f816c098db28

Distinguiendo Beans


Crearemos otro Bean de PersonaRepoImpl2, el cual es calificado con @Repository e implementa IPersonaRepo, De esta forma cuando @Autowired intenta instanciar IPersonaRepo, encuentra que hay dos, y no sabe cual usar, esto nos lo hace saber con el mensaje siguiente al ejecutar la app.

Field personaRepo in com.bext.service.PersonaServiceImpl required a single bean, but 2 were found:
    - personaRepoImpl: defined in file [/home/bext/eclipse-workspace/springBootWebProtos/target/classes/com/bext/repository/PersonaRepoImpl.class]
    - personaRepoImpl2: defined in file [/home/bext/eclipse-workspace/springBootWebProtos/target/classes/com/bext/repository/PersonaRepoImpl2.class]


Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

Si calificamos alguno de los dos con @Primary tomará este bean y no habrá ya el problema. Le ponemos @Primary al a PersonaRepoImpl2 y la respuesta es

2019-08-23 20:52:54.373  INFO 31353 --- [           main] com.bext.SpringBootWebApplication        : Logging en SpringBoot.
2019-08-23 20:52:54.374  INFO 31353 --- [           main] com.bext.SpringBootWebApplication        : Service Alta Persona: Juan Perez
2019-08-23 20:52:54.374  INFO 31353 --- [           main] com.bext.SpringBootWebApplication        : Repository2 Persistiendo Persona: Juan Perez

El log nos confirma que está utilizando el Bean PersonaRepoImpl2.

https://github.com/jalbertomr/springBootWebProtos/commit/f34b2bef0c962354227847fd1af7f816c098db28

Tambien podemos usar @Qualifier

@Repository
@Qualifier("PersonaRepo1")
public class PersonaRepoImpl implements IPersonaRepo {
...


En el otro bean

@Repository
@Qualifier("PersonaRepo2")
public class PersonaRepoImpl2 implements IPersonaRepo {
...


Al instanciarlo con @Autowired en Service lo calificamos y ese utilizará.

   @Autowired
   @Qualifier("PersonaRepo2")
    private IPersonaRepo personaRepo;


https://github.com/jalbertomr/springBootWebProtos/commit/d1943f72828be9f0c40500b0fa1569f2282221e3



eot

jueves, 15 de agosto de 2019

Spring Boot Web MVC Security custom Login Actualizacion Starter 1.5.2->2.1.7

Spring Boot Web MVC Security custom Login Actualizacion Starter 1.5.2->2.1.7


   La creación del proyecto con spring initializer https://jalbertomr.blogspot.com/2019/08/spring-boot-web-mvc-security-custom.html le asignó la versión al spring starter en el pom.xml a 2.1.7 que no era compatible con el código, Ahora se actualiza de la 1.5.2 a 2.1.7, esto implica agregar algunos ajustes a EmployeeSecurityConfiguration.java, se le regresa un noOpPasswordEncoder por el momento.

...
public class EmployeeSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return NoOpPasswordEncoder.getInstance();
    }
    ...


y tambien se modifica en altaEmpleado.jsp commandName por modelAttribute, ya que así lo requiere la actualización.

https://github.com/jalbertomr/bootWebMVCSecLogin/commit/125df8f0fa91b6209745accf220d85383a833f0e

eot

miércoles, 14 de agosto de 2019

Spring Boot Web MVC Security custom Login

Spring Boot Web MVC Security custom Login



Al anterior post se le agrega una forma de login customizado.
https://jalbertomr.blogspot.com/2019/08/spring-boot-web-mvc.html

Se crea un controlador para el login y un jsp
https://github.com/jalbertomr/bootWebMVCSecLogin/commit/33038795bfd207bf3d1b6bc7f91dd2bc4f3a0de9


loginController.java

@Controller
public class LoginController {
    private static final Logger logger = LoggerFactory.getLogger(ListEmployeeController.class);
   
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String login(Model model, String error, String logout) {
        if (error != null) {
            model.addAttribute("errorMsg", "El Usuario y/o Clave son incorrectos.");
        }
        if (logout != null) {
            model.addAttribute("msg", "Se ha Desautenticado Satisfactoriamente.");
        }
        return "login";
    }
}


login.jsp

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

<c:set var="contextPath" value="${pageContext.request.contextPath}"/>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
    <meta name="description" content="">
    <meta name="author" content="">

    <title>Autenticacion con credenciales</title>

    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
</head>

<body>

<div class="container">

    <form method="POST" action="${contextPath}/login" class="form-signin">
        <h2 class="form-heading">Autenticación</h2>

        <div class="form-group ${error != null ? 'hayError' : ''}">
            <span>${msg}</span>
            <input name="username" type="text" class="form-control" placeholder="Usuario"
                   autofocus="true"/>
            <input name="password" type="password" class="form-control" placeholder="Clave"/>
            <span>${errorMsg}</span>

            <button class="btn btn-lg btn-primary btn-block" type="submit">Autenticarse</button>
        </div>

    </form>

</div>
<!-- /container -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script></body>
</html>



Se ejecuta






eot

domingo, 11 de agosto de 2019

Spring Boot Web MVC Security

Spring Boot Web MVC Security


https://github.com/jalbertomr/bootWebMVCSecLogin.git

Relación de Seguridad de Acceso

Usuario      Role          Páginas Accesibles       Páginas NO Accesibles
bext            USER        Inicio
                   ADMIN     listaEmpleados                -----------
                                    altaEmpleados
employee    USER       listaEmpleados              altaEmpleados
          
Se crea el proyecto con sprint initializr, y se ajusta la versión de spring security
a una menor en el pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bext</groupId>
    <artifactId>bootWebMVCSecLogin</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>bootWebMVCSecLogin</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <!-- <version>1.5.2.RELEASE</version>  -->
        <!--  <version>2.1.7.RELEASE</version>  Esta version la inserto el spring initiz aqui no compatible -->
        <version>1.5.2.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>


    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
        </dependency>
        <!-- Servlet -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>


La configuración de seguridad se hace por codificación java.

@Configuration
@EnableWebSecurity
public class EmployeeSecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/resources/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests().antMatchers("/").permitAll().antMatchers("/inicio")
        .hasAnyRole("USER","ADMIN").antMatchers("/listaEmpleados").hasAnyRole("USER","ADMIN")
        .antMatchers("/altaEmpleado").hasAnyRole("ADMIN").anyRequest().authenticated()
        .and().formLogin().permitAll().and().logout().permitAll();
       
        http.csrf().disable();
    }
   
    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder authenticationMgr) throws Exception {
        authenticationMgr.inMemoryAuthentication()
        .withUser("empleado").password("empleado").authorities("ROLE_USER")
        .and()
        .withUser("bext").password("bext").authorities("ROLE_USER","ROLE_ADMIN");
    }
}


Estructura del proyecto


Ejecutando el Proyecto










eot

sábado, 10 de agosto de 2019

Spring Boot Web Security thymeleaf

Spring Boot Web Security thymeleaf

   referencia Securing a Web Application https://spring.io/guides/gs/securing-web/

   Thymeleaf es una librería java para elaborar aplicaciones web. Se crea un proyecto con una estructura que se contruye a mano. de momento no se encontró un template para elaborar la estructura del proyecto, así que se hace partiendo del ejemplo de la referencia. Crearemos una estructura básica en spring boot web thymeleaf sin seguridad y después le aplicaremos seguridad con spring.

Creamos un nuevo proyecto maven, para posteriormente ajustar el pom de acuderdo al prototipo de referencia. se agrega al pom parent, dependencies, properties, plugins.

sin seguridad https://github.com/jalbertomr/springBootWebSecurityThymeleaf/commit/e51721693a119a9511de976944311b0e1492d04a

pom.xml con spring security deshabilitado.
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.bext</groupId>
    <artifactId>springBootWebSecurityThymeleaf</artifactId>
    <version>1</version>
    <name>springBootWebSecurityThymeleaf</name>
    <description>springBoot Web Security Thymeleaf</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- tag::security[]
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        -->
        <!-- end::security[] -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!--
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
         -->
    </dependencies>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>


Estructura del proyecto


La configuración del flujo de las páginas se hace por medio de códificación java a diferencia de hacerlo en xml. en MvcConfig.java, en /resources/templates tenemos las páginas html. home y paso2.

Ejecutamos el proyecto



Ahora implementamos la seguridad. Se habilitan las dependencias de seguridad en el pom.xml. Se crea la página login.html, se modifican las otras para dar lugar al login/logout. se crea WebSecurityConfig.java

Al ejecutarlo tenemos









https://github.com/jalbertomr/springBootWebSecurityThymeleaf/commit/37e69250a842893dbe0200ac75a4a7d4fd4a494f

eot

viernes, 9 de agosto de 2019

Spring MVC Security Basic Authentication Provider

Spring MVC Security Basic Authentication Provider

  Spring security permite implementar seguridad de varias maneras, haremos una aplicación sencilla con un authentication provider simple, de la forma más sencilla, utilizaremos la aplicación springMVC que hicimos anteriormente.

https://jalbertomr.blogspot.com/2019/08/springmvc-form-handling-y-spring.html

Esta aplicación la modificamos en varios puntos para integrar spring security, en resumen, se agregan dependencias de spring-security con versión, modifica la estructura de archivos de configuración xml. para que en este caso solo la ruta /listaEmpleados tenga un paso de autenticación (página login default de spring) con una configuración de usuario, esto en appconfig-security.xml.


https://github.com/jalbertomr/SpringSecurity/commit/11899fc773f186182e63c044a5a4a2f12522f879
La estructura del proyecto

Ejecutamos el proyecto, y accedemos la ruta /listaEmpleados






Desde Terminal...

bext@bext-VPCF13WFX:~$ curl  http://localhost:8080/springSecurity/listaEmpleados
 
bext@bext-VPCF13WFX:~$ curl --user bext:bext http://localhost:8080/springSecurity/listaEmpleados
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Lista de Empleados</title>
</head>
<body>
 <div id="listaEmpleados">
  <h2>Lista de Empleados</h2>
  <ul>
   
    <li>
     <b>1</b>
     <b>emp1</b>
     <b>funciones1</b>
     <b>10000.0</b>
    </li>
   
    <li>
     <b>2</b>
     <b>emp2</b>
     <b>funciones2</b>
     <b>20000.0</b>
    </li>
   
    <li>
     <b>3</b>
     <b>emp3</b>
     <b>funciones3</b>
     <b>30000.0</b>
    </li>
   
    <li>
     <b>4</b>
     <b>emp4</b>
     <b>funciones4</b>
     <b>40000.0</b>
    </li>
   
    <li>
     <b>5</b>
     <b>emp5</b>
     <b>funciones5</b>
     <b>50000.0</b>
    </li>
   
    <li>
     <b>6</b>
     <b>emp6</b>
     <b>funciones6</b>
     <b>60000.0</b>
    </li>
   
  </ul>
 </div>
</body>
</html>bext@bext-VPCF13WFX:~$ 

Referencia https://github.com/hellokoding/registration-login-spring-xml-maven-jsp-mysql

eot

miércoles, 7 de agosto de 2019

Mysql-Workbench crear base datos para usuarios y roles

 Mysql-Workbench crear base datos para usuarios y roles


Este es el script que necesitamos para crear la base de datos, lo podemos crear con el amigable entorno de mysql-workbench. 

CREATE DATABASE  IF NOT EXISTS `accounts`;
USE `accounts`;
---- Table structure for table `role`--
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

---- Dumping data for table `role`--
LOCK TABLES `role` WRITE;
INSERT INTO `role` VALUES (1,'ROLE_USER');
UNLOCK TABLES;

---- Table structure for table `user`--
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) DEFAULT NULL,
  `password` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

---- Table structure for table `user_role`--
DROP TABLE IF EXISTS `user_role`;
CREATE TABLE `user_role` (
  `user_id` int(11) NOT NULL,
  `role_id` int(11) NOT NULL,
  PRIMARY KEY (`user_id`,`role_id`),
  KEY `fk_user_role_roleid_idx` (`role_id`),
  CONSTRAINT `fk_user_role_roleid` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
  CONSTRAINT `fk_user_role_userid` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 Primero creamos la base de datos gráficamente , y luego descargamos el script para ejecutarlo todo. lo cual nos creará las tablas de users y roles, y verificamos.





eot

Install MySQL 5.7.27 on Ubuntu 18.04

Install MySQL 5.7.27 on Ubuntu 18.04

Instalamos según https://www.digitalocean.com/community/tutorials/how-to-install-mysql-on-ubuntu-16-04

Nos dará algunos problemas al intentar accesar, las razones son estas https://askubuntu.com/questions/773446/unable-to-connect-via-mysql-workbench-to-localhost-in-ubuntu-16-04-passwordless

Se hacen ajustes
bext@bext-VPCF13WFX:~$ sudo mysql -u root
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 13
Server version: 5.7.27-0ubuntu0.18.04.1 (Ubuntu)

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
Query OK, 0 rows affected (0.00 sec)

mysql> CREATE USER 'admin'@'localhost' IDENTIFIED BY 'admin';
Query OK, 0 rows affected (0.00 sec)

mysql> GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost' WITH GRANT OPTION;
Query OK, 0 rows affected (0.00 sec)

mysql> exit

Basicamente ahora tenemos a dos usuarios:
user1:          root
password1: password
user2:          admin
password:   admin

que usamos para pruebas.


eot

sábado, 3 de agosto de 2019

SpringMVC Form Handling y Spring Backing Bean

SpringMVC Form Handling y Spring Backing Bean

https://github.com/jalbertomr/SpringMVCsimple/commit/e3ab9d18e395507a67075a690e99bfd7fd51d84c


En este caso, si hay error en los datos de entrada, se limpian los campos y se recarga la página de captura de empleado.

El código original sin backing Bean

AddEmployeeController.java
package com.bext.empManSys.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.bext.empManSys.domain.Employee;
import com.bext.empManSys.service.EmployeeService;

@Controllerpublic class AddEmployeeController {

   @Autowired   private EmployeeService employeeService;

   @RequestMapping(value = "/altaEmpleado", method = RequestMethod.GET)
   public ModelAndView show() {
      return new ModelAndView("altaEmpleado", "emp", new Employee());
   }

   @RequestMapping(value = "/altaEmpleado", method = RequestMethod.POST)
   public ModelAndView addEmployee(
         @RequestParam("empId")String empId,
         @RequestParam("nombre")String nombre,
         @RequestParam("designacion")String designacion,
         @RequestParam("sueldo")String sueldo) {
      double sueldoDouble = new Double(sueldo);
      Employee empleado = new Employee(empId, nombre, designacion, sueldoDouble);
      employeeService.addNewEmployee(empleado);
      return new ModelAndView("/altaEmpleadoOK","empleado", empleado);
   }
}

Con backing bean

AddEmployeeController.java
package com.bext.empManSys.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.bext.empManSys.domain.Employee;
import com.bext.empManSys.service.EmployeeService;

@Controllerpublic class AddEmployeeController {

   @Autowired   private EmployeeService employeeService;
   
   @RequestMapping(value = "/altaEmpleado", method = RequestMethod.GET)
   public ModelAndView show() {
      return new ModelAndView("altaEmpleado", "empleado", new Employee());
   }
   
   @RequestMapping(value = "/altaEmpleado", method = RequestMethod.POST)
   public ModelAndView processRequest( Employee empleado, Errors result) { 
      if (result.hasErrors()) {
         return new ModelAndView("/altaEmpleado", "empleado", empleado);
      }
      employeeService.addNewEmployee(empleado);
      return new ModelAndView("/altaEmpleadoOK","empleado", empleado);
   }
}


eot

SpringMVC ModelAndView agregar datos al Modelo

SpringMVC ModelAndView agregar datos al Modelo

  Se agrega funcionalidad el sistema simple de empleados, la alta de un empleado.


Se agrega un controlador, el de altaEmpleado, dos vistas jsp altaEmpleado.jsp, altaEmpleadoOK.jsp, y se modifican algunos nombres con respecto a la versión anterior del proyecto.

https://github.com/jalbertomr/SpringMVCsimple/commit/1f9ad04e643bc15c327ae80bba16b58233fa3bb9

Estructura del proyecto


 Ejecutando el Proyecto







eot

SpringMVC ModelAndView simple

SpringMVC ModelAndView simple

Este es un prototipo usando Spring MVC, se toma como base la creación del proyecto con Eclipse IDE y STS de spring, y se modifica.
https://jalbertomr.blogspot.com/2019/08/configurar-ambiente-springmvc-apache.html

https://github.com/jalbertomr/SpringMVCsimple/commit/e243238b99e08d8a941f00c08041dffb20ef3b19

La estructura final del proyecto, muestra un controlador, en modelo tiene una entidad empleado, que es la clase java que representa los datos en memoria por medio de la clase. En el nivel de servicio, EmployeeService es una interface que se implementa con datos fijos en este caso, que bien podría llenarse por SQL.
  El controlador manda a llamar la vista listaEmpleados.jsp que envia el objeto listaEmpleados que tiene el modelo de datos de empleado con los datos tomados en el servicio.


El Controlador


@Controller
public class EmployeeController {
    private static final Logger logger = LoggerFactory.getLogger(EmployeeController.class);
   
    @Autowired
    private EmployeeService employeeService;
   
    /**
     * Simply selects the home view to render by returning its name.
     */
    @RequestMapping(value = "/")
    public ModelAndView viewAllItems() {
        logger.info("listando items...");
       
        List<Employee> listaEmpleados = employeeService.getAllEmployees();
        return new ModelAndView("/listaEmpleados","listaEmpleados", listaEmpleados);
    }
}



El modelo

Employee.java

public class Employee {
    private String empId;
    private String nombre;
    private String designacion;
    private double sueldo;

    public Employee( ) {
    }
   
    public Employee(String empId, String nombre, String designacion, double sueldo) {
        super();
        this.empId = empId;
        this.nombre = nombre;
        this.designacion = designacion;
        this.sueldo = sueldo;
    }

getters y setters...


EmployeeService.java
public interface EmployeeService {
    public List<Employee> getAllEmployees();
}


EmployeeServiceMockImpl.java
@Component
public class EmployeeServiceMockImpl implements EmployeeService {

    private List<Employee> mockEmployees = new ArrayList<Employee>();
   
    public EmployeeServiceMockImpl() {
        mockEmployees.add(new Employee("1","emp1","funciones1",10000));
        mockEmployees.add(new Employee("2","emp2","funciones2",20000));
        mockEmployees.add(new Employee("3","emp3","funciones3",30000));
        mockEmployees.add(new Employee("4","emp4","funciones4",40000));
        mockEmployees.add(new Employee("5","emp5","funciones5",50000));
        mockEmployees.add(new Employee("6","emp6","funciones6",60000));
    }

    @Override
    public List<Employee> getAllEmployees() {
        return mockEmployees;
    }

}


La Vista

listaEmpleados.jsp
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Lista de Empleados</title>
</head>
<body>
    <div id="listaEmpleados">
        <h2>Lista de Empleados</h2>
        <ul>
            <c:forEach items="${listaEmpleados}" var="nextEmp">
                <li>
                    <b>${nextEmp.empId}</b>
                    <b>${nextEmp.nombre}</b>
                    <b>${nextEmp.designacion}</b>
                    <b>${nextEmp.sueldo}</b>
                </li>
            </c:forEach>
        </ul>
    </div>
</body>
</html>

La Prueba





eot

viernes, 2 de agosto de 2019

Deploy aplicacion springMVC en Sevidor local Tomcat 9, Manualmente

Deploy aplicacion springMVC en Sevidor local Tomcat 9, Manualmente

   Creamos una aplicación spring MVC con el template de Eclipse Ide https://jalbertomr.blogspot.com/2019/08/configurar-ambiente-springmvc-apache.html
  Le hacemos algunas modificaciones, como acortar la version en el POM para que el war salga más corto. y una página extra con miController.java y mi.jsp.


desde terminal damos mvn clean, mvn install

bext@bext-VPCF13WFX:~/eclipse-workspace/springMVCTomcat$ mvn clean
[INFO] Scanning for projects...
[INFO] 
[INFO] -------------------------< com.bext:springMVC >-------------------------
[INFO] Building springMVCTomcat 1
[INFO] --------------------------------[ war ]---------------------------------
[INFO] 
[INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ springMVC ---
[INFO] Deleting /home/bext/eclipse-workspace/springMVCTomcat/target
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  0.510 s
[INFO] Finished at: 2019-08-02T18:16:28-05:00
[INFO] ------------------------------------------------------------------------
bext@bext-VPCF13WFX:~/eclipse-workspace/springMVCTomcat$ mvn install
[INFO] Scanning for projects...
[INFO] 
[INFO] -------------------------< com.bext:springMVC >-------------------------
[INFO] Building springMVCTomcat 1
[INFO] --------------------------------[ war ]---------------------------------
[INFO] 
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ springMVC ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 1 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.5.1:compile (default-compile) @ springMVC ---
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 2 source files to /home/bext/eclipse-workspace/springMVCTomcat/target/classes
[INFO] 
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ springMVC ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 1 resource
[INFO] 
[INFO] --- maven-compiler-plugin:2.5.1:testCompile (default-testCompile) @ springMVC ---
[INFO] Nothing to compile - all classes are up to date
[INFO] 
[INFO] --- maven-surefire-plugin:2.12.4:test (default-test) @ springMVC ---
[INFO] 
[INFO] --- maven-war-plugin:2.2:war (default-war) @ springMVC ---
[INFO] Packaging webapp
[INFO] Assembling webapp [springMVC] in [/home/bext/eclipse-workspace/springMVCTomcat/target/springMVC-1]
[INFO] Processing war project
[INFO] Copying webapp resources [/home/bext/eclipse-workspace/springMVCTomcat/src/main/webapp]
[INFO] Webapp assembled in [90 msecs]
[INFO] Building war: /home/bext/eclipse-workspace/springMVCTomcat/target/springMVC-1.war
[INFO] WEB-INF/web.xml already added, skipping
[INFO] 
[INFO] --- maven-install-plugin:2.4:install (default-install) @ springMVC ---
[INFO] Installing /home/bext/eclipse-workspace/springMVCTomcat/target/springMVC-1.war to /home/bext/.m2/repository/com/bext/springMVC/1/springMVC-1.war
[INFO] Installing /home/bext/eclipse-workspace/springMVCTomcat/pom.xml to /home/bext/.m2/repository/com/bext/springMVC/1/springMVC-1.pom
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  3.493 s
[INFO] Finished at: 2019-08-02T18:16:41-05:00
[INFO] ------------------------------------------------------------------------
bext@bext-VPCF13WFX:~/eclipse-workspace/springMVCTomcat$ 

Nos genera el war que llamaremos en la página de administración de tomcat.
Nuestro servidor tomcat debe estar arriba.

bext@bext-VPCF13WFX:/opt/tomcat$ sudo systemctl start tomcat

En la página de tomcat elegimos el archivo war y le damos deploy.


Aparecera en la lista de aplicaciones


La llamamos con un click desde la lista de aplicaciones o con la url ingresada manualmente.

Podemos indicarle otro Context Path en lugar de springMVC que en este caso lo heredo del idArtifact cuando creamos el POM. Para ello undeployamos la aplicación, y el apache admin especificamos la ruta del war (/home/bext/eclipse-workspace/springMVCTomcat/target/springMVC-1.war) y el Context Path, por ejemplo /otroCamino


En la lista de aplicaciones ya nos aparece como /otroCamino, el cual clickeamos para verificarlo.



eot

Instalar Apache Tomcat 9 en Ubuntu 18.04

 Instalar Apache Tomcat 9 en Ubuntu 18.04


    Basicamente se siguen las intrucciones de DigitalOcean https://www.digitalocean.com/community/tutorials/install-tomcat-9-ubuntu-1804

con algunas adaptaciones como apuntar a java 8, y usuarios y roles para pruebas en tomcat-users.xml

  <role rolename="tomcat"/>
  <role rolename="role1"/>
  <role rolename="admin"/>
  <role rolename="manager-gui"/>
  <role rolename="manager-script"/>
  <role rolename="manager-jmx"/>
  <role rolename="manager-status"/>
  <role rolename="admin-gui"/>
  <user username="admin" password="admin" roles="tomcat,manager-gui,manager-scr$
  <user username="tomcat" password="password" roles="tomcat"/>
  <user username="both" password="password" roles="tomcat,role1"/>
  <user username="role1" password="password" roles="role1"/>

Se agregan roles que no vienen en el  archivo que se bajo del paquete, se determinan estos por los mensajes de error al intentar accesar las páginas
 administrativas de localhost:8080









eot