Injection of HttpServletRequest in GWTP ActionHandler using Spring - spring

I have implemented my GWT application using Spring + GWTP.
I want to access HttpServletRequest object into my ActionHandler class.
The ServerModule is Spring Configuration class (using #Configuration Annotation).
Now problem is how can I inject the current HttpServletRequest, ServletContext, ServletConfig in my ActionHandler using Spring.
Following is the definition of ServerModule:
#Configuration
#Import(DefaultModule.class)
public class ServerModule extends HandlerModule
{
#Bean
public UserVerficationActionHandler getUserVerificationActionActionHandler()
{
return new UserVerficationActionHandler();
}
}
In above Example I just want to inject the HttpServletRequest using Spring.
Any guidance on this highly appreciated.
Thanks.

The RequestProvider is your solution. It's a class in gwt-dispatch-server jar.
DefaultModule provides the RequestProvider bean so that you can just inject it into places you need it.
Take a look at the sourcec code for com.gwtplatform.dispatch.server.spring.configuration.DefaultModule which creates the RequestProvider as a DefaultRequestProvider which then defers to RequestContextHolder to do the work.
See the link for what you need to add to your web.xml to get this to work.

Related

Spring Boot 2.1.4: #Autowired does not work in custom Jackson Serializers/Deserializers, how to enable it?

I am struggeling to get a Spring Component #Autowired into my custom Deserializer.
Example:
#JsonDeserialize (using = SomeClassJsonDeserializer.class)
SomeClass {
[...]
}
#JsonComponent
SomeClassJsonDeserializer extends JsonDeserializer<SomeClass> {
#Autowired
private SomeService service;
#Override
public SomeClass deserialize(JsonParser jsonParser,
DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
[...]
// this.service is null
}
}
I found mainly two possible solutions which didn't work for me at all:
use SpringBeanAutowiringSupport in default constructor of Deserializer
use HandlerInstantiator (via config / custom implementation)
I am using only those Jackson annotations shown in the example above to 'configure' the Jackson parsing.
There is no additional custom configuration affecting Jackson in any way besides the default SpringBoot auto configuration. When using #EnableWebMvc (which breaks Spring-Boot auto configuration so I don't want to use it), the Component-wiring does work as expected.
Is there any official / recommended solution for plain Spring-Boot with default auto configuration ?
The problem was with how I used Spring's RestTemplate.
For a remote call, I created a new Instance of RestTemplate by contructor call (new RestTemplate()).
This way, Spring wasn't able to configure the RestTemplate - bean correctly (so that SpringBoot autoconfigure and Jackson autoconfigure 'connect' together, resulting in working Spring-DI in custom Jackson components).
I simply had to #Autowire the RestTemplateBuilder bean instance provided by Spring, and then call RestTemplateBuilder.build() to aqquire a RestTemplate bean instance created by Spring.

How to Inject custom method argument in Spring WebFlux using HandlerMethodArgumentResolver?

I want to create an custom method argument Resolver using Spring WebFlux. I am following link but its seem to be not working.
I am able to create the custom argument resolver using WebMvc.
import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver;
public class MyContextArgumentResolver implements HandlerMethodArgumentResolver {
#Override
public boolean supportsParameter(MethodParameter parameter) {
return MyCustomeObject.class.isAssignableFrom(parameter.getParameterType())
}
#Override
public Mono<Object> resolveArgument(MethodParameter parameter, BindingContext bindingContext,
ServerWebExchange exchange) {
.....
return Mono.just(new MyCustomeObject())
}
Please note that i am using HandlerMethodArgumentResolver from .web.reactive. package.
My AutoConfiguration file look like
#Configuration
#ConditionalOnClass(EnableWebFlux.class) // checks that WebFlux is on the class-path
#ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)//checks that the app is a reactive web-app
public class RandomWebFluxConfig implements WebFluxConfigurer {
#Override
public void configureArgumentResolvers(ArgumentResolverConfigurer configurer) {
MyContextArgumentResolver[] myContextArgumentResolverArray = {contextArgumentResolver()};
configurer.addCustomResolver(myContextArgumentResolverArray );
}
#Bean
public MyContextArgumentResolver contextArgumentResolver() {
return new MyContextArgumentResolver ();
}
My spring.factories looks like
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.XXXX.XXX.XXX.RandomWebFluxConfig
Please note that above configuration is part of the jar which is added in Spring WebFlux Boot project enabled using #EnableWebFlux .
It seems you're conflating two different problems here.
First, you should make sure that your method argument resolver works in a regular project.
For that, you need a #Configuration class that implements the relevant method in WebFluxConfigurer. Your code snippet is doing that but with two flaws:
Your configuration is using #EnableWebFlux, which is disabling the WebFlux auto-configuration in Spring Boot. You should remove that
it seems you're trying to cast a list of MethodArgumentResolver into a single instance and that's probably why things aren't working here. I believe your code snippet could be just:
configurer.addCustomResolver(contextArgumentResolver());
Now the second part of this question is about setting this up as a Spring Boot auto-configuration. I guess that you'd like WebFlux applications to automatically get that custom argument resolvers if they depend on your library.
If you want to achieve that, you should first make sure to read up a bit about auto-configurations in the reference documentation. After that, you'll realize that your configuration class is not really an auto-configuration since it will be applied in all cases.
You should probably add a few conditions on that configuration like:
#ConditionalOnClass(EnableWebFlux.class) // checks that WebFlux is on the classpath
#ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) // checks that the app is a reactive web app

Java bean validation on Spring MVC Controller PathVariables

I am trying to get Java Bean validation annotations to work with path variables and query parameters in Spring MVC controller. (Environment: Spring Boot v1.3.5, Springxxx 4.2.6, programming language Kotlin 1.0.3)
e.g.
#RequestMapping(value = "/{someId}" ...)
fun getSomething(**#SomeValidId** #PathVariable("someId") someId: String):...
I have added org.springframework.validation.beanvalidation.MethodValidationPostProcessor as described in https://raymondhlee.wordpress.com/2015/08/29/validating-spring-mvc-request-mapping-method-parameters/ and also added org.springframework.validation.beanvalidation.LocalValidatorFactoryBean as the validatorFactory to the above.
#Configuration
...class .... {
...
#Bean
open fun localValidatorFactoryBean() = LocalValidatorFactoryBean()
#Bean
open fun methodValidationPostProcessor() : MethodValidationPostProcessor {
val methodValidationPostProcessor = MethodValidationPostProcessor()
methodValidationPostProcessor.setValidator(localValidatorFactoryBean())
return methodValidationPostProcessor
}
}
But when I annotate the Controller class (or the interface it implements) with
org.springframework.validation.annotation.Validated as suggested looks like the controller class is proxied (which seems to be as expected - https://github.com/spring-projects/spring-security/issues/3215).
#Validated
interface SomeResource {
....
#RestController
#RequestMapping("/somepath")
class SomeController ......: SomeResource ....
But this causes the Spring mvc request mapping setup to ignore the SomeController. Debugging through the Spring framework code looked like org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.initHandlerMethods() goes through the list of beans and tries to detect handler methods but the above controller is ignored by the looks of it as it encounters a proxy instance and it doesn't carry the #Controller or #RequestMapping annotations.
Does anyone have any idea what's missing? There seems to be a lot of information out there that seem to suggest this should be possible, but couldn't find a working example .
Well I found the issue - it was because the proxy created for the controller was a JDK Dynamic proxy. When I forced it to be a CGLIB proxy it started working alright.
By default Kotlin classes are final and therefore forced to use JDK Dynamic proxies, but marking the controller as 'open' was not sufficient to coerce it to use CGLIB. Had to add #Scope(proxyMode = ScopedProxyMode.TARGET_CLASS) to the controller class
#RestController
#RequestMapping("/somepath")
#Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
class SomeController ......: SomeResource ....

how to use #Service annotation in Spring MVC to create the bean of Service layer

Can someone tell how to get the bean of service layer in spring MVC. One way to get the bean of service layer is by using #Service annotation but how to do that, I don't know.
Controller:
#Controller
public class ConfigureApplicationController {
#RequestMapping(value="/ConfigureApplication.html", method=RequestMethod.GET)
public ModelAndView getListOfAllConfigureApplication(){
AppConfigureServiceImpl getService=new AppConfigureServiceImpl();
ArrayList<ConfigureApplication> results =getService.getListOfAllAppConfigure();
ModelAndView model=new ModelAndView("ConfigureApplication");
model.addObject("results",results);
return model;
}
and serviceImpl is:
#Service("appConfigureServiceImpl")
public class AppConfigureServiceImpl implements AppConfigureService {
public ArrayList<ConfigureApplication> getListOfAllAppConfigure(){
#SuppressWarnings("resource")
ApplicationContext ctx=new ClassPathXmlApplicationContext("spring-dispatcher-servlet.xml");
AppConfigureDAOImpl getAll=ctx.getBean("appConfigureDAOImpl", AppConfigureDAOImpl.class);
ArrayList<ConfigureApplication> results =getAll.getList();
return results;
}
In this i have made the object of AppConfigureServiceImpl (in service layer)then i invoke the method but by doing so i am not using dependency injection in spring. I know i can do this using #Service annotation but i don';t know the syntax. can someone help me to solve this problem.
put a plain #Service annotation over your AppConfigureServiceImpl (you don't have to specify the "appConfigureServiceImpl" like you did).
Then have the service instance injected automatically in your controller by adding the following inside ConfigureApplicationController class:
#Autowired
AppConfigureService appConfigureService;
Now you can just call it like this: appConfigureService.getListOfAllAppConfigure();
Note that for the injection to happen, you need to make sure that you have set componentScan property in your configuration file to scan the packages that contain the classes to be injected. In your case, the package that contains AppConfigureServiceImpl.
<context:component-scan base-package="com.my.servicepackage" />
Note also that you should do the same with your dao instead of creating a new application context and getting it from the there. I.e. add a
#Autowired
AppConfigureDAO appConfigureDAO;
property inside your AppConfigureServiceImpl and use that.

In a Spring example, how is a Validator object generated?

I am studying a spring exmaple. And I found the following code. I can't understand the construct function. A validator interface is passed to this function. How is this validator generated? Thanks in advance.
#Controller
#RequestMapping(value="/account")
public class AccountController {
private Map<Long, Account> accounts = new ConcurrentHashMap<Long, Account>();
private Validator validator;
#Autowired
public AccountController(Validator validator) {
this.validator = validator;
}
#RequestMapping(method=RequestMethod.POST)
public #ResponseBody Map<String, ? extends Object> create(#RequestBody Account account, HttpServletResponse response) {
Set<ConstraintViolation<Account>> failures = validator.validate(account);
if (!failures.isEmpty()) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return validationMessages(failures);
} else {
accounts.put(account.assignId(), account);
return Collections.singletonMap("id", account.getId());
}
}
The validator can be any class that implements Springs Validator interface and is available in the current application context. By default Spring autowires by type. This means that every bean which implements the Validator interface can satisfy the constructor of AccountController. I don't know the exact example but there might be something like an AccountValidator bean available int the application context.
Be aware that this approach could cause problem if multiple validator beans are available in the application context.
See the Validation section in the spring documentation for details on the Validator interface.
When You use Autowired on constructor Spring looks for Validator implementation/
In this example Spring injects its default Validator implementation:
org.springframework.validation.beanvalidation.LocalValidatorFactoryBean
Here's more:
section: 5.7.2.1 Injecting a Validator
http://docs.spring.io/spring/docs/3.0.0.RC3/reference/html/ch05s07.html
There must be some concrete implementation of Validator.Without that it is not possible.
Further to support my answer see that it is being #Autowired.
Please post the link from which you are studying or check the source code for the presence of validaor class.
Also,check this link There is no concrete implementation by default.

Resources