@WebServlet("/portfolios")
public class PortfolioServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("application/json");
response.setHeader("Access-Control-Allow-Origin", "*");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
JSONArray portfolioList = new JSONArray();
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
// Database Connection
Class.forName("com.mysql.cj.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/xxxx?useSSL=false", "root","xxxx");
stmt = conn.createStatement();
rs = stmt.executeQuery("SELECT * FROM users");
// Convert ResultSet to JSON
while (rs.next()) {
JSONObject portfolio = new JSONObject();
portfolio.put("id", rs.getInt("id"));
portfolio.put("full_name", rs.getString("full_name"));
portfolio.put("discipline", rs.getString("discipline"));
portfolio.put("batch", rs.getString("batch"));
portfolio.put("keywords", rs.getString("keywords"));
portfolio.put("profile_photo", "image?type=profile_photo&id=" + rs.getInt("id"));
portfolio.put("background_image", "image?type=background_image&id=" + rs.getInt("id"));
portfolioList.put(portfolio);
}
out.print(portfolioList.toString());
out.flush();
conn.close();
} catch (Exception e) {
e.printStackTrace();
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
JSONObject errorResponse = new JSONObject();
errorResponse.put("error", "Failed to load portfolios: " + e.getMessage());
out.print(errorResponse.toString());
out.flush();
} finally {
try {
if (rs != null)
rs.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
if (stmt != null)
stmt.close();
} catch (Exception e) {
e.printStackTrace();
}
try {
if (conn != null)
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
< /code>
imageservlet.java:
@WebServlet("/image")
public class ImageServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String type = request.getParameter("type"); // "portfolio", or "background"
int id = Integer.parseInt(request.getParameter("id"));
try {
Class.forName("com.mysql.cj.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/xxxx?useSSL=false", "root","xxxx");
PreparedStatement stmt = conn.prepareStatement("SELECT " + type + " FROM users WHERE id = ?");
stmt.setInt(1, id);
ResultSet rs = stmt.executeQuery();
if (rs.next()) {
byte[] imgData = rs.getBytes(1);
String contentType = "image/jpeg"; // Default
if (imgData.length > 4 && imgData[0] == (byte) 0x89 && imgData[1] == (byte) 0x50) {
contentType = "image/png"; // PNG signature detected
}
response.setContentType(contentType);
OutputStream os = response.getOutputStream();
os.write(imgData);
os.close();
}
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
< /code>
index.html:
Discover diverse portfolios from
the xxxxx
connect
collaborate
create
All Programs
Industrial Design
Communication Design
Textile and Apparel Design
All batches
< /code>
javascript: < /p>
document.addeventlistener("moncontentloaded ", function () {
console.log("script загружен, ждал Портфели ... "); < /p>
const cardContainer = document.querySelector(".card-container");
if (!cardContainer) {
console.error("Error: .card-container not found!");
return;
}
const loadingMessage = document.createElement("p");
loadingMessage.className = "loading-message";
loadingMessage.innerText = "Loading portfolios...";
cardContainer.appendChild(loadingMessage);
console.log("Fetching data from /portfolios...");
fetch("/Student/portfolios")
.then(response => {
console.log("Response received:", response);
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.then(data => {
console.log("Fetched data:", data);
cardContainer.innerHTML = ""; // Clear loading message
if (!Array.isArray(data) || data.length === 0) {
console.warn("No portfolios found:", data);
cardContainer.innerHTML = "
No portfolios found.
";
return;
}
data.forEach(portfolio => {
console.log("Processing portfolio:", portfolio);
const profilePhotoURL = "/Student" + portfolio.profile_photo;
const backgroundImageURL = "/Student" + portfolio.background_image;
console.log("Updated Profile Photo URL:", profilePhotoURL);
console.log("Updated Background Image URL:", backgroundImageURL);
const cardHTML = `
${portfolio.full_name}
${portfolio.discipline}, ${portfolio.batch}
Interests
${portfolio.keywords}
`;
cardContainer.insertAdjacentHTML("beforeend", cardHTML);
});
console.log("Portfolios successfully loaded.");
filterCardsByData();
})
.catch(error => {
console.error("Error loading portfolios:", error);
cardContainer.innerHTML = `
Error loading portfolios. Please try again later.
`;
});
});
// **Filtering Logic**
// Select all filter buttons, filterable cards, and dropdowns
const filterButtons = document.querySelectorAll(".filter_buttons button");
const filterableCards = document.querySelectorAll(".card-container .card");
const dropdowns = document.querySelectorAll(".dropdown");
// Common filtering logic
function filterCardsByData(selectedFilter) {
filterableCards.forEach((card) => {
const cardBatch = card.getAttribute("data-batch");
const cardName = card.dataset.name;
// Show or hide the card based on filter condition
if (
selectedFilter === "All batches" ||
selectedFilter === "" ||
cardBatch === selectedFilter ||
cardName === selectedFilter
) {
// Show card and add reveal animation
card.classList.remove("hide", "exit");
setTimeout(() => {
card.classList.add("reveal"); // Add reveal class for the animation
}, 10);
setTimeout(() => {
card.classList.add("visible"); // Ensure visibility after animation
}, 500); // Adjust based on reveal animation duration
} else {
// Apply exit animation before hiding the card
card.classList.remove("reveal", "visible");
card.classList.add("exit");
setTimeout(() => {
card.classList.add("hide");
}, 500); // Ensure card hides after exit animation
}
});
}
// Button click event
filterButtons.forEach((button) => {
button.addEventListener("click", (e) => {
// Update active button state
document
.querySelector(".filter_buttons .active")
.classList.remove("active");
e.target.classList.add("active");
// Get filter value from the button's data-name attribute or default to "All batches"
const filterValue = e.target.dataset.name || "All batches";
// Apply the filter
filterCardsByData(filterValue);
});
});
// Dropdown logic
dropdowns.forEach((dropdown) => {
const select = dropdown.querySelector(".select");
const caret = dropdown.querySelector(".caret");
const selected = dropdown.querySelector(".selected");
const menu = document.createElement("ul");
menu.className = "menu";
const menuItems = [
"All batches",
"Batch of 2017",
"Batch of 2018",
"Batch of 2019",
"Batch of 2020",
"Batch of 2021",
"Batch of 2022",
"Batch of 2023",
"Batch of 2024",
];
// Add menu items dynamically
menuItems.forEach((item) => {
const option = document.createElement("li");
option.innerText = item;
// Handle dropdown item selection
option.addEventListener("click", () => {
selected.innerText = item;
caret.classList.remove("caret-rotate");
menu.classList.remove("menu-open");
// Add dd-active to the selected option and remove it from others
menu.querySelectorAll("li").forEach((opt) => {
opt.classList.remove("dd-active"); // Remove dd-active from all items
});
option.classList.add("dd-active"); // Add dd-active to the clicked option
// Apply the filter
filterCardsByData(item);
});
menu.appendChild(option);
});
dropdown.appendChild(menu);
// Toggle dropdown visibility
select.addEventListener("click", (event) => {
event.stopPropagation();
caret.classList.toggle("caret-rotate");
menu.classList.toggle("menu-open");
});
// Close dropdown if clicked outside
document.addEventListener("click", (event) => {
if (!dropdown.contains(event.target)) {
caret.classList.remove("caret-rotate");
menu.classList.remove("menu-open");
}
});
});
// Ensure cards are visible on page load or refresh by applying the default filter
document.addEventListener("DOMContentLoaded", () => {
// Trigger the default filter to show all cards (or set to a specific filter if needed)
filterCardsByData("All batches");
});
< /code>
css: < /p>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
/* Font-Falimy */
@font-face {
font-family: "manrope-bold";
src: url(./../fonts/manrope.bold.otf);
}
@font-face {
font-family: "manrope-extrabold";
src: url(./../fonts/manrope.extrabold.otf);
}
@font-face {
font-family: "manrope-light";
src: url(./../fonts/manrope.light.otf);
}
@font-face {
font-family: "manrope-medium";
src: url(./../fonts/manrope.medium.otf);
}
@font-face {
font-family: "manrope-regular";
src: url(./../fonts/manrope.regular.otf);
}
:root {
--baseWhite: #ffffff;
--accentBlue: #0048ff;
--textGray: #838383;
--secoundaryGray: #b3b3b3;
}
body {
font-family: "manrope-regular" !important;
font-size: 16px;
min-height: 100vh;
background-color: var(--baseWhite);
}
/* .container {
width: 90%;
margin: 0 0 0 1em;
} */
.container {
width: 90%;
margin: 0 auto;
}
.hero__container {
width: 98%;
margin: 10px 0 10px 20px;
}
.logo__container {
border: 1px solid black;
width: 253px;
border-radius: 10px;
float: right;
margin: 10px 10px 0 0;
}
.logo__container img {
width: 250px;
border-radius: 10px;
}
/* Hero Section */
.hero__container p {
clear: both;
font-size: 16px;
color: var(--textGray);
}
.hero__title-1 {
width: 100%;
font-size: 48px;
font-weight: 300;
color: black;
position: relative;
display: inline-block;
}
.hero__title-1 span {
font-size: 120px;
font-family: "manrope-light";
line-height: 1.1;
}
.hero__title-1::after {
content: " ";
height: 7px;
width: auto;
background: var(--accentBlue);
display: block;
position: absolute;
top: 80%;
left: 10.5em;
right: 0;
}
.hero__title-1 .circle {
position: absolute;
width: 77px;
height: 77px;
/* opacity: .8; */
top: 39px;
left: 64px;
background: linear-gradient(to bottom, #1c40a5, #728dd1);
border-radius: 50%;
margin: 0 5px;
}
.hero__title-2 {
margin-top: 10px;
width: 100%;
font-size: 48px;
font-weight: 300;
color: black;
position: relative;
display: inline-block;
}
.hero__title-2 span {
font-size: 120px;
font-family: "manrope-bold";
line-height: 1.1;
}
.hero__title-2::after {
content: " ";
height: 7px;
width: auto;
background: var(--accentBlue);
display: block;
position: absolute;
top: 80%;
left: 15em;
right: 0;
}
.hero__title-2 .circle {
position: absolute;
/* Position relative to the container */
width: 77px;
height: 77px;
/* opacity: .8; */
top: 39px;
left: 69px;
background: linear-gradient(to bottom, #1c40a5, #728dd1);
border-radius: 50%;
margin: 0 5px;
}
.hero__title-3 {
margin-top: 10px;
width: 100%;
font-size: 48px;
font-weight: 300;
color: black;
position: relative;
display: inline-block;
}
.hero__title-3 span {
font-size: 120px;
font-family: "manrope-bold";
line-height: 1.1;
}
.hero__title-3::after {
content: " ";
height: 7px;
width: auto;
background: var(--accentBlue);
display: block;
position: absolute;
top: 80%;
left: 8.9em;
right: 0;
}
.hero__title-3 .circle {
position: absolute;
width: 77px;
height: 77px;
/* opacity: .8; */
top: 39px;
left: -1px;
background: linear-gradient(to bottom, #1c40a5, #728dd1);
border-radius: 50%;
margin: 0 5px;
}
.circle-cut {
position: absolute;
width: 15px;
height: 77px;
/* opacity: .8; */
top: 39px;
left: 61px;
background-color: var(--baseWhite);
margin: 0 5px;
cursor: not-allowed;
}
/* Body Start */
.body__container {
width: 95%;
margin: 0 auto;
height: auto;
}
/* */
/* Dropdown Section */
.filter__container {
display: flex;
align-items: center;
justify-content: space-between;
margin: 2em 0;
border-bottom: 1px solid black;
}
.filter_buttons {
gap: 30px;
display: flex;
}
button.filter-btn {
padding: 20px 0;
font-family: "manrope-regular";
font-size: 16px;
cursor: pointer;
background-color: var(--baseWhite);
border: none;
}
.filter-btn.active {
border-bottom: 2px solid var(--accentBlue);
}
.dropdown {
display: inline-block;
position: relative;
}
.label {
margin-bottom: 3px;
}
/* Select container */
.select {
cursor: pointer;
transition: 0.3s;
background-color: var(--baseWhite);
border-radius: 5px;
border: 1px solid black;
display: flex;
padding: 5px 15px;
align-items: center;
justify-content: space-between;
}
.selected {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.caret {
margin-left: 10px;
transition: 0.3s;
}
/* Hover effect for the select container */
.select:hover {
background-color: var(--secoundaryGray);
}
/* Dropdown Menu Animation */
.menu {
visibility: hidden;
border-radius: 5px;
border: 1px solid black;
background-color: var(--baseWhite);
overflow: hidden;
position: absolute;
width: 100%;
top: 146%;
opacity: 0;
transform: translateY(-20px);
transition: visibility 0s, opacity 0.3s ease, transform 0.3s ease;
z-index: 10;
}
.menu-open {
visibility: visible;
opacity: 1;
transform: translateY(0);
}
/* Caret animation */
.caret {
margin-left: 10px;
transition: transform 0.3s ease;
}
.caret-rotate {
transform: rotate(180deg);
}
/* Menu items */
.menu li {
cursor: pointer;
padding: 10px;
}
/* Hover effect for menu items */
.menu li:hover {
background-color: var(--secoundaryGray);
}
/* Active item style */
.dd-active {
background-color: var(--accentBlue);
color: #fff;
}
/* "All batches" - Make clickable */
.menu li:first-child {
font-weight: normal;
cursor: pointer;
}
/* Show all batches filter text */
.show-all-batches {
font-weight: bold;
color: var(--accentBlue);
cursor: pointer;
padding: 10px;
}
/* Card Container */
.card-container {
margin: 2em 0 5em 0;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
gap: 50px;
}
.card {
transform: scale(0) translate(0, 0);
opacity: 0;
transition: transform 0.5s ease, opacity 0.5s ease;
transform-origin: top left;
}
/* When the card becomes visible */
.card.visible {
transform: scale(1) translate(0, 0);
opacity: 1;
}
.card {
background-color: var(--baseWhite);
border-radius: 10px;
overflow: hidden;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
width: 417px;
height: 312px;
transition: transform 0.3s ease;
position: relative;
}
.card.hide {
display: none;
}
.card__image {
width: 100%;
height: 100%;
max-height: auto;
object-fit: cover;
}
.card__overlay {
position: absolute;
bottom: 0;
height: 257px;
left: 0;
right: 0;
z-index: 1;
background-color: rgba(39, 39, 39, 0.6);
backdrop-filter: blur(5px);
transform: translateY(100%);
transition: transform 0.3s ease-in-out, box-shadow 0.4s ease-in-out;
color: var(--baseWhite);
}
.card:hover .card__overlay {
transform: translateY(0);
box-shadow: 0 8px 15px rgba(0, 0, 0, 0);
}
.card__header {
position: relative;
display: flex;
align-items: center;
gap: 2rem;
background-color: rgba(33, 33, 33, 0.9);
padding: 2em;
transform: translateY(-100%);
transition: 0.3s ease-in-out;
font-size: 16px;
font-family: "manrope-regular";
}
.card:hover .card__header {
transform: translateY(0);
background-color: rgba(33, 33, 33, 0);
transition: 0.3s ease-in-out;
transition-delay: 0s;
}
.card__thumb {
flex-shrink: 0;
width: 3.125em;
height: 3.125em;
border-radius: 50%;
}
.card__title {
font-size: 16px;
margin: 0 0 0.3rem;
font-family: "manrope-bold";
}
.card__status {
font-size: 16px;
}
.card__descraption-box {
padding: 0 2em 0 7em;
font-size: 16px;
}
.card__descraption-title {
margin: 0;
font-size: 16px;
font-family: "manrope-bold";
}
.card__descraption {
font-size: 16px;
font-family: "manrope-regular";
display: -webkit-box;
-webkit-box-orient: vertical;
overflow: hidden;
}
@keyframes revealAnimation {
0% {
transform: scale(0) translate(-50%, -50%);
opacity: 0;
}
100% {
transform: scale(1) translate(0, 0);
opacity: 1;
}
}
< /code>
Я хочу отображение в соответствии с нижепроводом, но я пустые результаты /данные при фильтрации или при выполнении:
< /p>
Но получить вывод ниже и отображать сообщение при обновлении страницы" Загрузка портфелей ... "
Итак, пожалуйста, направляйте меня, где точная проблема, почему данные не отображается. Я отлаживаю код много раз, но не могу найти фактическую проблему.
Подробнее здесь: https://stackoverflow.com/questions/793 ... g-servlets
Мобильная версия