How to use HttpServletRequest in Spring boot 2.x? - spring-boot

I want to use HttpServletRequest in spring boot 2.x. Here are my example:
<a class="dropdown-item" th:href="${'?'+(#httpServletRequest.getParameter('categoryId')==null?'':('&categoryId='+#httpServletRequest.getParameter('categoryId')))
+(#httpServletRequest.getParameter('page')==null?'':('&page='+#httpServletRequest.getParameter('page')))
+(#httpServletRequest.getParameter('size')==null?'':('&size='+#httpServletRequest.getParameter('size')))
+('&sortByPrice=ASC')
+(#httpServletRequest.getParameter('name')==null?'':('&name='+#httpServletRequest.getParameter('name')))}">Price ASC</a>
I use this config but it returns errors about templates. How can I config to use that?
#Bean
public TomcatServletWebServerFactory containerFactory() {
return new TomcatServletWebServerFactory() {
protected void customizeConnector(Connector connector) {
int maxSize = 50000000;
super.customizeConnector(connector);
connector.setMaxPostSize(maxSize);
connector.setMaxSavePostSize(maxSize);
if (connector.getProtocolHandler() instanceof AbstractHttp11Protocol) {
((AbstractHttp11Protocol <?>) connector.getProtocolHandler()).setMaxSwallowSize(maxSize);
logger.info("Set MaxSwallowSize "+ maxSize);
}
}
};
}
/**
* Fix bean cookie
* #return
*/
#Component
public class CustomContainer implements
WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
#Override
public void customize(TomcatServletWebServerFactory factory) {
factory.setContextPath("");
factory.setPort(8080);
}
}

you could Add HttpServletRequest as parameter to your controller
#RequestMapping(value="/") public String home(HttpServletRequest request){
System.out.println("My Attribute :: "+request.getAttribute("YourAttributeName"));
return "home"; }
OR
you could access HttpServletRequest via injecting it in your class
#Autowired
private HttpServletRequest context;

Related

Spring Security - Process custom annotation in GenericFilterBean

in my controller I have a custom annotation like:
#GetMapping("/apikey")
#Secured(apiKeys = { ApiKey.APP_1}) // <- Custom annotation
public ResponseEntity startApiKey() {
return ResponseEntity.status(HttpStatus.OK).body("ApiKey approved");
}
In my Spring Security Config I have added a Filter for checking the apikey and authentication:
public class ApiKeyAuthenticationFilter extends AbstractPreAuthenticatedProcessingFilter {
#Override
protected Object getPreAuthenticatedPrincipal(HttpServletRequest request) {
return request.getHeader(ApiKeyHeadername.DEFAULTHEADERNAME.getHeadername());
}
#Override
protected Object getPreAuthenticatedCredentials(HttpServletRequest request) {
return "N/A";
}
#Override
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
super.setAuthenticationManager(authentication -> {
String principal = (String) authentication.getPrincipal();
if (!ApiKey.APP_1.getApiKey().equals(principal))
{
throw new BadCredentialsException("The API key was not found or not the expected value.");
}
authentication.setAuthenticated(true);
return authentication;
});
}
}
Before the custom annotation was proccessed within a AspectJ class:
#Component
#Aspect
#Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class SecurityAspect {
#Autowired
private IPrincipal principal;
#Autowired
private AuthorizationManager authorizationManager;
#Pointcut("#annotation(my.demo.application.security.aspect.Secured)")
public void methodAnnotatedWithSecured() {
}
#Around("methodAnnotatedWithSecured()")
public Object userAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
Secured securedAnnotation = method.getAnnotation(Secured.class);
Authorized securityInformation = new Authorized(securedAnnotation.apiKeys(), securedAnnotation.roles(),
securedAnnotation.usernames());
if (authorizationManager.authorizeUserPrincipal(principal,
securityInformation) == AuthorizationState.UNAUTHORIZED) {
throw DefaultNotAuthorizedExceptionFactory.createNotAuthorizedException();
}
return joinPoint.proceed();
}
}
How can I process the annotation informations in the AbstractPreAuthenticatedProcessingFilter, or how can i get the annotation by Reflection in this Filter. Or can I inject something to get it?
Thank you in advice

Adding custom header to response in spring rest / spring boot

