Skip to content

Commit 04c1ff8

Browse files
Update of the repository with practice examples only
1 parent e58c52d commit 04c1ff8

File tree

2,425 files changed

+275
-630162
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

2,425 files changed

+275
-630162
lines changed

README.md

+2-42
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,5 @@
11
# Desarrollo de Aplicaciones Web
22

3-
En este repositorio se encuentra el código con ejemplos y ejercicios resueltos de las diferentes partes de la asignatura "Desarrollo de Aplicaciones Web" del Grado en Ingeniería del Software de la ETSII URJC.
3+
En este repositorio se encuentran ejemplos de las diferentes prácticas solicitadas en la asignatura.
44

5-
## El temario de la asignatura se divide en 4 partes
6-
7-
### Parte 1: Tecnologías web básicas de cliente: HTML, CSS, JavaScript y APIs REST
8-
* Tema 1: Introducción
9-
* Tema 2: Maquetación (HTML y CSS)
10-
* Tema 3: JavaScript
11-
* Tema 4: APIs REST
12-
13-
Los ejemplos y ejercicios de esta parte pueden encontrarse en [Parte 1](parte_1)
14-
15-
### Parte 2. Tecnologías web de servidor: Java, Spring y MySQL
16-
* Tema 1: Desarrollo web con Spring
17-
* Tema 2: APIs REST con Spring
18-
* Tema 3: Bases de datos con Spring
19-
* Tema 4: Seguridad en Spring
20-
* Tema 5: Despliegue Spring
21-
22-
Los ejemplos y ejercicios de esta parte pueden encontrarse en [Parte 2](parte_2)
23-
24-
### Parte 3. Despliegue de aplicaciones web
25-
* Tema 1. Virtualización, Cloud Computing y Contenedores
26-
* Tema 2. Docker
27-
* Tema 3. Docker Compose
28-
* Tema 4. Railway
29-
* Tema 5. Heroku
30-
31-
Los ejemplos y ejercicios de esta parte pueden encontrarse en [Parte 3](parte_3)
32-
33-
### Parte 4. Tecnologías web avanzadas de cliente: SPA con Angular
34-
* Tema 1. Introducción: Angular, TypeScript y Herramientas
35-
* Tema 2. Componentes en Angular
36-
* Tema 3. REST y Servicios en Angular
37-
* Tema 4. Aplicaciones multipágina. Router
38-
* Tema 5. Librerías de componentes gráficos
39-
* Tema 6. Publicación
40-
41-
Los ejemplos y ejercicios de esta parte pueden encontrarse en [Parte 4](parte_4)
42-
43-
### Proyectos de ejemplo
44-
45-
El objetivo de la asignatura es que los alumnos desarrollen una aplicación web como si estuvieran trabajando profesionalmente. Los alumnos desarrollarán la aplicación web en grupos, y será entregada por fases. Podemos encontrar proyectos de ejemplo de las diferentes fases de la práctica en [Proyectos de Ejemplo](proyectos_de_ejemplo)
5+
* [Práctica 1](ejemplo-practica1)

proyectos_de_ejemplo/sample-project-phase2/README.md renamed to ejemplo-practica1/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# sample-project-phase2
22

3-
Ejemplo que contiene algunas de las funcionalidades solicitadas en la Fase 2 del proyecto, en concreto:
3+
Ejemplo que contiene algunas de las funcionalidades solicitadas en la Prática 1 del proyecto, en concreto:
44

55
* Aplicación web implementada con Spring MVC y templates Mustache.
66
* Base de datos MySQL
@@ -18,7 +18,7 @@ Por defecto el proyecto require una base de datos MySQL disponible en localhost
1818
Se puede arrancar usando docker con el comando:
1919

2020
```
21-
$ docker run --rm -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=books -p 3306:3306 -d mysql:8.0
21+
$ docker run --rm -e MYSQL_ROOT_PASSWORD=password -e MYSQL_DATABASE=books -p 3306:3306 -d mysql:9.2
2222
```
2323

2424
La aplicación se ejecuta con el comando:

proyectos_de_ejemplo/sample-project-phase2/pom.xml renamed to ejemplo-practica1/pom.xml

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,19 @@
44
<modelVersion>4.0.0</modelVersion>
55

66
<groupId>es.codeurjc</groupId>
7-
<artifactId>sample-project-phase2</artifactId>
7+
<artifactId>ejemplo-practica1</artifactId>
88
<version>0.0.1-SNAPSHOT</version>
99
<packaging>jar</packaging>
1010

1111
<parent>
1212
<groupId>org.springframework.boot</groupId>
1313
<artifactId>spring-boot-starter-parent</artifactId>
14-
<version>2.7.7</version>
14+
<version>3.4.1</version>
1515
</parent>
1616

1717
<properties>
1818
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
19-
<java.version>17</java.version>
19+
<java.version>21</java.version>
2020
</properties>
2121

