I a'm developing web application for websphere 7.0. It's XML based spring 3.1 application. In my application I use many configuration properties files. But in production we don't have access to file system on websphere server, so we don't have access to spring or properties files or web.xml. Therefore we need override properties from configuration files in websphere administration console. But also we need programmatic access to resolved values of some properties overrided by administrator.
I've found that context:property-placeholder resolve both context parmeters and entry-env from web.xml and override properties from file as it should be in my application, but I don't know how to get properties programatically from context:property-placeholder(it's new PropertySourcesPlaceholderConfigurer).
And in my case I could not get util:properties to be overrided by context parameters or entry-env values. As and PropertyPlaceholderConfigurer.
Also I can't edit Context parameters from websphere administration console. I didn't find this functionality and google doesn't give answers. In console I can edit only servlet initialization parameters or entry-env values.
My situation:
web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/webappconf.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>springServlet</servlet-name>
<servlet-class>org.springframework.web.context.support.HttpRequestHandlerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springServlet</servlet-name>
<url-pattern>/springServlet</url-pattern>
</servlet-mapping>
<env-entry>
<env-entry-name>AA.AA</env-entry-name>
<env-entry-type>java.lang.String</env-entry-type>
<env-entry-value>Override AA.AA</env-entry-value>
</env-entry>
webappconf.xml
any properties resolver definition
<bean id="springService" class="ru.test.krp.SpringService">
<property name="a" value="${AA.AA}" />
<property name="b" value="${BB.BB}" />
<property name="c" value="${CC.CC}" />
<property name="config" ref="any refrence to properties for access from code"/>
</bean>
<bean id="springServlet" class="ru.test.krp.SpringServlet">
<property name="springService" ref="springService"></property>
</bean>
SpringService.java
public class SpringService {
private String a;
private String b;
private String c;
private Properties config;
// getter/setter pairs
I will appreciate any help or ideas.
You can put your configuration properties files into shared libraries. Library shoud be attached to your application.
All that you need to it's only how to reread new configuration.
Related
I'm trying to modify a wicket application to store the session in redis via spring-session. The session is showing up in redis, but I've run into a problem that whenever the application makes a standard wicket ajax call, the response from wicket includes an Ajax-Location header that is interpreted by wicket-ajax-jquery.js triggering a page redirect. But this only happens AFTER the first ajax call has been successful. For example, the first ajax call may look like this:
http://host:port/context/help/admin?0-1.IBehaviorListener.0-smartTable-tableArea-records-0-row-detailToggleCell-detailToggleLink&_=1636756805561
and the response headers do NOT include Ajax-Location. And then later, the next ajax call may look like this:
http://host:port/context/help/admin?1-1.IBehaviorListener.0-smartTable-tableArea-records-0-row-detailToggleCell-detailToggleLink&_=1636756906417
But the response header now includes this:
Ajax-Location: ./admin?2
and instead of just doing the ajax update to the page, the entire page redirects to the URL specified in that header because of code in src/main/java/org/apache/wicket/ajax/res/js/wicket-ajax-jquery.js
Digging down into the wicket-core code using the debugger, consider this where it doesn't produce the Ajax-Location header and works properly:
Step completed: "thread=ba6f07:3", org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler.respond(), line=197 bci=169
ba6f07:3[1] print canCallListenerInterfaceAfterExpiry
canCallListenerInterfaceAfterExpiry = false
ba6f07:3[1] print freshPage
freshPage = false
ba6f07:3[1] print isStateless
isStateless = false
ba6f07:3[1] print component
component = "[AjaxLink [Component id = detailToggleLink]]"
and then compare with this where it DOES produce an Ajax-Location header and doesn't work properly:
Breakpoint hit: "thread=ba6f07:7", org.apache.wicket.core.request.handler.ListenerInterfaceRequestHandler.respond(), line=197 bci=169
ba6f07:7[1] print canCallListenerInterfaceAfterExpiry
canCallListenerInterfaceAfterExpiry = false
ba6f07:7[1] print freshPage
freshPage = true
ba6f07:7[1] print isStateless
isStateless = false
ba6f07:7[1] print component
component = null
The difference being that when it doesn't work, freshPage is true and component is null.
Note: this pattern is fully functional in another similar application that I have and I’ve spent some time comparing the two. Clearly, something is missing from the original application in the app that I’m working on but I haven’t been able to identify it yet.
My redis http session config class looks like this:
import javax.annotation.PostConstruct;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
import org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration;
import org.springframework.session.web.http.CookieHttpSessionStrategy;
import org.springframework.session.web.http.DefaultCookieSerializer;
#Configuration
#EnableRedisHttpSession
public class MyRedisHttpSessionConfig extends RedisHttpSessionConfiguration
{
private JedisConnectionFactory connectionFactory;
#PostConstruct
public void init()
{
CookieHttpSessionStrategy strategy = new CookieHttpSessionStrategy();
DefaultCookieSerializer cookieSerializer = new DefaultCookieSerializer();
cookieSerializer.setCookieName( "SESSION" );
strategy.setCookieSerializer(cookieSerializer);
setHttpSessionStrategy( strategy );
}
#Bean
public JedisConnectionFactory connectionFactory() throws Exception
{
return connectionFactory;
}
public void setConnectionFactory( JedisConnectionFactory connectionFactory )
{
this.connectionFactory = connectionFactory;
}
}
my web.xml has this:
...
<filter>
<filter-name>requestLoggingFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter>
<filter-name>springSessionRepositoryFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter>
<filter-name>myApplicationWicketFilter</filter-name>
<filter-class>org.apache.wicket.protocol.http.WicketFilter</filter-class>
<init-param>
<param-name>applicationFactoryClassName</param-name>
<param-value>org.apache.wicket.spring.SpringWebApplicationFactory</param-value>
</init-param>
<init-param>
<param-name>filterMappingUrlPattern</param-name>
<param-value>/*</param-value>
</init-param>
</filter>
...
<filter-mapping>
<filter-name>springSessionRepositoryFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
...
<filter-mapping>
<filter-name>ariesApplicationWicketFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
...
and my spring beans config file has this:
...
<!-- The RedisHttpSessionConfiguration creates an http Filter bean with name "springSessionRepositoryFilter" which is referenced in web.xml -->
<context:annotation-config/>
<util:constant static-field="org.springframework.session.data.redis.config.ConfigureRedisAction.NO_OP"/>
<bean class="MyRedisHttpSessionConfig">
<property name="connectionFactory" ref="webTierRedisConnectionFactory"/>
</bean>
<bean id="webTierRedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${service-tier:redisSentinelMasterName}"/>
<property name="port" value="${service-tier:redisSentinelHostPortCsv}"/>
<property name="usePool" value="true"/>
<property name="poolConfig">
<bean class="redis.clients.jedis.JedisPoolConfig">
<property name="maxWaitMillis" value="5000"/>
<property name="maxTotal" value="50"/>
<property name="maxIdle" value="5"/>
<property name="minIdle" value="1"/>
<property name="testWhileIdle" value="true"/>
<property name="timeBetweenEvictionRunsMillis" value="60000"/>
<property name="numTestsPerEvictionRun" value="10"/>
</bean>
</property>
</bean>
...
Ivy Dependencies include:
<!-- these are for redis httpsession -->
<dependency org="redis.clients" name="jedis" rev="2.8.1"/>
<dependency org="org.springframework.data" name="spring-data-redis" rev="1.7.4.RELEASE"/>
<dependency org="org.springframework.data" name="spring-data-keyvalue" rev="1.1.4.RELEASE"/>
<dependency org="org.springframework.session" name="spring-session" rev="1.2.2.RELEASE"/>
and wicket 7.5.0 and spring 4.2.8 stuff.
Anybody have any insights on what might be going on? Why after putting the session into redis (which it is showing up there, I see it (via redis-cli and keys and dump commands), most ajax calls are triggering full page redirects due to response headers from the ajax call including Ajax-Location?
This turned out to be caused by a custom org.apache.wicket.IPageManagerProvider implementation which needed to be replaced with a version that was compatible with redis.
Using PropertyPlaceholderConfigurer to externalize spring-configuration
properties.
Added following code to spring-servlet.xml
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:environment.properties</value>
</property>
</bean>
Filter to be externalized from spring-security.xml
<security:custom-filter position="AUTH_FILTER" ref="${filter}" />
filter value is present in environment.properties
environment.properties file is present inside Jboss modules and is readable from code using resource bundle.
But, with these changes somehow properties file is not getting loaded and following error is thrown while publishing code.
Caused by: java.lang.IllegalArgumentException: Could not resolve
placeholder 'filter' in string value "${filter}"
PS:
Also tried hardcoding path as <value>file:${jboss.home.dir}/modules/system/layers/base/configuration/main/environment.properties</value> but, dosen't seems to be working.
I think your problem is that your spring-servlet.xml is not linked to your spring-security.xml. So spring-security.xml has no knowledged of the PropertyPlaceholderConfigurer.
IMO, you should configure PropertyPlaceholderConfigurer in a properties-context.xml (for instance) so you can import this new file into your spring-servlet.xml and spring-security.xml as following:
<import resource="classpath:properties-context.xml" />
I'm trying to deploy a CAS web application on JBOSS 7. The package name is cas-server-webapp-3.4.11.war.
I'm facing the following error during install:
09:37:06,951 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/cas-server-webapp-3.4.11]] (MSC service thread 1-5)
Exception sending context initialized event to listener instance of class org.springframework.web.util.Log4jConfigListener: java.lang.IllegalArgumentException: Invalid 'log4jConfigLocation' parameter: class path resource [log4j.xml] cannot be resolved to absolute file path because it does not reside in the file system: vfs:/D:/Programming/jboss7/bin/content/cas-server-webapp-3.4.11.war/WEB-INF/classes/log4j.xml
Deployment package is located in D:\Programming\jboss7\standalone\deployments\cas-server-webapp-3.4.11.war, but obviously JBOSS tries to resolve paths to D:/Programming/jboss7/bin/content/cas-server-webapp-3.4.11.war.
How I can change this path?
For CAS 1.5 log4j configuration is defined in WEB-INF/cas.properties file where you define the location.
I used this configuration:
log4j.config.location=${jboss.server.base.dir}/deployments/cas-server-webapp.war/WEB-INF/classes/log4j.xml
However, when application server doesn't unpack war during deployment it doesn't work anyway because this file is not on filesystem. So the easiest way is to disable initialization of this bean at all by deleting src/main/webapp/WEB-INF/spring-configuration/log4jConfiguration.xml file.
Also this issue is relevant to this topic.
Solution is the following:
In persistence.xml put the following content:
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="CasPersistence" transaction-type="RESOURCE_LOCAL">
<class>org.jasig.cas.services.RegisteredServiceImpl</class>
<class>org.jasig.cas.ticket.TicketGrantingTicketImpl</class>
<class>org.jasig.cas.ticket.ServiceTicketImpl</class>
<class>org.jasig.cas.ticket.registry.support.JpaLockingStrategy$Lock</class>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
</properties>
</persistence-unit>
In web.xml instead of:
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.xml</param-value>
</context-param>
put
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>WEB-INF\classes\log4j.xml</param-value>
</context-param>
Hope this will help & save time to others.
I have a RESTful service that has a single path parameter and a parameter that is unmarshalled from the request body. The request body parameter is XML for which I have an XSD. I've been trying to validate the XML payload against the XSD but to no avail. I've tried the following, as described here:
<jaxrs:server address="/"
serviceClass="my.endpoint.class">
<jaxrs:schemaLocations>
<jaxrs:schemaLocation>classpath:schema/myschema.xsd</jaxrs:schemaLocation>
</jaxrs:schemaLocations>
</jaxrs:server>
The schemas are being found (there are no errors at least) but what I expect to be an invalid payload is not throwing an exception. Parameters that don't match the XSD contents are coming through as null. It may not be relevant but my auto-generated payload class has three attributes, some of which are required.
I've had a brief go at creating a MessageBodyReader, as described here but I think I'm having scope issues and my schema object is not available when readFrom is called.
Any help or suggestions would be gratefully appreciated!
Turns out the servlet I was using wasn't accepting the jaxrs configuration shown above. I changed from using this:
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
to this:
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<init-param>
<param-name>config-location</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</init-param>
Snippet of my applicationContext.xml
<jaxrs:server address="/">
<jaxrs:schemaLocations>
<jaxrs:schemaLocation>classpath:schema/myschema1.xsd</jaxrs:schemaLocation>
<jaxrs:schemaLocation>schema/myschema2.xsd</jaxrs:schemaLocation>
<jaxrs:schemaLocation>schema/myschema3.xsd</jaxrs:schemaLocation>
</jaxrs:schemaLocations>
<jaxrs:serviceBeans>
<bean class="my.package.endPoint1" />
<bean class="my.package.endPoint2" />
</jaxrs:serviceBeans>
<jaxrs:features>
<cxf:logging />
</jaxrs:features>
</jaxrs:server>
Schema references are from the resources directory, adjacent to WEB-INF.
I'd like to introduce Spring MVC to an application that has up till now used simple direct access to JSP files i.e www.example.com/login.jsp which contains the business logic and presentation details.
I'd like to strip out the business logic and keep only the presentation in the JSP. To do this, I've moved the jsp file from webapp/login.jsp to webapp/WEB-INF/jsp/login.jsp and then mapped all urls with the pattern *.jsp to Spring's DispatchServlet which goes to a Controller and then a view which (should) forward to /WEB-INF/jsp/login.jsp.
The web.xml looks like this:
<servlet>
<servlet-name>springapp</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>*.jsp</url-pattern>
</servlet-mapping>
springapp-context.xml
<bean id="urlFilenameViewController" class="org.springframework.web.servlet.mvc.UrlFilenameViewController"/>
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<value>
/*.jsp=urlFilenameViewController
</value>
</property>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"></property>
</bean>
However, the fundamental problem with this is that I'm mapping external URL requests ending in .jsp to internal web requests that also map to .jsp. The internal .jsp request then goes through the DispatchServlet for a second time which returns an error as it cannot find anything to handle the request:
WARN - DispatcherServlet.noHandlerFound(1077) | No mapping found for HTTP request with URI [/myapp/WEB-INF/jsp/login.jsp] in DispatcherServlet with name 'springapp'
Given that I cannot change the external URLs, is there a way to get round this issue when mapping external file types to the same internal file type?
We address this in our application by using a different pattern for request URLs (*.htm instead of *.jsp). This avoids the problem and it is good practice anyway because there may not be a 1-to-1 relationship between a URL and a JSP.
I suggest you:
map Spring MVC requests to a different pattern ( e.g *.do);
use a UrlRewriteFilter or your application server's url rewrite functionality to map *.jsp calls to *.do;
I'm not sure how to tell Spring to ignore its internal requests for JSP files, but intercept other JSP requests. Why don't you keep your old jsps, but just have them forward to a controller. E.g. "page.jsp":
<%# taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<c:redirect url="/page.htm" />
This way, you can keep your old URLs intact, but the only function is to redirect to the controllers.