I have my servlet init parameter defined in the servlet
#WebServlet(
urlPatterns = {"/*"},
initParams = {#WebInitParam(name = "targetUri", value = "http://my host:10040")})
public class WebOption extends ProxyServlet {
I want to set this in the application.properties
Can an example and url to the docs be provided?
After inspection of the servlet I'm extending, I determined that I could override a method to set the init parameter
Related
I want to load Spring initial context inside a AWS lambda handler class. This class is the starting point of my application. I did it in the below way.
#SpringBootApplication
public class LambdaFunctionHandler implements RequestHandler<KinesisEvent, Object> {
#Override
public Object handleRequest(KinesisEvent input, Context context) {
AnnotationConfigApplicationContext appContext = new AnnotationConfigApplicationContext(LambdaFunctionHandler.class);
LambdaFunctionHandler lambdaHandlerBean = appContext.getBean(LambdaFunctionHandler.class);
// some business logic call
return null;
}
}
This is working fine but I'm getting warning on appContext that it should be closed as it is resource leak. this can be fixed by calling appContext.close() but my doubt is whether this way of initializing Spring application context in a non main method is correct ? Most recommended way to do in a main method is like below
SpringApplication app = new SpringApplication(LambdaFunctionHandler.class);
ConfigurableApplicationContext context = app.run(args);
LambdaFunctionHandler lambdaFunctionHandler =
context.getBean(LambdaFunctionHandler.class);
But I don't have the value to replace the args in my case. can anyone suggest the right way of doing this
You can simple class with main method for #SpringBootApplication and
use CommandLineRunner for loading AWS lambda handler. Just implement the run to load the bean
https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/CommandLineRunner.html
I'm creating a service that uses ImageWorkshop. In order to init a new image, I need to call:
$layer = ImageWorkshop::initFromPath(__DIR__.'/../path/to/myimage.jpg');
I'd like to inject ImageWorkshop as a dependency, but I can't figure out how to do this since it uses static methods. I know I could just call ImageWorkshop statically from my service, but I'm trying to declare my dependencies.
That's the perfect use case for service factories.
You declare your $layer as a service and create it with the static factory method in the service container.
services:
myimage_layer:
class: PHPImageWorkshop\Core\ImageWorkshopLayer
factory_class: PHPImageWorkshop\ImageWorkshop
factory_method: initFromPath
arguments:
- "%kernel.root_dir%/../path/to/myimage.jpg"
Now you can inject the myimage_layer service into your service as a service argument.
EDIT: If you need the ImageWorkshop directly to call them, but don't want to write ImageWorkshop::initFromPath('...') directly in your code, you can decouple it with the class name. It's not really useful, because ImageWorkshop is not directly replaceable, but it helps for mocking in tests.
services:
myimage_whatever:
class: Acme\Bundle\AcmeBundle\Image\Whatever
arguments:
- "PHPImageWorkshop\\ImageWorkshop"
Your service:
namespace Acme\Bundle\AcmeBundle\Image;
class Whatever
{
private $imageWorkshop;
public function __construct($imageWorkshop)
{
$this->imageWorkshop = $imageWorkshop;
}
public function doWhatever($path)
{
$layer = $this->imageWorkshop::initFromPath($path);
// ...
}
}
Beware yourself, $imageWorkshop is no instance. Instead it's a string containing the fully qualified class name of ImageWorkshop to call the static method on it. I hope this should work.
Reference for calling a static method on a string variable containing the class name: http://php.net/manual/en/language.oop5.static.php#example-214
I would create a wrapper class and implement the static class methods in it
e.g
Class ImageWorkshopWrapper
{
public function initFromPath($path)
{
ImageWorkshop::initFromPath($path);
}
}
and inject ImageWorkshopWrapper class
I'm attempting to use Unity to inject a dependency per this article:
http://www.asp.net/web-api/overview/extensibility/using-the-web-api-dependency-resolver
Here is what I have in my global.asax
void ConfigureApi(HttpConfiguration config)
{
var unity = new UnityContainer();
unity.RegisterType<CustomerController>();
unity.RegisterType<TPS.Data.Can.IUnitOfWork, TPS.Data.Can.EFRepository.UnitOfWork>(new HierarchicalLifetimeManager());
config.DependencyResolver = new IoCContainer(unity);
}
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
ConfigureApi(GlobalConfiguration.Configuration);
}
Here is my API controller:
public class CustomerController : ApiController
{
private TPS.Data.Can.IRepository<tblCustomer> _repo;
private TPS.Data.Can.IUnitOfWork _uow;
public CustomerController() { }
public CustomerController(TPS.Data.Can.IUnitOfWork uow) {
_uow = uow;
_repo = uow.CustomerRepository;
}
// GET api/customer/5
public IEnumerable<Customer> Get()
{
string identity = HttpContext.Current.User.Identity.Name;
//REFACTOR THIS
if (String.IsNullOrWhiteSpace(identity))
identity = "chardie";
var customers = from c in _repo.Get()
where c.SalesRep == identity
select new Customer
{
IDCUST = null,
CustCode = c.CustCode,
CustName = c.CustName
};
return customers.ToList();
}
This works when I first start debugging my application. If I set a breakpoint in the parameterized constructor, the breakpoint will be hit when I hit the Web API for the first time. When I hit refresh in my browser, the constructor does not get called, the dependency doesn't get injected, and the Get() action throws an exception because the expected repository is null.
Can anyone tell me why my constructor isn't being called after the first request?
Thanks!
Chris
EDIT
FWIW, I removed the parameterless constructor entirely from the Web API controller, and on my second request to it, I get the exception:
Type 'TPS.Website.Api.CustomerController' does not have a default constructor
So it appears I'm getting my repo dependency injected on the first request, but after that every instantiation of the Web API controller is done through the parameterless constructor.
You're not specifying a lifecycle for the controller. MSDN states
If you do not specify a value for the lifetime, the instance will have
the default container-controlled lifetime. It will return a reference
to the original object on each call to Resolve.
If the IUnitOfWork dependency is transient, then the controller should be transient too. So try
unity.RegisterType<CustomerController>(new TransientLifetimeManager());
This might not solve the whole problem but it sounds like part of it. You certainly shouldn't need the parameterless constructor.
I had this as I was returning my resolver for my dependency scope using this and then disposing the container in the dispose. So after the first request the container was disposed.
Looks like it's because you're not using singleton pattern for the Unity Container.
Have a private static variable instead of the var container = new UnityContainer();
internal static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() => new UnityContainer());
Then access within code using the .Value property.
I have this inside my spring xml file:
<object type="Test.Web.Utilities.TestClass, Test.Web" singleton="false" id="TestClass">
<property name="TestService" ref="TestService"/>
</object>
In the TestClass I have this:
public ITestService TestService { get; set; }
and this:
public void TestMethod()
{
var x = TestService.ExampleMethod();
}
next, inside my controller I have this:
TestClass t = new TestClass();
t.TestMethod();
However, I don't seem to get this to work. other spring related stuff on the controller works well.
Any ideas how can I get this to work?
EDIT: Forgot to add, the error I get is a NullReferenceException
This cannot work since you're creating TestClass instance via new and Spring is of course not aware to inject dependencies into objects created via the frameworks new. You'll not find a .NET IOC framework that can do this (for good reasons!).
So what you need to do is to inject instances of TestClass into your controller. You could register these instances with a request or prototype scope.
You cannot use the normal "new" keyword, because this is handled via the .NET VM. You actually need to call Spring's Activator Context to give you an instance.
First you acquire the Spring.NET Activator context by calling:
IApplicationContext ctx = ContextRegistry.GetContext();
Then you can get an instance of your class specified in your configuration xml:
ITestService svc = (ITestService)ctx.GetObject("TestClass");
This enables you to configure via your XML file what concrete implementation class that implements the ITestService interface.
In my application based on spring mvc and spring security I am using #Controller annotation to configure controller.
I have configured Spring Handler Interceptor and in preHandle() method , I want to get method name which is going to be call by interceptor.
I want to get custom annotation defined on controller method in preHandle() method of HandlerInterceptor so that I can manage by logging activity for that particular method.
Please have a look at my application requirement and code
#Controller
public class ConsoleUserManagementController{
#RequestMapping(value = CONSOLE_NAMESPACE + "/account/changePassword.do", method = RequestMethod.GET)
#doLog(true)
public ModelAndView showChangePasswordPage() {
String returnView = USERMANAGEMENT_NAMESPACE + "/account/ChangePassword";
ModelAndView mavChangePassword = new ModelAndView(returnView);
LogUtils.logInfo("Getting Change Password service prerequisit attributes");
mavChangePassword.getModelMap().put("passwordModel", new PasswordModel());
return mavChangePassword;
}
}
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
// here I want the controller method name(i.e showChangePasswordPage()
// for /account/changePassword.do url ) to be called and that method annotation
// (i.e doLog() ) so that by viewing annotation , I can manage whether for that
// particular controller method, whether to enable logging or not.
}
I am using SPRING 3.0 in my application
Don't know about the Handler interceptor, but you could try to use Aspects and create a general interceptor for all your controller methods.
Using aspects, it would be easy to access your joinpoint method name.
You can inject the request object inside your aspect or use:
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
To retrieve it from your advice method.
For instance:
#Around("execution (* com.yourpackages.controllers.*.*(..)) && #annotation(org.springframework.web.bind.annotation.RequestMapping)")
public Object doSomething(ProceedingJoinPoint pjp){
pjp.getSignature().getDeclaringType().getName();
}