cdi observe session scoped bean changed - java

i'm trying to observes a #SessionScoped component after change any property. HttpSessionAttributeListener not fire changes in cdi managed components.
#SuppressWarnings("serial")
#SessionScoped
public class TestSession implements Serializable {
private User user;
public TestSession() {
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
An example Servlet:
#SuppressWarnings("serial")
#WebServlet(name = "demo", urlPatterns = "/demo")
public class DemoServlet extends HttpServlet {
private static final Logger logger = LoggerFactory.getLogger(DemoServlet.class);
#Inject
private TestSession testSession;
#Override
protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
throws ServletException, IOException {
User user = new User(1L,new Role(1L));
user.setId(RandomUtils.nextLong());
testSession.setUser(user); //listen that component change something
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/WEB-INF/jsp/demo.jsp");
dispatcher.forward(httpServletRequest, httpServletResponse);
}
}
Is the a way to listen when component change any attribute ? Anyone has some approach to do that ?
Important : I dont have access to rewrite or add code on TestSession java class or servlet .

You can place an interceptor in the setUser() method that creates an event then catch it.

Related

Injected Bean is null in my quarkus extension

I have a quite simple quarkus extension which defines a ContainerRequestFilter to filter authentication and add data to a custom AuthenticationContext.
Here is my code:
runtime/AuthenticationContext.java
public interface AuthenticationContext {
User getCurrentUser();
}
runtime/AuthenticationContextImpl.java
#RequestScoped
public class AuthenticationContextImpl implements AuthenticationContext {
private User user;
#Override
public User getCurrentUser() {
return user;
}
public void setCurrentUser(User user) {
this.user = user;
}
}
runtime/MyFilter.java
#ApplicationScoped
public class MyFilter implements ContainerRequestFilter {
#Inject
AuthenticationContextImpl authCtx;
#Override
public void filter(ContainerRequestContext requestContext){
// doing some stuff like retrieving the user from the request Context
// ...
authCtx.setCurrentUser(retrievedUser)
}
}
deployment/MyProcessor.java:
class MyProcessor {
//... Some stuff
#BuildStep
AdditionalBeanBuildItem createContext() {
return new AdditionalBeanBuildItem(AuthenticationContextImpl.class);
}
}
I have a Null Pointer Exception in authCtx.setCurrentUser(retrievedUser) call (authCtx is never injected)
What am I missing here ?
Thanks
Indexing the runtime module of the extension fixes the problem.
There are multiple ways to do that as mentioned in https://stackoverflow.com/a/55513723/2504224

How to retrieve SecurityContext in a Quarkus application?

I have a Quarkus application in which I implemented the ContainerRequestFilter interface to save a header from incoming requests:
#PreMatching
public class SecurityFilter implements ContainerRequestFilter {
private static final String HEADER_EMAIL = "HD-Email";
#Override
public void filter(ContainerRequestContext requestContext) throws IOException {
String email = requestContext.getHeaders().getFirst(HEADER_EMAIL);
if (email == null) {
throw new AuthenticationFailedException("Email header is required");
}
requestContext.setSecurityContext(new SecurityContext() {
#Override
public Principal getUserPrincipal() {
return () -> email;
}
#Override
public boolean isUserInRole(String role) {
return false;
}
#Override
public boolean isSecure() {
return false;
}
#Override
public String getAuthenticationScheme() {
return null;
}
});
}
}
In a class annotated with ApplicationScoped I injected the context as follows:
#ApplicationScoped
public class ProjectService {
#Context
SecurityContext context;
...
}
The problem is that the context attribute is actually never injected, as it is always null.
What am I doing wrong? What should I do to be able to retrieve the SecurityContext throughout the application's code?
I like to abstract this problem, so that the business logic does not depend on JAX-RS-specific constructs. So, I create a class to describe my user, say User, and another interface, the AuthenticationContext, that holds the current user and any other authentication-related information I need, e.g.:
public interface AuthenticationContext {
User getCurrentUser();
}
I create a RequestScoped implementation of this class, that also has the relevant setter(s):
#RequestScoped
public class AuthenticationContextImpl implements AuthenticationContext {
private User user;
#Override
public User getCurrentUser() {
return user;
}
public void setCurrentUser(User user) {
this.user = user;
}
}
Now, I inject this bean and the JAX-RS SecurityContext in a filter, that knows how to create the User and set it into my application-specific AuthenticationContext:
#PreMatching
public class SecurityFilter implements ContainerRequestFilter {
#Inject AuthenticationContextImpl authCtx; // Injecting the implementation,
// not the interface!!!
#Context SecurityContext securityCtx;
#Override
public void filter(ContainerRequestContext requestContext) throws IOException {
User user = ...// translate the securityCtx into a User
authCtx.setCurrentUser(user);
}
}
And then, any business bean that needs the user data, injects the environment-neutral, application-specific AuthenticationContext.
#Context can only be used in JAX-RS classes - i.e. classes annotated with #Path.
In your case, ProjectService is a CDI bean, not a JAX-RS class.
The canonical way to do what you want is to inject the SecurityContext into a JAX-RS resource and then pass that as a method parameter to your ProjectService

Spring Boot - set value from an external properties file

I have an external location set on my application.properties as below
spring.config.location=file:${catalina.home}/conf/app.properties
app.properties has a property as timeOut=10000. There are many other properties as well.
I need to set this property on my session something like this:
session.setMaxInactiveInterval(timeOut_Property);
How can this be achieved?
Adding Controller:
#Controller
public class StartController {
#Value("${spring.config.location.defaultTimeout}")
private int defaultTimeout;
#RequestMapping("login.do")
public String login(HttpServletRequest request, HttpSession session, Model model) {
session.setMaxInactiveInterval(defaultTimeout);
return null;
}
Your Main Application class should look like this:
#SpringBootApplication
#PropertySource(name = "general-properties", value = { "classpath:path to your app.properties"})
public class MainApplication {
public static void main(String[] args) {
SpringApplication.run(NayapayApplication.class, args);
}
}
And change your controller to:
#Controller
public class StartController {
#Value("${timeOut}")
private int defaultTimeout;
#RequestMapping("login.do")
public String login(HttpServletRequest request, HttpSession session, Model model) {
session.setMaxInactiveInterval(defaultTimeout);
return null;
}
}
You can annotate the variable with this property in the class as:
#Value("${timeOut}")
private String timeOut;
Use this variable to set session inactive interval as:
session.setMaxInactiveInterval(timeOut);

Getting Null in request.getAttribute(..) in Struts 2

Setting Attribute
public class VoucherApproverListAction extends ActionSupport implements
SessionAware, ServletRequestAware, Preparable {
private HttpServletRequest servletRequest;
public HttpServletRequest getServletRequest() {
return servletRequest;
}
#Override
public void setServletRequest(HttpServletRequest servletRequest) {
this.servletRequest=servletRequest;
}
public void prepare() throws Exception {
servletRequest.setAttribute("id",tCaseVouchrDto.getId());
}
}
Getting Attribute
public class VoucherAction extends ActionSupport implements
SessionAware, ServletRequestAware, Preparable {
private HttpServletRequest servletRequest;
public HttpServletRequest getServletRequest() {
return servletRequest;
}
#Override
public void setServletRequest(HttpServletRequest servletRequest) {
this.servletRequest=servletRequest;
}
public void prepare() throws Exception {
String paramValue = (String)servletRequest.getAttribute("id");
logger.info("#-----Id===-----#" + paramValue);
}
}
From VoucherApproverListAction action class after success ,it is redirected to VoucherAction action class Getting null in paramValue
From VoucherApproverListAction action class after success ,it is
redirected to VoucherAction action class
This is the problem, request attributes are lost if you send redirect. You need to pass a parameter or save it in the session before the next request.

Accessing Session variable in action class

i have struts2.0 in my project, i am storing username in session by implements SessionAware done as follows
public class NewProduct extends ActionSupport implements SessionAware{
private Map session;
public String execute() {
session.put("username", "Rangappa");
return "success"
}
public void setSession(Map session) {
this.session = session;
}
public Map getSession() {
return session;
}
here I am setting session variable here, i m not getting how to get this session variable in other class,
i done as below but its not working
public class NewProduct extends ActionSupport implements SessionAware{
public String execute() throws Exception {
String username = (String) session.get("username");
System.out.println("username: "+username );
return "success"
}
}
both class are in same packages, please let me know solution, Thanks i advance
Use this code after importing the appropriate packages
Map session = ActionContext.getContext().get("session");
String userName = (String)(session.get("username"));

Categories