Server side session management in GWTP - gwt

Hello I am using GWTP for my application development. In the application I am in need to server side session instance to put some data in that session instance. I saw some examples of GWT where there is Action class which extends ActionSupport class.
There are some method in the examples through which we can have the server side session instance.Like below :
public HttpServletRequest getRequest() {
return ServletActionContext.getRequest();
}
public HttpServletResponse getResponse() {
return ServletActionContext.getResponse();
}
public HttpSession getSession() {
HttpSession session = getRequest().getSession();
return session;
}
But I am not getting the similar thing in GWTP. Please help me out. Thanks in Advance.

Finally I got some thing which is helping me.I am sharing this here.
private Provider<HttpServletRequest> requestProvider;
private ServletContext servletContext;
#Inject
public LoginCallerActionHandler(
Provider<HttpServletRequest> requestProvider,
ServletContext servletContext) {
super();
this.requestProvider = requestProvider;
this.servletContext = servletContext;
}
Here is my action handler class.In which i can use session.
servletContext.setAttribute(SessionKeys.LOGGEDIN_USER.toString(), returnObject.getLoggedInUser());

If you are using Spring or Guice on your server side you can get Request/Response injected into your Action. For example, if your are using GWTP's DispatchServletModule, you can use features of Guice's ServletModule as:
DispatchServletModule extends Guice ServletModule and maps request
URLs to handler classes.
Here's an example from Guice wiki:
#RequestScoped
class SomeNonServletPojo {
#Inject
SomeNonServletPojo(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
...
}
}
I am not sure if GWTP binds the handlers in Singleton scope or not. If it does bind it in singleton you should inject a Provider instead.

Related

Same QueryParams In All JAX-RS Endpoints

I have a requirement that a few QueryParams should be present in absolutely all JAX-RS endpoints of my application.
Is there a way to specify somewhere, only once, these parameters? Or do I have to repeat myself in all method endpoints?
Thank you!
I would implement a ContainerRequestFilter and handle the parameters there. You can add the result to the ContainerRequestContext:
#Provider
public class MyFilter implements ContainerRequestFilter {
#Override
public void filter(ContainerRequestContext requestContext) throws IOException {
Object result = // handle the parameter
requestContext.setProperty("myParam", result);
}
}
Your implementation will of course depend on your needs.
You can inject the context into your resource classes like:
#Context
private ContainerRequestContext containerRequestContext;
See also:
Jersey 2 filter uses Container Request Context in Client Request Filter

Swagger UI does not list any of the controller/end points though I am able to see the json under v2/api-docs endpoint

