ERROR: 'ContentNegotiatingViewResolver'of Spring 3.0.3 MVC Portlet+JSON - java

I want to make spring MVC 3.0.3 portlet using DispatcherPortlet class With JSON support. So, i added following configuration in the spring context file.
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
text/html
Without this, if i use the 'InternalResourceViewResolver' only then it runs fine and i am able to use the portlet. But with this bean defined, i got the following error on tomcat startup.
I googled around and find a link stating that this bean with JSON only works with servlets in the latest spring vesion. please check the link as well.
http://jira.springframework.org/browse/SPR-7344 (JSON issue for portlets...)
http://jira.springframework.org/browse/SPR-6932?page=com.atlassian.jira.plugin.system.issuetabpanels%3Aall-tabpanel#issue-tabs
Also please check the error pasted below. Help me...
thanks.
:ERROR:
java.lang.IllegalArgumentException: Object of class [org.springframework.web.portlet.context.PortletRequestAttributes] must be an instance of class org.springframework.web.context.request.ServletRequestAttributes
please check the log
Caused by: java.lang.IllegalArgumentException: Object of class [org.springframework.web.portlet.context.PortletRequestAttributes] must be an instance of class org.springframework.web.context.request.ServletRequestAttributes
at org.springframework.util.Assert.isInstanceOf(Assert.java:337)
at org.springframework.util.Assert.isInstanceOf(Assert.java:319)
at org.springframework.web.servlet.view.ContentNegotiatingViewResolver.resolveViewName(ContentNegotiatingViewResolver.java:363)
at org.springframework.web.portlet.DispatcherPortlet.resolveViewName(DispatcherPortlet.java:1110)
at org.springframework.web.portlet.DispatcherPortlet.render(DispatcherPortlet.java:1052)
at org.springframework.web.portlet.DispatcherPortlet.doRenderService(DispatcherPortlet.java:761)
at org.springframework.web.portlet.FrameworkPortlet.processRequest(FrameworkPortlet.java:522)

