Displaying images in jasper html reports with spring - spring

I am working on Spring, JasperReports. My Spring version is 3.0.5 RELEASE, iReport-4.5.0.
I am using http://chathurangat.blogspot.in/2012/02/jasperreport-with-spring-mvc-fully.html link as sample to generate the reports. For this every thing is working fine. But when i am exporting the report to html i am not able to get the images. For this I have configured imageservlet in my web.xml and IMAGES_URI, IMAGES_DIR_NAME, IS_OUTPUT_IMAGES_TO_DIR, IS_USING_IMAGES_TO_ALIGN parameters in jasper-views.xml file.
Below is the configuration of my code in jasper-views.xml, web.xml.
Using this configurations if i run the report i am getting the 500 Error as no jasperprint document found on the httpsession.
If i configure the DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE attribute then I've get the image. But i am not getting how to configure this in jasper-views.xml file. This attribute is expecting the JasperPrint object but i am not creating any JasperPrint object.
Can any one help me regarding this. I am struggling a lot for this. If you want any more information i vl give you.
This is my jasper-views.xml configuration:
<util:map id="exportParameterMap">
<entry key="net.sf.jasperreports.engine.export.JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN">
<value>false</value>
</entry>
<entry key="net.sf.jasperreports.engine.export.JRHtmlExporterParameter.IS_OUTPUT_IMAGES_TO_DIR">
<value>true</value>
</entry>
<entry key="net.sf.jasperreports.engine.export.JRHtmlExporterParameter.IMAGES_URI">
<value>images?image=</value>
</entry>
<entry key="net.sf.jasperreports.engine.export.JRHtmlExporterParameter.IMAGES_DIR_NAME">
<value>/home/rupa/Workspace/sample/src/main/webapp/images/rupa</value>
</entry>
</util:map>
<bean id="ipHtmlReport"
class="org.springframework.web.servlet.view.jasperreports.JasperReportsHtmlView"
p:url="classpath:reports/ggsnreport.jrxml"
p:reportDataKey="datasource"
p:exporterParameters-ref="exportParameterMap">
</bean>
This is my web.xml configuration:
<servlet>
<servlet-name>image</servlet-name>
<servlet-class>net.sf.jasperreports.j2ee.servlets.ImageServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>image</servlet-name>
<url-pattern>/images</url-pattern>
</servlet-mapping>

I haven't done it with a pure Spring approach. I have part of the site with Spring, but the reports are generated using traditional Servlets.
If it is helpful to you, you can see this answer I wrote for a similar question.

Related

Spring Session changed the cookie value causing HTTP 302 on succeeding requests

Migrating from servlet container HTTP session to spring session has caused HTTP 302 after successful login. I've got an HTTP 200 on first request after login, but succeeding requests seem redirected to login page again. Cannot debug on succeeding requests as it seems not able to reach through the servlet where I put some breakpoint.
Right now, we are using spring session 1.3.5 version. And have noticed that in spring's SessionRepositoryFilter, it replaced the original request cookies (e.g. servlet container) to the value from spring session. I am not sure if this is the root cause of the issue. If it is, can someone suggest how to resolve it? Or is it related to some sort of missing configuration?
Here's the current setup based on the guide from spring session: here
Spring session XML configuration:
<context:annotation-config/>
<bean class="org.springframework.session.hazelcast.config.annotation.web.http.HazelcastHttpSessionConfiguration"/>
<bean id="hazelcastInstance" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod" value="com.xxx.xxx.xxx.xxx.CustomHazelcastProvider.getInstance"/>
</bean>
<bean class="org.springframework.session.web.http.DefaultCookieSerializer">
<property name="cookieName" value="JSESSIONID"/>
<property name="cookiePath" value="/"/>
<property name="domainNamePattern" value="^.+?\.(\w+\.[a-z]+)$"/>
</bean>
Reference of spring XML configuration in web.xml:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:application-context.xml</param-value>
</context-param>
Registration of spring session repository filter in web.xml. As describe in the guide, I placed it as the first entry of the filter chain.
<filter>
<filter-name>springSessionRepositoryFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSessionRepositoryFilter</filter-name>
<url-pattern>/rs/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>ERROR</dispatcher>
</filter-mapping>
I have been working on it for days now and don't know yet how to fix it. Will appreciate any help or suggestion that you can advise.
Thank you in advance.
I resolved the issue using spring session HeaderHttpSessionStrategy.
Steps I've made:
In my spring session XML configuration, I removed the entry related to cookie serializer to change the cookie name.
<bean class="org.springframework.session.web.http.DefaultCookieSerializer">
<property name="cookieName" value="JSESSIONID"/>
<property name="cookiePath" value="/"/>
<property name="domainNamePattern" value="^.+?\.(\w+\.[a-z]+)$"/>
</bean>
By default, spring session uses CookieHttpSessionStrategy. Added below entry in spring session XML configuration.
<bean id="httpSessionStrategy" class="org.springframework.session.web.http.HeaderHttpSessionStrategy"/>
Then on every request, I am passing x-auth-token in the http request header.
After the said change, the application works as expected. Able to login without an issue.
Hope this solution will help others who have encountered the same issue.