i am trying to send session id in response header in rest controller but excludepathpattern() seems not working
** the configuration class is not triggering **
i have tried changing the sevlet version but it didnt work
ContextListener
#Override
public void contextInitialized(ServletContextEvent sce) {
ServletContext context = sce.getServletContext();
Map<String, HttpSession> map = new HashMap<>();
context.setAttribute("activeUsers", map);
HttpSessionListener
ServletContext context = session.getServletContext();
Map<String, HttpSession> activeUsers = (Map<String, HttpSession>) context.getAttribute("activeUsers");
activeUsers.put(session.getId(), session);
HandlerInterceptor
ServletContext context = request.getServletContext();
Map<String, HttpSession> activeUsers = (Map<String, HttpSession>) context.getAttribute("activeUsers");
String sessionId = request.getHeader("sessionId");
String requestUrl = request.getRequestURL().toString();
if (requestUrl.contains("/getOtp") || requestUrl.contains("/validateOtp")) {
return true;
} else {
if (activeUsers.containsKey(sessionId)) {
return true;
} else {
response.setStatus(401);
return false;
}
}
interceptorconfigurartion by extendig websecurityconfigure
#Configuration
#EnableAutoConfiguration
public class SessionInterceptorConfig implements WebMvcConfigurer {
#Autowired
private SessionHanlderInterceptor sessionHandlerIntercepto;
#Override
public void addInterceptors(InterceptorRegistry registry) {
// List<String> paths = new ArrayList<String>();
// paths.add("/auth/*");
registry.addInterceptor(sessionHandlerIntercepto).excludePathPatterns("/auth/**");
}
#Bean
public ServletListenerRegistrationBean<CustomSessionListener> filterRegistrationBean() {
ServletListenerRegistrationBean<CustomSessionListener> registrationBean = new ServletListenerRegistrationBean<CustomSessionListener>();
CustomSessionListener customURLFilter = new CustomSessionListener();
registrationBean.setListener(customURLFilter);
registrationBean.setOrder(1); // set precedence
return registrationBean;
}
#Bean
public ServletListenerRegistrationBean<CustomServletContextListener> filterContextRregistration() {
ServletListenerRegistrationBean<CustomServletContextListener> registrationBean = new ServletListenerRegistrationBean<CustomServletContextListener>();
CustomServletContextListener customURLFilter = new CustomServletContextListener();
registrationBean.setListener(customURLFilter);
registrationBean.setOrder(1); // set precedence
return registrationBean;
}
Sprinboot main class
#SpringBootApplication
public class CustomerApplication extends SpringBootServletInitializer {
i expect to add the session id to header in response and to check for the sessionid in request
You can use spring web component "OncePerRequestFilter". You need to inject a bean which extends OncePerRequestFilter. Example:
public class CustomHeaderFilter extends OncePerRequestFilter {
#Override
public void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response,
final FilterChain chain) throws IOException, ServletException {
response.setHeader(customHeaderName, customHeaderValue);
chain.doFilter(request, response);
}
}

Expose Togglz Admin console in Spring Boot on management-port

By default Togglz admin console runs on application port (configured by server.port property). I want to expose it on management.port. My question: is it possible?
If you use Togglz >= 2.4.0 then this feature is available out of the box.
For older releases solution is below:
I managed to expose a raw servlet on management.port by wrapping it with MvcEndpoint.
The easiest way to do it to use Spring Cloud module which does all the job for you (for example in the HystrixStreamEndpoint):
public class HystrixStreamEndpoint extends ServletWrappingEndpoint {
public HystrixStreamEndpoint() {
super(HystrixMetricsStreamServlet.class, "hystrixStream", "/hystrix.stream",
true, true);
}
}
In the case of TogglzConsoleServlet there is unfortunately one more hack to do with path's due to the way it extracts prefix from request URI, so the whole solution looks a little bit ugly:
#Component
class TogglzConsoleEndpoint implements MvcEndpoint {
private static final String ADMIN_CONSOLE_URL = "/togglz-console";
private final TogglzConsoleServlet togglzConsoleServlet;
#Autowired
TogglzConsoleEndpoint(final ServletContext servletContext) throws ServletException {
this.togglzConsoleServlet = new TogglzConsoleServlet();
togglzConsoleServlet.init(new DelegatingServletConfig(servletContext));
}
#Override
public String getPath() {
return ADMIN_CONSOLE_URL;
}
#Override
public boolean isSensitive() {
return true;
}
#Override
public Class<? extends Endpoint> getEndpointType() {
return null;
}
#RequestMapping("**")
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequestWrapper requestWrapper = new HttpServletRequestWrapper(request) {
#Override
public String getServletPath() {
return ADMIN_CONSOLE_URL;
}
};
togglzConsoleServlet.service(requestWrapper, response);
return null;
}
private class DelegatingServletConfig implements ServletConfig {
private final ServletContext servletContext;
DelegatingServletConfig(final ServletContext servletContext) {
this.servletContext = servletContext;
}
#Override
public String getServletName() {
return TogglzConsoleEndpoint.this.togglzConsoleServlet.getServletName();
}
#Override
public ServletContext getServletContext() {
return servletContext;
}
#Override
public String getInitParameter(final String name) {
return servletContext.getInitParameter(name);
}
#Override
public Enumeration<String> getInitParameterNames() {
return servletContext.getInitParameterNames();
}
}
}

Spring MVC with Atmosphere

I have recently started with Atmosphere. I need it to implement it in a Spring MVC application.
Till now I've managed to integrate it with Spring MVC.
I just need to perform a very simple task. I have a counter an instance variable as soon as it reaches 10, a response should be broadcasted to the UI.
Can anyone help me how do I write the code for that in the controller.
I've got the Atmosphere resource into the controller.
AtmosphereArgumentResolver.java
public class AtmosphereArgumentResolver implements HandlerMethodArgumentResolver {
//#Override
public boolean supportsParameter(MethodParameter parameter) {
return AtmosphereResource.class.isAssignableFrom(parameter.getParameterType());
}
//#Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception
{
HttpServletRequest httpServletRequest= webRequest.getNativeRequest(HttpServletRequest.class);
return Meteor.build(httpServletRequest).getAtmosphereResource();
}
}
HomeController.java
#Controller
public class HomeController {
private int counter = 0;
private final BroadcasterFactory bf;
public BroadcasterFactory broadcasterFactory()
{
return BroadcasterFactory.getDefault();
}
for(int i=0; i<=15; i++)
{
counter ++;
}
// As soon as the counter reaches 10 I need to send a broadcast message to the UI.
}
Can anyone please help? A skeleton code would also help as in which Atmosphere method to use for this?
I will copy/past the code i use in my application :
Controller :
#ManagedService(path = "/websocket/*")
#Singleton
public class LanesWebSocket {
private final Logger logger = LoggerFactory.getLogger(LanesWebSocket.class);
// private ScheduledExecutorService scheduledExecutorService;
private Future<?> scheduleFixedBroadcast;
private final ObjectMapper mapper = new ObjectMapper();
private SupervisionCenterService supervisionCenterService;
#Ready
public void onReady(final AtmosphereResource resource) {
if (this.supervisionCenterService == null)
supervisionCenterService = SpringApplicationContext.getBean(SupervisionCenterService.class);
Broadcaster bc = BroadcasterFactory.getDefault().lookup("lanes",true);
bc.addAtmosphereResource(resource);
scheduleFixedBroadcast = bc.scheduleFixedBroadcast(new Callable<String>() {
#Override
public String call() throws Exception {
try {
return mapper.writeValueAsString(supervisionCenterService.findCenterData());
} catch (Exception e) {
scheduleFixedBroadcast.cancel(true);
e.printStackTrace();
return null;
}
}
}, 1, TimeUnit.SECONDS);
}
And you also need to register the atmosphere servlet :
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
[...]
#Override
protected void registerDispatcherServlet(ServletContext servletContext) {
super.registerDispatcherServlet(servletContext);
initAtmosphereServlet(servletContext);
}
private void initAtmosphereServlet(ServletContext servletContext) {
AtmosphereServlet servlet = new AtmosphereServlet();
Field frameworkField = ReflectionUtils.findField(AtmosphereServlet.class, "framework");
ReflectionUtils.makeAccessible(frameworkField);
ReflectionUtils.setField(frameworkField, servlet, new NoAnalyticsAtmosphereFramework());
ServletRegistration.Dynamic atmosphereServlet =
servletContext.addServlet("atmosphereServlet", servlet);
atmosphereServlet.setInitParameter("org.atmosphere.cpr.packages", "com.myclient.theproduct.supervision.websocket");
atmosphereServlet.setInitParameter("org.atmosphere.cpr.broadcasterCacheClass", UUIDBroadcasterCache.class.getName());
atmosphereServlet.setInitParameter("org.atmosphere.cpr.broadcaster.shareableThreadPool", "true");
atmosphereServlet.setInitParameter("org.atmosphere.cpr.broadcaster.maxProcessingThreads", "10");
atmosphereServlet.setInitParameter("org.atmosphere.cpr.broadcaster.maxAsyncWriteThreads", "10");
servletContext.addListener(new org.atmosphere.cpr.SessionSupport());
atmosphereServlet.addMapping("/websocket/*");
atmosphereServlet.setLoadOnStartup(3);
atmosphereServlet.setAsyncSupported(true);
}
public class NoAnalyticsAtmosphereFramework extends AtmosphereFramework {
public NoAnalyticsAtmosphereFramework() {
super();
}
#Override
protected void analytics() {
// nothing
}
}
}
Don't ask me the reason of the NoAnalyticsAtmosphereFramework class, it could not work without.
Hope this will help you !

How to access a Jersey bean from Spring FactoryBean?

I have a Spring BeanFactory and I need to inject httpHeaders to it.
public class SpecificFactoryBean extends SomeFactoryBean<Exception> {
#Context
private HttpHeaders httpHeaders;
protected SpecificFactoryBean() {
super(Exception.class);
}
#Override
protected void doRegistration(RegistryBuilder<Exception> registryBuilder) {
registryBuilder.registerMapper(WebApplicationException.class, new ExceptionMapper<WebApplicationException>() {
#Override
public int map(WebApplicationException e) {
httpHeaders.getSomeInfo();
return 3;
}
});
}
}
Now #Context doesn't work, so how can I do this?

Resources