ContentNegotiatingViewResolver doesn't work with portlets, only servlets.
As a general rule, many servlet API classes in Spring have a portlet equivalent, e.g.
org.springframework.web.servlet.HandlerAdapter
org.springframework.web.portlet.HandlerAdapter
You have to make sure that you use the right one - the servlet and portlet APIs are completely incompatible.
However, since Spring 2.5, the portlet framework has been neglected (probably because it's very rarely used), and newer parts of the servlet MVC API have not been included in the portlet MVC API.
It would seem that if you want to do what you're trying to do, you're going to have to do a lot of it yourself. You might be able to copy some of the code from ContentNegotiatingViewResolver and related classes.

Check this out. It should work now
<!-- View Resolver -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/test/testJSp/" />
<property name="suffix" value=".jsp" />
<property name="order" value="2" />
</bean>

Related

IBM MQ and Spring Integration - security settings

I've got a Spring Integration flow which uses an inbound gateway to get messages from an IBM MQ queue:
<int-jms:inbound-gateway id="InputGateway"
request-destination="RequestQueue"
request-channel="RequestChannel"
reply-channel="ReplyChannel"
/>
However I'm not capable of assigning security settings. In particular, I need an username, password and userAuthenticationMQCSP = false (for reasons beyond the scope of this post, I won't get into details but my broker will throw a MQRC = 2009 otherwise).
I've followed the IBM guide to connect with jmsTemplate and works just fine. This uses the official Spring boot starter from IBM MQ which will kindly create a connection factory and will autoconfigure it with some defaults from application.properties:
ibm.mq.queueManager=myQMName
ibm.mq.channel=myChannel
ibm.mq.connName=myhostname(myPort)
ibm.mq.user=username
ibm.mq.password=*******
ibm.mq.userAuthenticationMQCSP=false
Now, back to the Spring Integration case. According to the int-jms:inbound-gateway spec, a connectionFactory will be injected to the gateway, by name (attribute: connection-factory) which is set up to be "jmsConnectionFactory" by default
By default, all of the JMS adapters that require a reference to the
ConnectionFactory automatically look for a bean named
jmsConnectionFactory. That is why you do not see a connection-factory
attribute in many of the examples. However, if your JMS
ConnectionFactory has a different bean name, you need to provide that
attribute.
I don't see any way to set up a predictable name for the connection factory that I can plug into the int-jms:inbound-gateway.
Now, taking a different approach, as per this example I've created my connectionFactory with an adecuate name:
<bean id="jmsConnectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
<property name="transportType" value="1"/>
<property name="queueManager" value="myQMName"/>
<property name="hostName" value="myhostname"/>
<property name="port" value="myPort" />
<property name="channel" value="myChannel"/>
</bean>
But now I need somewhere to put the credentials and the security parameters. Looking at the example above, it looks like I need to plug something like:
<bean id="secureJmsConnectionAdapter" class="**yourpackages.SecureJMSConnectionAdapter**">
<property name="targetConnectionFactory" ref="${jms.mq.connection.factory}" />
<property name="userName" value="${jms.username}"/>
<property name="pwdAlias" value="${jms.alias}"/>
</bean>
However it is unclear to me how to implement this SecureJMSConnectionAdapter.
Additionally, if I set up my own connection factory, I will lose all of MQ boot starter automagic thanks to this annotation on the MQAutoConfiguration class:
#ConditionalOnMissingBean(value=javax.jms.ConnectionFactory.class)
Any ideas on how to put these pieces together?
EDIT: Just to avoid any possible red herrings to anyone, the MQRC2009 was irrelevant to ibm.mq.userAuthenticationMQCSP=false.
Some of my old projects I used a bean like this:
<bean id="jmsQueueConnectionFactory"
class="org.springframework.jms.connection.UserCredentialsConnectionFactoryAdapter">
<property name="targetConnectionFactory" ref="jmsConnectionFactory"/>
<property name="username" value="${jms.username}"/>
<property name="password" value="${jms.alias}"/>
</bean>
Should work well as a wrapper for your com.ibm.mq.jms.MQQueueConnectionFactory, but you have to use this jmsQueueConnectionFactory in the target components.
Although it looks like the mentioned IBM MQ JMS Spring doesn't that for us properly exposing a jmsConnectionFactory bean. You can rely on the default from Spring Integration in this case or use that jmsConnectionFactory explicitly for the connection-factory.
Also with Spring Boot you should consider to go away from XML configuration and give a chance for Spring Integration Java DSL: https://docs.spring.io/spring-integration/docs/5.1.7.RELEASE/reference/html/#java-dsl

Spring-Boot: Jmx annotation not working in library

I have a Spring-Boot application that just have a simple rest controller. On this controller, I added the jmx annotations #ManagedResource and #ManagedOperation and it is working fine. It is correctly exposed in Jmx.
This application depends on a "global-commons" library to share many basic functionality to all of our modules.
But if I add the same annotations to a class in this library, it is ignored!
And before you ask, yes the library is imported with the latest change.
There is no error or warning message in the logs.
I am configuring all my beans using an xml file. Both classes are beans defined in the same file.
One is a #RestController. The other one is a simple utility class.
Any idea?
Make sure the classes from the global-commons library as managed by Spring. As long as none of the classes in the library are managed by Spring, the annotions don't have any effect.
I found the problems:
The bean that was not working was defined as an "inner" bean:
<bean id="imMetrics" class="com.imetrik.global.common.metrics.ImGlobalMetrics" init-method="init">
...
<property name="reporterList">
<util:list>
<bean id="jmxReporter" class="com.imetrik.global.common.metrics.reporters.ImJmxReporter">
<property name="registryId" value="metricRegistry1"/>
<property name="durationUnit" value="SECONDS"/>
<property name="rateUnit" value="SECONDS"/>
<property name="domain" value="com.imetrik.global.metric"/>
</bean>
</util:list>
</property>
</bean>
The annotated beans is "jmxReporter".
But if I put it outside as a normal "first level" bean and use a reference instead, it is working.
But it is annoying! Is there a way to make it work even as a inner beans?