I am not able to get my Swagger UI to work with my project. Swagger UI comes up fine but it does not list any of my REST controllers.
I am using SPRING 4.2.6.RELEASE and Swagger 2.5.0 . My rest services are deployed to Tomcat 7.0.54 .
When Tomcat 7.0.54 comes up, it is able to fetch the swagger end points.
I am able to hit the endpoint v2/api-docs that fetches the json messages.
I am also able to hit the swagger-ui but I dont see any controllers listed.
The dropdowns are empty, as below
**The issue I am facing currently is that
I am not able to fetch the /swagger-resources/configuration/ui, when I launch the swagger UI I get 404 (Not Found) errror while the UI is trying to fetch /swagger-resources/configuration/ui . I have setup resource handlers for swagger-resources, but that does not seem to help. Can you please let me know what could be missing?
Should I be seeing resources folder under META-INF in my expanded WAR? Should there be any springfox related files/folder inside META-INF?
**
Maven dependency for Swagger
io.springfox
springfox-swagger2
2.5.0
io.springfox
springfox-swagger-ui
2.5.0
Below is my SwaggerCongifuration
#EnableSwagger2
public class SwaggerConfiguration {
#Bean
public Docket api() {
List<SecurityContext> security = new ArrayList<SecurityContext>();
security.add(securityContext());
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build()
.pathMapping("/").securityContexts(security);
}
private SecurityContext securityContext() {
return SecurityContext.builder()
.forPaths(PathSelectors.regex("/"))
.build();
}
}
Below is my WebConfig.xml
#EnableWebMvc
#Configuration
#Import(SwaggerConfiguration.class)
#ComponentScan("com.bank.direct.services")
public class WebConfig extends WebMvcConfigurerAdapter {
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> pConverters) {
pConverters.add(RestUtils.getJSONMessageConverter());
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
}
Below is the SecurityCongif.xml
#EnableWebSecurity
#EnableGlobalMethodSecurity(prePostEnabled = true)
#Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private AuthenticationService _authenticationService;
#Autowired
public void globalUserDetails(AuthenticationManagerBuilder pAuth) throws Exception {
pAuth.userDetailsService(_authenticationService);
}
#Override
protected void configure(HttpSecurity pHttp) throws Exception {
// Enable HTTP caching
pHttp.headers().cacheControl().disable();
// Configure security
pHttp.httpBasic()
// -- Allow only authenticated request
.and()
.authorizeRequests()
.anyRequest().authenticated()
// -- Logout configuration
.and()
.logout()
.logoutUrl("/rest/users/logout/")
.deleteCookies("XSRF-TOKEN")
.logoutSuccessUrl("/static/index.html")
.invalidateHttpSession(true)
// -- CSRF configuration
.and()
.csrf().csrfTokenRepository(csrfTokenRepository())
.and()
.addFilterAfter(csrfHeaderFilter(), SessionManagementFilter.class);
}
private Filter csrfHeaderFilter() {
return new OncePerRequestFilter() {
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class.getName());
if (csrf != null) {
Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
String token = csrf.getToken();
if (cookie == null || token != null && !token.equals(cookie.getValue())) {
cookie = new Cookie("XSRF-TOKEN", token);
cookie.setPath("/");
response.addCookie(cookie);
}
}
filterChain.doFilter(request, response);
}
};
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
Rest Controller class as below
#RestController
#RequestMapping(value = "/vehicles", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public class VehicleResource extends Resource {
#Autowired
private IVehicleService _vehicleService;
#RequestMapping(value = "/brands", method = RequestMethod.GET)
public APIResponseEntity getBrands(WebRequest pWebRequest) {
IUser user = getUser(pWebRequest);
BrandCriteria criteria = new BrandCriteria();
criteria.setLanguageCode(user.getLanguageCode());
List<Brand> res = _vehicleService.getBrands(user, criteria);
return newResponseOK(res);
}
#RequestMapping(value = "/brands/{brand_code}", method = RequestMethod.GET)
public APIResponseEntity getBrand(WebRequest pWebRequest, #PathVariable("brand_code") String pBrandCode) {
IUser user = getUser(pWebRequest);
BrandCriteria criteria = new BrandCriteria();
criteria.setLanguageCode(user.getLanguageCode());
criteria.setBrandCode(pBrandCode);
List<Brand> res = _vehicleService.getBrands(user, criteria);
return newResponseOK(res);
}
}
After migrating an older project from XML Spring configuration to Java Spring configuration and updating spring and Swagger versions I struggled with an issue that sounds exactly like this so I thought I'd document my solution here.
I had a number of problems but the main ones that match the OP's scenario were that while /v2/api-docs was accessible and returned JSON, my Controllers clearly weren't being picked up, and when I accessed the Swagger UI at /swagger-ui.html, I was getting a 404 when that page tried to request /swagger-resources/configuration/ui
My Swagger configuration class was:
#Configuration
#EnableSwagger2
public class SwaggerWebConfig {
#Bean
public Docket api() {
...
}
}
The #EnableSwagger2 annotation imports another configuration class Swagger2DocumentationConfiguration, which in turn imports SwaggerCommonConfiguration, which does a component scan for classes in springfox.documentation.swagger.web which finally loads the ApiResourceController, which is where
/swagger-resources/
/swagger-resources/configuration/security and
/swagger-resources/configuration/ui
are served from.
What I had incorrect was that my SwaggerWebConfig class was being loaded by the root application context, when it should belong to the web application context (see ApplicationContext vs WebApplicationContext).
Beans in the web application context can access beans in the root application context, but not the other way around, which explained why Docket bean (incorrectly in the root application context) could not pick up the #Controller beans in the web application context and also explained why despite the ApiResourceController bean being created, its methods were giving 404's when trying to access them (they should be in the web application context)
A few other notes for related issues:
If you can hit v2/api-docs then your Docket bean is working
In a non-spring-boot environment, you need to register two resource handlers yourself as spring boot's auto-configuration would have done this for you as explained in the answers to this question. That should solve 404's for:
/swagger-ui.html (i.e. 404 fetching the actual html swagger-ui.html page)
and the three webjars that swagger-ui.html loads:
/webjars/springfox-swagger-ui/springfox.js
/webjars/springfox-swagger-ui/swagger-ui-bundle.js
/webjars/springfox-swagger-ui/swagger-ui-standalone-preset.js
If you are getting an access denied rather than a 404 not found, then as shown in this answer, you might need to tell spring security to allow access to:
/webjars/**
/swagger-ui.html
/v2/api-docs
/swagger-resources/**
You need to point the the generated Swagger Definition in Swagger UI. i.e in place of http://example.com/api give your swagger definition path something like http://localhost:8080/RestResource/api/swagger.json
This article might help you more

Is there a way to propagate SessionContext to a new thread (getting WELD-001303)?

there's a session scoped bean 'Identity' which I injected in a #Stateless bean which implements Runnable:
#Stateless
#LocalBean
public class Test implements Runnable {
#Inject
Identity identity;
#Inject
Logger log;
#Override
public void run() {
log.warn("Test: " + this + " " + identity.getAccount().getId());
}
}
There's also a bean which invokes the above Runnable asynchronously:
#Stateless
#LocalBean
public class BeanContextExecutor implements Executor {
#Asynchronous
#Override
public void execute(Runnable command) {
command.run();
}
}
and finally, the invocation looks like this:
#Stateless
public class OtherBean {
#Inject
BeanContextExecutor executor;
...
executor.execute(command);
...
}
When running this I'm getting the following error:
...
Caused by: org.jboss.weld.context.ContextNotActiveException: WELD-001303: No active contexts for scope type javax.enterprise.context.SessionScoped
...
Is there any way to propagate the SessionContext to the background thread?
I also tried to submit this Runnable to ManagedExecutorService and even to create a proxy for it with a ContextService and submit a proxy but still getting the same error.
Thanks for any help with this!
As a workaround in BeanContextExecutor I used BoundSessionContext to create a dummy session context for a new thread and also had to manually copy the required session bean to make its state available in the background thread:
#Inject
BoundSessionContext boundSessionContext;
// Backed by a ConcurrentHashMap<Runnable, Identity> which stores the state of the session scoped bean before spawning a new thread
#Inject
GlobalExecutionContext globalExecutionContext;
#Inject
Instance<Identity> identityInstance;
#Inject
Cloner cloner;
#Inject
private BeanManager beanManager;
#Asynchronous
#Override
public void execute(Runnable command) {
HashMap<String, Object> storage = new HashMap<>();
boundSessionContext.associate(storage);
boundSessionContext.activate();
Identity identity = globalExecutionContext.remove(command);
Bean<Identity> bean = (Bean<Identity>) beanManager.resolve(beanManager.getBeans(Identity.class));
Identity localIdentity = beanManager.getContext(bean.getScope()).get(bean, beanManager.createCreationalContext(bean));
cloner.copyPropertiesOfInheritedClass(identity, localIdentity);
command.run();
boundSessionContext.invalidate();
boundSessionContext.deactivate();
boundSessionContext.dissociate(storage);
}
The example is intended to demonstrate the approach, it's possible to improve it like support passing beans of an arbitrary type. But I don't like this approach at all. There should be a better solution for context propagation problem.
Update:
I'd like to keep the caller identity in a background thread even if initial session is expired, it looks like the above solution is suitable for this.

Can I do setter injection using #Inject annotation

In my GWTP application I need to Inject HttpServletRequest, HttpSession as instance variable of ActionHandler.
My ActionHandler is initialized through Spring.
I can't get current Request object through Spring as it instantiates just POJO.
I am thinking about mixing GIN and Spring.
Would I be able inject HttpServletRequest using GIN in my ActionHandler which is instantiated through Spring?????
Is it possible to do following way??
#Configuration
#Import(DefaultModule.class)
public class ServerModule extends HandlerModule
{
#Bean
public UserVerficationActionHandler getUserVerificationActionActionHandler()
{
return new UserVerficationActionHandler();
}
}
public class UserVerficationActionHandler implements ActionHandler<UserVerficationAction, UserVerficationActionResult>
{
#Autowired
private UserService userService;
private Provider<HttpServletRequest> requestProvider;
#Inject
public UserVerficationActionHandler()
{
}
public UserVerficationActionResult execute(UserVerficationAction action, ExecutionContext context) throws ActionException
{
....
}
#Inject
public Provider<HttpServletRequest> setRequestProvider()
{
return requestProvider;
}
}
-------ActionHandler Ends--------
Can somebody let me know Is it possible to do SetterInjection this way?
Second thing, if above is possible then will I be getting current request object using this method?
Thanks in advance.
Bhavesh.

Connecting gwt-dispatch with guice and mvp4g

I have some questions regarding gwt-dispatch and guice. I'm using Guice 2.0, gwt-dispatch 1.1.0 snapshot, mvp4g 1.1.0 and GIN 1.0
First of all, I have defined simple action, result and handler:
ListContactsAction.java
public class ListContactsAction implements Action<ListContactsResult>{
public ListContactsAction() {
}
}
ListContactsResult.java
public class ListContactsResult implements Result {
private List<Contact> contactList;
public ListContactsResult() {
}
public ListContactsResult(List<Contact> contactList) {
this.contactList = contactList;
}
public List<Contact> getContactList() {
return contactList;
}
}
ListContactsHandler.java
public class ListContactsHandler implements ActionHandler<ListContactsAction, ListContactsResult>{
#Inject
private SqlSessionFactory factory;
public Class<ListContactsAction> getActionType() {
return ListContactsAction.class;
}
public ListContactsResult execute(ListContactsAction a, ExecutionContext ec) throws DispatchException {
// some code using SqlSessionFactory and returning ListContactResult
// with list of contacts
}
public void rollback(ListContactsAction a, ListContactsResult r, ExecutionContext ec) throws DispatchException {
/* get action - no rollback needed */
}
}
In previous version of my app, which was using rpc service instead of command pattern, I had a method which was providing SqlSessionFactory for injections, something like this:
#Provides
public SqlSessionFactory getSqlSessionFactory(){
// some code here
}
I read on gwt-dispatch getting started that I have to provide binding between my action and it's handler, which should look something like that:
public class ContactModule extends ActionHandlerModule{
#Override
protected void configureHandlers() {
bindHandler(ListContactsAction.class, ListContactsHandler.class);
}
}
But I have problem wiring it all with Guice, because this example from gwt-dispatch site:
public class DispatchServletModule extends ServletModule {
#Override
public void configureServlets() {
serve( "/path/to/dispatch" ).with( DispatchServiceServlet.class );
}
}
doesn't work, since there is no DispatchServiceServlet in the package.
My questions are:
How should I write DispatchServletModule and how to make it going (with what I should serve path)
what should I put in the web.xml file of my app to be able to correctly execute actions from my presenter, which has GIN injected DispatcherAsync implementation
Where should I put my SqlSessionFactory providing method (in which module) to be able to inject SqlSessionFactory where I need it
How I instantiate the injector so then I can use it in other action handlers properly
I think that is all and I made myself clear. If something isn't clear enough, I'll try to be more specific.
Have you created a GuiceServletConfig class? This is where you setup your Dispatch servlet module as well as your action handler module with Guice.
plubic class GuiceServletConfig extends GuiceServletContextListener {
#Override
protected Injector getInjector() {
return Guice.createInjector(new HandlerModule(), new DispatchServletModule());
}
}
The HandlerModule is your ActionHandler module class, so from your code you would put your ContactModule class.
For your SqlSessionFactory, you could setup the binding for it in your ContactModule, with my code I only have a single ServerModule that sets up all my service and action handler bindings. This is mainly for the sake of simplicity.
GWT-Platform framework uses a gwt-dispatch fork to handle rpc requests. There's a lot of code, which you probably had to wtite yourself, if you think of seriously using dispatcher and Guice. I highly recommend it.
Firstly, I sympathise. Putting this all together isn't documented in any one spot. I'll answer each of your questions in turn. Add comments to my answer if any of it is unclear.
QU: How should I write DispatchServletModule and how to make it going (with what I should serve path)?
There's a GuiceStandardDispatchServlet class in the net.customware.gwt.dispatch.server.guice package; use that. I'm not 100 percent sure why, but the path I use includes the name of my GWT module, followed by '/dispatch'. You might have to experiment with that.
public class MyServletModule extends ServletModule {
#Override protected void configureServlets() {
serve("/com.my.module.name/dispatch")
.with(GuiceStandardDispatchServlet.class);
}
}
QU: what should I put in the web.xml file of my app to be able to correctly execute actions from my presenter, which has GIN injected DispatcherAsync implementation?
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>com.myapp.whatever.MyContextListener</listener-class>
</listener>
...
</web-app>
... and then you'll need a custom context listener that creates a Guice injector as follows. Notice that I've included your ContactModule, which binds action handlers.
public class MyContextListener extends GuiceServletContextListener {
#Override protected Injector getInjector() {
return Guice.createInjector(new MyServletModule(),
new ContactModule(), new SQLStuffModule());
}
}
QU: Where should I put my SqlSessionFactory providing method (in which module) to be able to inject SqlSessionFactory where I need it?
Notice that I included a new SQLStuffModule in the previous code snippet; that would be a good place to put your SqlSessionFactory binding. There's no harm having multiple modules, and I find that it keeps the various concerns nicely separated.
QU: How I instantiate the injector so then I can use it in other action handlers properly?
For the server-side, see the MyContextListener code snippet above.
On the client side, you'll need a custom injector interface something like this:
#GinModules(StandardDispatchModule.class, MyClientModule.class)
public interface MyGinjector extends Ginjector {
MyWidgetMainPanel getMainPanel();
}
...and you can bind your MVP stuff in a custom Gin module as follows. I'm sorry that I'm not familiar with mvp4g, but I assume that you'll need to wire the views and presenters together in the module class.
public class MyClientModule extends AbstractGinModule {
#Override protected void configure() {
bind(...).to(...);
...
}
}