feat: add rest

This commit is contained in:
Sergey Krylov 2026-02-24 06:03:42 +03:00
parent d52a1d7914
commit 3faa214d18
9 changed files with 150 additions and 3 deletions

Binary file not shown.

BIN
lib/jackson-core-2.21.0.jar Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -14,6 +14,9 @@ import java.io.IOException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Set; import java.util.Set;
import static ru.charm.back.utils.UrlUtils.LOGIN_REST_URL;
import static ru.charm.back.utils.UrlUtils.REST_URL;
@WebFilter("/*") @WebFilter("/*")
@Slf4j @Slf4j
public class AuthFilter implements Filter { public class AuthFilter implements Filter {
@ -24,12 +27,15 @@ public class AuthFilter implements Filter {
HttpServletRequest req = (HttpServletRequest) servletRequest; HttpServletRequest req = (HttpServletRequest) servletRequest;
HttpServletResponse res = (HttpServletResponse) servletResponse; HttpServletResponse res = (HttpServletResponse) servletResponse;
if (PRIVATE_PATHS.contains(req.getRequestURI())) { if (!LOGIN_REST_URL.equals(req.getRequestURI()) && PRIVATE_PATHS.contains(req.getRequestURI())) {
ProfileGetDto userDetails = (ProfileGetDto) req.getSession().getAttribute("userDetails"); ProfileGetDto userDetails = (ProfileGetDto) req.getSession().getAttribute("userDetails");
log.info("User {} is trying to access {}", userDetails, req.getRequestURI()); log.info("User {} is trying to access {}", userDetails, req.getRequestURI());
if (userDetails == null) { if (userDetails == null) {
res.sendError(HttpServletResponse.SC_UNAUTHORIZED); res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
} else if (userDetails.getRole() == Role.ADMIN || userDetails.getId().toString().equals( req.getParameter("id"))) { } else if (!req.getRequestURI().startsWith(REST_URL) &&
userDetails.getRole() == Role.ADMIN ||
userDetails.getId().toString().equals( req.getParameter("id"))
) {
filterChain.doFilter(req, res); filterChain.doFilter(req, res);
} else { } else {
res.sendError(HttpServletResponse.SC_FORBIDDEN); res.sendError(HttpServletResponse.SC_FORBIDDEN);

View File

@ -9,6 +9,8 @@ import lombok.extern.slf4j.Slf4j;
import java.io.IOException; import java.io.IOException;
import static jakarta.servlet.RequestDispatcher.ERROR_EXCEPTION; import static jakarta.servlet.RequestDispatcher.ERROR_EXCEPTION;
import static jakarta.servlet.RequestDispatcher.ERROR_REQUEST_URI;
import static ru.charm.back.utils.UrlUtils.REST_URL;
@WebFilter(value = "/*", dispatcherTypes = DispatcherType.ERROR) @WebFilter(value = "/*", dispatcherTypes = DispatcherType.ERROR)
@Slf4j @Slf4j
@ -26,6 +28,14 @@ public class ErrorFilter implements Filter {
log.warn("Exception code {}", res.getStatus()); log.warn("Exception code {}", res.getStatus());
} }
filterChain.doFilter(servletRequest, servletResponse); String requestUri = (String) req.getAttribute(ERROR_REQUEST_URI);
if (requestUri.startsWith(REST_URL)) {
res.setContentType("application/json");
res.setCharacterEncoding("UTF-8");
} else {
filterChain.doFilter(servletRequest, servletResponse);
}
} }
} }

View File

@ -0,0 +1,46 @@
package ru.charm.back.controller.rest;
import com.fasterxml.jackson.databind.DatabindException;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import ru.charm.back.dto.LoginDto;
import ru.charm.back.dto.ProfileGetDto;
import ru.charm.back.mapper.RequestToLoginDtoMapper;
import ru.charm.back.service.ProfileService;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.Optional;
import static ru.charm.back.utils.UrlUtils.LOGIN_REST_URL;
@WebServlet(LOGIN_REST_URL)
@Slf4j
public class LoginController extends HttpServlet {
private final ProfileService service = ProfileService.getInstance();
private final ObjectMapper objectMapper = new ObjectMapper();
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
try (BufferedReader reader = req.getReader()) {
LoginDto dto = objectMapper.readValue(reader, LoginDto.class);
Optional<ProfileGetDto> userDetailOpt = service.login(dto);
if (userDetailOpt.isPresent()) {
req.getSession().setAttribute("userDetails", userDetailOpt.get());
return;
} else {
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
} catch (DatabindException e) {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST);
}
}
}

View File

@ -0,0 +1,52 @@
package ru.charm.back.controller.rest;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import jakarta.servlet.annotation.MultipartConfig;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import ru.charm.back.dto.ProfileGetDto;
import ru.charm.back.service.ProfileService;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Optional;
import static jakarta.servlet.http.HttpServletResponse.SC_NOT_FOUND;
import static ru.charm.back.utils.UrlUtils.REST_URL;
@WebServlet(REST_URL + "/profile")
@MultipartConfig
public class ProfileController extends HttpServlet {
private final ProfileService service = ProfileService.getInstance();
private final ObjectMapper objectMapper = JsonMapper.builder()
.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true)
.addModule(new JavaTimeModule())
.build();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
try (PrintWriter writer = resp.getWriter()) {
resp.setContentType("application/json");
resp.setCharacterEncoding("UTF-8");
String sId = req.getParameter("id");
if (sId != null) {
Optional<ProfileGetDto> optProfileDto = service.findById(Long.parseLong(sId));
if (optProfileDto.isPresent()) {
ProfileGetDto profileGetDto = optProfileDto.get();
objectMapper.writeValue(writer, profileGetDto);
} else {
resp.sendError(SC_NOT_FOUND);
}
} else {
objectMapper.writeValue(writer, service.findAll());
}
}
}
}

View File

@ -0,0 +1,33 @@
package ru.charm.back.utils;
import lombok.experimental.UtilityClass;
import java.util.Set;
@UtilityClass
public class UrlUtils {
public static final String PROFILE_URL = "/profile";
public static final String CREDENTIALS_URL = "/credentials";
public static final String LOGIN_URL = "/login";
public static final String LOGOUT_URL = "/logout";
public static final String REGISTRATION_URL = "/registration";
public static final String LANG_URL = "/lang";
public static final String CONTENT_URL = "/content";
public static final String BASE_CONTENT_PATH = "/Users/andrey.s.eliseev/Downloads";
public static final Set<String> PRIVATE_PATHS = Set.of(PROFILE_URL, CREDENTIALS_URL);
public static final Set<String> ENTRY_PATHS = Set.of(LOGIN_URL, REGISTRATION_URL);
public static String getJspPath(String url) {
return "/WEB-INF/jsp" + url + ".jsp";
}
public static final String REST_URL = "/api/v1";
public static final String LOGIN_REST_URL = REST_URL + LOGIN_URL;
public static String getProfilePhotoPath(Long id, String fileName) {
return "/profiles/" + id + "/" + fileName;
}
}