How to write Java code to Spring Configuration File

I have a spring configuration file for spring security. At beginning my file is getting from cache and when I do an operation it redirects me to the login page (However I can see page at first.) I want to solve that cache problem like that:
<beans:property name="defaultTargetUrl" value="/index.html?Math.random()"/>
However I think that it is not doing what I want, I am not sure.
Any ideas?
Try using Spring expression language
<property name="url" value="#{'/index.html?' + T(java.lang.Math).random()}"/>

Does Spring 3.0 provides a service definition file?

I'm wondering about Spring 3.0 whether it provides an automatically generated service definition page after I defined services.
With SOAP we have a WSDL file which contains WHAT, HOW and WHERE we can call a service.
Is that possible with Spring 3.0 or not?
Yes it does. Just add "?WSDL" to the URL of your Spring-generated web service and you'll get the definition. Also you can append "?xsd=1" instead and you'll get the schema you need (this is referenced also from the WSDL).
You can use an MBeanExporter to expose all of your services via JMX, which would be viewable through a JMX dashboard on your container (IE Tomcat, Jboss, etc). This is an easy way to account for 'what is deployed'. Your question is not entirely clear what sort of artifact you're looking for though.
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="autodetect" value="true"/>
</bean>
Will automatically export all of your defined beans as MBeans. Usually that's not entirely what you want, so alternatively, you'll specify them manually.
<bean id="exporter" class="org.springframework.jmx.export.MBeanExporter">
<property name="beans">
<map>
<entry key="bean:name=testBean1" value-ref="testBean"/>
</map>
</property>
</bean>
I agree with Chochos.
These[?wsdl, ?xsd=N] are universal standard to find the service definition file and any Datacontract defined in the wsdl.
example:
if http://localhost:8080/MyService is your service endpoint then it is service container's responsibility to make the WSDl available at http://localhost:8080/MyService,
by default.
The answer is Yes,
Use tag in your message dispatcher spring context file.
if your message dispatcher bean id is spring-ws then the spring context file for it would be spring-ws-servlet.xml.
In that context file,
import the namespace http://www.springframework.org/schema/web-services/web-services-2.0.xsd
xmlns:sws="http://www.springframework.org/schema/web-services".
then use the tag dynamic-wsdl from this namespace.
Also, you can set attributes for it like portType, binding and id. This will generate the wsdl file for you. You can view it by querying for it in the browser
/.wsdl

Correct usage Of LOG4J in Spring Framework Via DI

I am trying to use Log4j as part of the Spring Framework,
as far as i understand through the use of a an appropriate bean
the system is supposed to map a singleton instance accessible in the code
while mapping the logging depth automatically to the class
Similar to the normal use of Log4J as in
Logger log = Logger.getLogger(getClass());
i have been using the following Spring bean definition
<bean id="log4jInitialization"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass"
value="org.springframework.util.Log4jConfigurer" />
<property name="targetMethod" value="initLogging" />
<property name="arguments">
<list>
<value>conf\log4j.xml</value>
</list>
</property>
</bean>
But i am unable to map this bean to a specific member in a given class
nor am i able to use it through #autowired
Please let me know if there are any better ways to integrate Log4j and Spring
Best Regards
Mark
The short answer to your question is that log4j is not DI friendly.
The Log4jConfigurer.initLogging() method has a void return value, so there's nothing to inject. The idea is that you call that method, which bootstraps log4j, and then you use the Log4j API as usual (using Logger.getLogger(getClass())).
You generally wouldn't configure Log4jConfigurer as a Spring bean, though, but more usually you'd invoke it directly from your own code during application startup.
If this is a webapp, then Spring provides alternatives to Log4jConfigurer that are better suited to that environment (Log4jWebConfigurer, Log4jConfigListener).
Incidentally, 2 years ago I filed a feature request to allow loggers to be autowired, and it's finally been marked as fix for Spring 3.1. Horray.

Categories

Resources