2222
<dependencies>
@@ -35,6 +35,7 @@
3535
<dependency>
3636
<groupId>mysql</groupId>
3737
<artifactId>mysql-connector-java</artifactId>
38+
<version>8.0.33</version>
3839
</dependency>
3940
<dependency>
4041
<groupId>org.springframework.boot</groupId>
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class WebSecurityConfig {
1616

1717
@Autowired
1818
RepositoryUserDetailsService userDetailsService;
19-
19+
2020
@Bean
2121
public PasswordEncoder passwordEncoder() {
2222
return new BCryptPasswordEncoder();
@@ -34,30 +34,29 @@ public DaoAuthenticationProvider authenticationProvider() {
3434

3535
@Bean
3636
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
37-
37+
3838
http.authenticationProvider(authenticationProvider());
39-
39+
4040
http
41-
.authorizeHttpRequests(authorize -> authorize
42-
// PUBLIC PAGES
43-
.requestMatchers("/").permitAll()
44-
.requestMatchers("/books/**").permitAll()
45-
// PRIVATE PAGES
46-
.requestMatchers("/newbook").hasAnyRole("USER")
47-
.requestMatchers("/editbook/*").hasAnyRole("USER")
48-
.requestMatchers("/removebook/*").hasAnyRole("ADMIN")
49-
)
50-
.formLogin(formLogin -> formLogin
51-
.loginPage("/login")
52-
.failureUrl("/loginerror")
53-
.defaultSuccessUrl("/")
54-
.permitAll()
55-
)
56-
.logout(logout -> logout
57-
.logoutUrl("/logout")
58-
.logoutSuccessUrl("/")
59-
.permitAll()
60-
);
41+
.authorizeHttpRequests(authorize -> authorize
42+
// PUBLIC PAGES
43+
.requestMatchers("/").permitAll()
44+
.requestMatchers("/images/**").permitAll() // Allow access to static resources
45+
.requestMatchers("/books/**").permitAll()
46+
// PRIVATE PAGES
47+
.requestMatchers("/newbook").hasAnyRole("USER")
48+
.requestMatchers("/editbook").hasAnyRole("USER")
49+
.requestMatchers("/editbook/*").hasAnyRole("USER")
50+
.requestMatchers("/removebook/*").hasAnyRole("ADMIN"))
51+
.formLogin(formLogin -> formLogin
52+
.loginPage("/login")
53+
.failureUrl("/loginerror")
54+
.defaultSuccessUrl("/")
55+
.permitAll())
56+
.logout(logout -> logout
57+
.logoutUrl("/logout")
58+
.logoutSuccessUrl("/")
59+
.permitAll());
6160

6261
return http.build();
6362
}
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
server.port = ${PORT:8080}
1+
server.port = 8443
22
server.ssl.key-store = classpath:keystore.jks
33
server.ssl.key-store-password = password
44
server.ssl.key-password = secret
@@ -10,6 +10,11 @@ spring.datasource.username=root
1010
spring.datasource.password=password
1111
spring.jpa.hibernate.ddl-auto=create-drop
1212

13+
# Necessary to be able to use accents and the letter ñ
14+
server.servlet.encoding.charset=UTF-8
15+
server.servlet.encoding.enabled=true
16+
server.servlet.encoding.force=true
17+
1318
logging.level.org.springframework.security=DEBUG
1419
logging.level.org.springframework.web=DEBUG
1520
spring.jpa.properties.hibernate.format_sql=true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
{{>header}}
2+
3+
<div class="container mt-4 mb-5">
4+
<h2>Book "{{book.title}}"</h2>
5+
6+
{{#book.image}}
7+
<img src="/books/{{book.id}}/image" class="img-fluid mb-4" alt="Book Image">
8+
{{/book.image}}
9+
10+
{{^book.image}}
11+
<img src="/images/no_image.png" class="img-fluid mb-4" alt="No Image">
12+
{{/book.image}}
13+
14+
<div>
15+
<p>{{book.description}}</p>
16+
</div>
17+
18+
<p><b>Shops where book is available:</b></p>
19+
<div>
20+
<ul class="list-group">
21+
{{#book.shops}}
22+
<li class="list-group-item">{{name}}</li>
23+
{{/book.shops}}
24+
</ul>
25+
</div>
26+
27+
<div class="mt-4">
28+
{{#logged}}
29+
<div class="btn-group">
30+
{{#admin}}
31+
<a href="/removebook/{{book.id}}" class="btn btn-danger">Remove</a>
32+
{{/admin}}
33+
34+
<a href="/editbook/{{book.id}}" class="btn btn-warning">Edit</a>
35+
</div>
36+
{{/logged}}
37+
38+
<br>
39+
<a href="/" class="btn btn-secondary mt-3">Back to all books</a>
40+
</div>
41+
</div>
42+
43+
{{>footer}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{{>header}}
2+
3+
<h2 class="mb-4">Books</h2>
4+
5+
<div class="row row-cols-1 row-cols-md-3 g-4">
6+
{{#books}}
7+
<div class="col">
8+
<div class="card h-100">
9+
<div class="card-body">
10+
<h5 class="card-title"><a href="/books/{{id}}" class="text-decoration-none text-dark">{{title}}</a></h5>
11+
</div>
12+
</div>
13+
</div>
14+
{{/books}}
15+
</div>
16+
17+
{{#logged}}
18+
<div class="mt-4">
19+
<button onclick="location.href='/newbook'" class="btn btn-primary">New Book</button>
20+
</div>
21+
{{/logged}}
22+
23+
{{>footer}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
{{>header}}
2+
3+
<div class="container mt-4 mb-5">
4+
<h2>Edit Book "{{book.title}}"</h2>
5+
6+
<form action="/editbook" method="post" enctype="multipart/form-data">
7+
<input type="hidden" name="id" value="{{book.id}}" />
8+
9+
<div class="mb-3">
10+
<label for="title" class="form-label">Title</label>
11+
<input type="text" name="title" class="form-control" id="title" value="{{book.title}}" placeholder="Title"
12+
required />
13+
</div>
14+
15+
<div class="mb-3">
16+
<label for="description" class="form-label">Abstract</label>
17+
<textarea name="description" class="form-control" id="description" placeholder="Description" rows="4"
18+
required>{{book.description}}</textarea>
19+
</div>
20+
21+
<p><b>Image:</b></p>
22+
23+
{{#book.image}}
24+
<img src="/books/{{book.id}}/image" class="img-fluid mb-3" alt="Book Image">
25+
<div class="form-check">
26+
<input type="checkbox" name="removeImage" class="form-check-input" id="removeImage">
27+
<label class="form-check-label" for="removeImage">Remove Image</label>
28+
</div>
29+
<div class="mb-3">
30+
<label for="updateImage" class="form-label">Update Image</label>
31+
</div>
32+
{{/book.image}}
33+
34+
{{^book.image}}
35+
<img src="/images/no_image.png" class="img-fluid mb-3" alt="No Image">
36+
<div class="mb-3">
37+
<label for="uploadImage" class="form-label">Upload Image</label>
38+
</div>
39+
{{/book.image}}
40+
41+
<input type="file" name="imageField" accept=".jpg, .jpeg" class="form-control mb-3" />
42+
43+
<input type="hidden" name="_csrf" value="{{token}}" />
44+
45+
<div class="mb-3">
46+
<button type="button" onclick="location.href='/books/{{book.id}}';"
47+
class="btn btn-secondary">Cancel</button>
48+
<input type="submit" value="Save" class="btn btn-primary" />
49+
</div>
50+
</form>
51+
</div>
52+
53+
{{>footer}}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
</div>
2+
</div>
3+
4+
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
5+
</body>
6+
</html>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<!DOCTYPE html>
2+
<html>
3+
4+
<head>
5+
<title>Main</title>
6+
7+
<meta charset="UTF-8">
8+
<base href=".">
9+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
10+
11+
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"
12+
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
13+
14+
</head>
15+
16+
<!-- 3. Display the application -->
17+
18+
<body>
19+
20+
<nav class="navbar navbar-expand-lg bg-dark navbar-dark px-3">
21+
22+
<a class="navbar-brand" href="/">Library</a>
23+
24+
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarContent">
25+
<span class="navbar-toggler-icon"></span>
26+
</button>
27+
28+
<div class="collapse navbar-collapse justify-content-end" id="navbarContent">
29+
{{^logged}}
30+
<form action="/login" method="post" class="d-flex align-items-center p-2">
31+
<input type="text" class="form-control me-3" name="username" placeholder="Username">
32+
<input type="password" class="form-control me-3" name="password" placeholder="Password">
33+
<button type="submit" class="btn btn-primary btn-nowrap w-50">Log In</button>
34+
<input type="hidden" name="_csrf" value="{{token}}" />
35+
</form>
36+
{{/logged}}
37+
{{#logged}}
38+
<ul class="navbar-nav d-flex align-items-center">
39+
<li class="nav-item">
40+
<span class="navbar-text fs-3 text-white mx-3">{{userName}}</span>
41+
</li>
42+
<li class="nav-item">
43+
<form action="/logout" method="post" class="d-inline">
44+
<button class="btn btn-primary btn-nowrap" type="submit">Log Out</button>
45+
<input type="hidden" name="_csrf" value="{{token}}" />
46+
</form>
47+
</li>
48+
</ul>
49+
{{/logged}}
50+
</div>
51+
</nav>
52+
53+
<div class="container">
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{{>header}}
2+
<form action="/login" method="post" class="d-flex flex-column gap-2 p-4">
3+
<input type="text" class="form-control" name="username" placeholder="Username">
4+
<input type="password" class="form-control" name="password" placeholder="Password">
5+
<div class="text-start w-100">
6+
<button type="submit" class="btn btn-primary">Log In</button>
7+
</div>
8+
<input type="hidden" name="_csrf" value="{{token}}" />
9+
</form>
10+
{{>footer}}

0 commit comments

Comments
 (0)