the attributes 'j_username' and 'j_password' were shown as a plain text under Form Data in the request header

I am facing one of a security issue that Chrome dev tools were showing these attributes 'j_username' and 'j_password' as a plain text under Form Data in the request header.
It is an old application, in which we are using acegi-security 0.8.2 with Spring framework.
Workaround in our project: 1. in web.xml, we have mentioned the filter ChannelProcessingFilter as a separate filter,
<filter>
<filter-name>Acegi Filter Chain Proxy</filter-name>
<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>net.sf.acegisecurity.util.FilterChainProxy
</param-value>
</init-param>
</filter>
<filter>
<filter-name>Acegi Channel Processing Filter</filter-name>
<filter-class>net.sf.acegisecurity.util.FilterToBeanProxy</filter-class>
<init-param>
<param-name>targetClass</param-name>
<param-value>
net.sf.acegisecurity.securechannel.ChannelProcessingFilter</param-value>
</init-param>
</filter>
2..In applicationContext.xml, we have defined the ChannelProcessingFilter,
<bean id="channelProcessingFilter" class="net.sf.acegisecurity.securechannel.ChannelProcessingFilter">
<property name="channelDecisionManager"><ref bean="channelDecisionManager"/></property>
<property name="filterInvocationDefinitionSource">
<value>
CONVERT_URL_TO_LOWERCASE_BEFORE_COMPARISON
PATTERN_TYPE_APACHE_ANT
/login.htm*=REQUIRES_SECURE_CHANNEL
/j_acegi_security_check*=REQUIRES_SECURE_CHANNEL
/admin/**=REQUIRES_SECURE_CHANNEL
/**=REQUIRES_INSECURE_CHANNEL
</value>
</property>
</bean>
<bean id="channelDecisionManager" class="net.sf.acegisecurity.securechannel.ChannelDecisionManagerImpl">
<property name="channelProcessors">
<list>
<ref bean="secureChannelProcessor"/>
<ref bean="insecureChannelProcessor"/>
</list>
</property>
</bean>
<bean id="secureChannelProcessor" class="net.sf.acegisecurity.securechannel.SecureChannelProcessor"/>
<bean id="insecureChannelProcessor" class="net.sf.acegisecurity.securechannel.InsecureChannelProcessor"/>
3.To only deliver the login page over HTTPS, we have enabled the SSL/TSL support by generating keystore and enabled the Connector port="8443" in conf/server.xml in the tomcat server
The problem here am facing is, on clicking the j_acegi_security_check request, in Chrome dev tools was showing these attributes 'j_username' and 'j_password' as a plain text under Form Data in the request header.
Am I missing anything here? Kindly help me on encrypt this password or disable this attribute as how it is implemented in the banking applications

How to load Spring AOP into web app?

I was trying to implement Spring AOP in web app. Unfortunately all the sample code I found on the Web are console app. I was running out of clue how could I do it in web app?
In web.xml file, I load the applicationContext.xml like this:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
In applicationContext.xml file, I have ProxyFactoryBean defined like this:
<bean id="theBo" class="my.package.TheBo">
...
</bean>
<bean id="theProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<list>
<value>my.package.ITheBo</value>
</list>
</property>
<property name="target" ref="theBo"/>
<property name="interceptorNames">
<list>
<value>loggingBeforeAdvice</value>
</list>
</property>
</bean>
My situation now is I don't know where is the best place to put this code:
ApplicationContext context = new ClassPathXmlApplicationContext("WEB-INF/applicationContext.xml");
theBo = (ITheBo) context.getBean("theProxy");
If this was a console app, I would rather put it in the main(), but how could I do it in web app?
You do not need the following piece of code to load the context:
ApplicationContext context = new ClassPathXmlApplicationContext("WEBINF/applicationContext.xml");
theBo = (ITheBo) context.getBean("theProxy");
You have to add the ContextLoaderListener to your web.xml file:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Now when your web application starts the contexts declared in the <context-param> contextConfigLocation are loaded. In your case '/WEB-INF/applicationContext.xml'.
If you need your context in a specific class you can implement the ApplicationContextAware interface to retrieve it.
For the rest, your webapp is now a basic spring application where you can wire your classes as you would normally do.
Thanks to #Dave Newton giving me the clue. In order for me to inject theProxy from the web, for my case, it was JSF, I have to put following code in faces-config.xml.
<application>
<variable-resolver>
org.springframework.web.jsf.DelegatingVariableResolver
</variable-resolver>
</application>
<managed-bean>
<managed-bean-name>theAction</managed-bean-name>
<managed-bean-class>org.huahsin68.theAction</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>theBo</property-name>
<value>#{theProxy}</value>
</managed-property>
</managed-bean>
And the put in the listener provided by #tom as well into web.xml.

How do I catch Spring errors when starting up a Tomcat webapp?

I have a webapp running in Tomcat which uses Spring for dependency injection. (It's a GWT application, but I don't think that makes much of a difference to the solution I'm looking for.)
My web.xml file is of the following format:
<web-app>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Servlets -->
<servlet>
<servlet-name>dispatch</servlet-name>
<servlet-class>com.example.my.gwt.dispatch.DispatchServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatch</servlet-name>
<url-pattern>/my_gwt/dispatch</url-pattern>
</servlet-mapping>
... more servlets ...
</web-app>
One of the things my Spring configuration does is to connect to a databse via Hibernate:
<bean id="datasource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${db.driver}" />
<property name="url"
value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</bean>
<bean id="databaseSessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="datasource" />
<property name="packagesToScan">
<array>
<value>com.example.my.gwt.model</value>
</array>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>
If the database is unavailable, this causes an org.h2.jdbc.JdbcSQLException to be thrown, so the Spring initialisation does not continue, so the rest of the webapp cannot be used. Navigating to the webapp's URL gives an HTTP 503 'Service Unavailable' error.
What I want to do is to catch that error and display a page to the user (when they first navigate to the app) explaining what the problem is likely to be and suggested fixes. How can I do this?
I have tried using a custom ContextLoaderListener class that delegates to the one in the XML above, but catches any exceptions. This allows me to catch the exception, but there is not much I can do - the web.xml is still pointing the user's request to a servlet that is not running after the Spring initialisation has failed. Is there any way that I can change the webapp config when I catch that exception, so that it doesn't try to load the servlets from the web.xml and perhaps changes the welcome file to point to a page about the error? Or is there any other way that I can make the webapp gracefully handle this exception?
Thanks
Basically you're asking if you can have a functioning web application after the web application fails to start up.
You could try configuring a 503 handler page and/or have a welcome page, not dependent on Spring, that checks for something in the application context that's set only on a good spin up. If it didn't spin up, the exception you've already captured could be placed into the app context.
Not sure if anything in the app, even web.xml-only resources, if Spring doesn't spin up, though.
You could add a Servlet Filter to your web app that would intercept all the requests to the Spring servlet and forward to your custom error page if the Spring initialization has failed.

Error while splitting application context file in spring

I am trying to split the ApplicationContext file in Spring.
For ex. the file is testproject-servlet.xml having all the entries. Now I want to split this single file into multiple files according to logical groups like :
group1-services.xml, group2-services.xml
I have created following entries in web.xml :
<servlet>
<servlet-name>testproject</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/group1-services.xml, /WEB-INF/group2-services.xml
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
I am using SimpleUrlHandlerMapping as:
<bean id="simpleUrlMapping"class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="order" value="0"/>
<property name="mappings">
<props>
<prop key="/register.htm">RegisterController</prop> <prop key="/payroll_services.htm">PayrollServicesController</prop>
</props>
</property>
</bean>
I also have the controller defined as :
<bean id="PayrollServicesController" class="com.triforce.b2bseek.businessservices.controller.PayrollServicesController">
<property name="facadeLookup" ref="FacadeLookup"/>
..
..
</property>
</bean>
The problem is that I have splitted the ApplicationContext file "testproject-servlet.xml" into two different files and I have kept the above entries in "group1-services.xml". Is it fine? I want to group things logically based on their use in seperate .xml files.
But I am getting the following error when I try to access a page inside the application :
org.springframework.web.servlet.DispatcherServlet noHandlerFound
WARNING: No mapping for [/TestProject/payroll_services.htm] in DispatcherServlet with name 'testproject'
Please tell me how to resolve it.
Thanks in Advance !
Replace this
/WEB-INF/group1-services.xml, /WEB-INF/group2-services.xml
with
/WEB-INF/group1-services.xml
/WEB-INF/group2-services.xm
Hope this will work...:)
I don't think its a problem with your contextConfigLocation as such
I think its more that the dispatcher needs to know where to send payroll_servives.htm to, and can't find an appropriate handler knowing what to do with this pattern.
See reference documentation
Did you really want *.htm files to be matched to the dispatcher servlet?
If you are using annotation-based controllers (#Controller), then you need to have a line similar to:
<context:component-scan base-package="org.springframework.samples.petclinic.web"/>
This installs an appropriate annotation-based handler, that searchs for classes/methods annotated like:
#Controller
public class PayrollController {
#RequestMapping("payroll_services.htm")
public ModelAndView payrollServices() {
....
}
}
Otherwise, if you are using more traditional handlers/controllers, you need to define this using XML. The reference documentation link earlier in this posting mentions two such handlers: SimpleUrlHandlerMapping or BeanNameUrlHandlerMapping
Perhaps if you updated your question with snippets of handler/controller XML, this may help?
Did you add the ContextLoaderListener to your web.xml? I don't see it:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
You need to include something like this in each of your files:
<context:component-scan base-package="com.example.dao" />
If it is missing from a file, it seems the annotated classes are not known in the context of that file.
You may want to revisit the documentation for details.
Either the handler mapping of your DispatcherServlet is incorrect or you're using the wrong url. If you fix the layout around your SimpleUrlHandlerMapping configuration I can tell you what to change.

Resources