How to integrate MyFaces with Spring - spring

In my logon.xhtml, I have following code that involve my backing bean to perform correspopnding logon through spring security.
<h:commandButton type="submit" id="login" value="Login"
action="#{logonController.doLogin}" />
My backing bean defines as the following.
#Component
#ManagedBean(name="logonController")
#SessionScoped
public class LogonController
{
. . .
public String doLogin() throws ServletException, IOException {
ExternalContext context = FacesContext.getCurrentInstance().getExternalContext();
RequestDispatcher dispatcher = ((ServletRequest) context.getRequest())
.getRequestDispatcher("/j_spring_security_check");
dispatcher.forward((ServletRequest) context.getRequest(),
(ServletResponse) context.getResponse());
FacesContext.getCurrentInstance().responseComplete();
logger.debug("in LogonPageController ");
return null;
}
}
In order to integrate spring with JSF, I have also added the following to the faces-config.xml.
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
Moreover, two standard spring listeners have also be inclued in the web.xml
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
I have tried the above setting in mojarra + tomcat and it should be able to trigger the logon() function of my backing bean when user click on the Logon button. However, when I swith to TomEE with MyFaces, this won't work. I have the following maven dependency in my pom.xml.
<dependency>
<groupId>org.apache.myfaces.core</groupId>
<artifactId>myfaces-api</artifactId>
<version>${myfaces-version}</version>
</dependency>
<dependency>
<groupId>org.apache.myfaces.core</groupId>
<artifactId>myfaces-impl</artifactId>
<version>${myfaces-version}</version>
</dependency>
Is there any thing that I need to add in order to make it work with MyFaces?
Thanks for your help.

Related

spring4gwt error:Spring bean not found: querySenior

I am trying to make gwt-2.7 work with spring-4.2.3.Configurations are:
web.xml
<!-- spring config -->
<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>
<!-- Spring GWT integration -->
<servlet>
<servlet-name>springGwtRemoteServiceServlet</servlet-name>
<servlet-class>org.spring4gwt.server.SpringGwtRemoteServiceServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springGwtRemoteServiceServlet</servlet-name>
<url-pattern>/idp_web/service/*</url-pattern>
</servlet-mapping>
applicationContext.xml
<beans
...
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
....
default-lazy-init="true">
<!-- auto-inject bean by annotation mechanism -->
<context:component-scan
base-package="com.vsi.idp.analysis.server,
com.vsi.idp.base.server,
com.vsi.idp.kpi.server,
com.vsi.idp.map.server,//SeniorQueryServiceImpl is under this package
com.vsi.idp.statistics.server" />
//other configurations
</beans>
GWT services
#RemoteServiceRelativePath("service/querySenior")
public interface SeniorQueryService extends RemoteService{...}
service impl
#Service("querySenior")
public class SeniorQueryServiceImpl extends RemoteServiceServlet implements SeniorQueryService{...}
Spock unit test works fine
#ContextConfiguration(locations = "file:war/WEB-INF/applicationContext.xml")
public class SeniorQueryServiceImplTest extends Specification{
#Autowired
SeniorQueryServiceImpl service
def "query by full address"(){
//blabla
}
}
Running gwt project tells:
Failed to load resource: the server responded with a status of 500 (Server Error)
Error stack looks like:
[WARN] Exception while dispatching incoming RPC call
java.lang.IllegalArgumentException: Spring bean not found: querySenior
at org.spring4gwt.server.SpringGwtRemoteServiceServlet.getBean(SpringGwtRemoteServiceServlet.java:96)
at org.spring4gwt.server.SpringGwtRemoteServiceServlet.getBean(SpringGwtRemoteServiceServlet.java:55)
at org.spring4gwt.server.SpringGwtRemoteServiceServlet.processCall(SpringGwtRemoteServiceServlet.java:31)
at com.google.gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:373)
I think:
1,"500(server error)" tells that gwt has recognized spring service
2,spring service unit test works fine,so spring configuration is right
The problem may come from spring4gwt,and how to solve this problem?
This really should be a working solution.
SpringGwtRemoteServiceServlet#getBean
protected Object getBean(String name) {
WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
if (applicationContext == null) {
throw new IllegalStateException("No Spring web application context found");
}
if (!applicationContext.containsBean(name)) {
throw new IllegalArgumentException("Spring bean not found: " + name);
}
return applicationContext.getBean(name);
}
We can see that Exception comes because there was no bean in applicationContext
Try to implicitly declare this bean in applicatinContext.
Recomendation
If you are a fun on RPC I recommend you to take a look at GWTP and their GWT dispatch module.
Approach is similar to Spring4Gwt, but it is much better to communicate with Command pattern.
With regular GWT RPC approach services in big projects becomes a mess of really lot's of
methods at one place, and you will be not happy to create a new Async pair for any new method.
Or the best approach will be to communicate with JSON and avoid GWT serialization approach, your will be happy and easy to integrate with you App later.

JSF2 with jdbctemplate in Spring 3.0

I am using JSF2 with Spring3 JDBC template. I have added the following content to the web.xml file
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
I have added the following code into faces-config.xml
<application>
<el-resolver>
org.springframework.web.jsf.el.SpringBeanFacesELResolver
</el-resolver>
</application>
DAO code is the following
#Repository
public class XXXDAOImpl implements ZZZDAO{
#Autowired
private JdbcTemplate jdbcTemplate
------------------
}
public void methodname(object){
jdbcTemplate.update(sqlquery,arguments);
}
I have added the following code in application context xml file.
The managed bean is
#ManagedBean(name = "aaaBean")
#RequestScoped
public class CustomerBean{
-----
}
I am using Spring 3.0 jar files and javax.faces-2.2.8 jar file.
The intention is to get customer details from a JSF view page and store it in a table.
Upon execution of the code a null pointer exception is thrown from DAO where jdbc template's update method is invoked. Help is apprciated.

Managed bean not working after adding Spring configuration

I really do not know what's the cause of the problem. I created a website with hibenate and JSF and later decided to integrate Spring framework as well, but eventually faced a problem.
My managed bean "loginbean" was working perfectly. It also recognizes the method within a JSF page, but when I run the application I see an "error excusion" message.
My bean:
#ManagedBean(name="loginBean")
#SessionScoped
public class LoginBean {
private String username;
private String password;
private int activeindex;
public String Dirige(int a){
setActiveindex(a);
if (a == 0){
return "/Menu.jsf";
}else{
if (a == 1) {
return "/pagess/pagesFabricant/Fabricant.jsf";
}else{
if (a == 2) {
return "/pagess/pagesComposant/Composant.jsf";
}else{
if(a == 3){
return "/pagess/pagesDeq/DEQ.jsf";
}
}
}
}
return null;
}
}
I added SpringBeanFacesELResolver in faces-config.xml:
<application>
<el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application> on faces.config.xml
and I also included the relevant listeners in web.xml:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/application.xml
</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
My view:
<p:tabMenu activeIndex="#{loginBean.activeindex}">
<p:menuitem value="Home" icon="ui-icon-star" action="#{loginBean.Dirige(0)}" />
<p:menuitem value="Fabricants" icon="ui-icon-wrench" action="#{loginBean.Dirige(1)}" />
<p:menuitem value="Composants" icon="ui-icon-search" action="#{loginBean.Dirige(2)}"/>
<p:menuitem value="Dossier d'equivalence" icon="ui-icon-document" action="#{loginBean.Dirige(3)}"/>
</p:tabMenu>
And finally this is the error I've got:
Grave: javax.el.MethodNotFoundException: /templates/template.xhtml #42,95 action="#{loginBean.Dirige(1)}": Method not found: com.ardia.beans.LoginBean#1af73b2.Dirige(java.lang.Long)
javax.faces.el.MethodNotFoundException: javax.el.MethodNotFoundException: /templates/template.xhtml #42,95 action="#{loginBean.Dirige(1)}": Method not found: com.ardia.beans.LoginBean#1af73b2.Dirige(java.lang.Long)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:92)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
at javax.faces.component.UICommand.broadcast(UICommand.java:315)
the problem is that I start the application in another tomcat server .. it works well it accepts bean method with parameters
Thx all for your cooperation

RestEasy with Spring renders no answer

I can see that the FilterDispatcher is called (by debugger), but it doesn't seem to find the service to call. I've got trouble grasping how RestEasy actually maps between resources defined in Spring and RestEasy.
Main story: Getting http://my.local.no:8087/rest/typeaheads/h only renders 404
web.xml:
...
<context-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<param-value>/rest</param-value>
</context-param>
<listener>
<listener-class>org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<filter>
<filter-name>restFilterDispatcher</filter-name>
<filter-class>org.jboss.resteasy.plugins.server.servlet.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>restFilterDispatcher</filter-name>
<url-pattern>/rest/*</url-pattern>
</filter-mapping>
...
resteasy resource is set up by bean:
#Configuration
#ComponentScan(basePackageClasses = TypeaheadsRestService.class)
public class SpringConfig {
}
TypeaheadsRestService.java:
#Resource
#Path("/typeaheads")
public class TypeaheadsRestService {
#GET
#Path("/{search}")
#Produces(MediaType.APPLICATION_JSON)
public List<NameUrl> get(#PathParam("search") String search) {
...
}
}
The RestEasy SpringContextLoaderListener seem to be the missing part. I created a stripped down problem from RestEasy example and used it. For my somewhat more complex application however it would not work. That is probably because it overrides the deprecated createContextLoader-method. In Spring 3 ContextLoaderListener is an instance of ContextLoader. So I reimplemented it like this:
public class MyContextLoaderListener extends ContextLoaderListener {
private SpringContextLoaderSupport springContextLoaderSupport = new SpringContextLoaderSupport();
#Override
protected void customizeContext(ServletContext servletContext, ConfigurableWebApplicationContext applicationContext) {
super.customizeContext(servletContext, applicationContext);
this.springContextLoaderSupport.customizeContext(servletContext, applicationContext);
}
}
I originally tried to do the customizeContext(...) in a bean initialisation. That worked in RestEasy 2.2.1.GA, but not in 2.3.4.FINAL.

Use Apache cxf with spring mvc in a single application with shared services

I'm currently working a project which based on spring MVC, it's just a standard project using spring MVC template. so I have web.xml and servlet-context.xml.
I'm working on adding Apache cxf web services into this project, and meet some problems on sharing services with existing Spring MVC.
My initial approach was trying to get web services working, so here is my web.xml looks like:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- The definition of the Root Spring Container shared by all Servlets
and Filters -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/root-context.xml
/WEB-INF/spring/jaxwsServlet/jaxwsServlet-context.xml
</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Process web service requests -->
<servlet>
<servlet-name>jaxws</servlet-name>
<servlet-class>com.sun.xml.ws.transport.http.servlet.WSSpringServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jaxws</servlet-name>
<url-pattern>/industryAspectWS</url-pattern>
</servlet-mapping>
<!-- Processes application requests -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
and my jaxwsServlet-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ws="http://jax-ws.dev.java.net/spring/core"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:wss="http://jax-ws.dev.java.net/spring/servlet"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://jax-ws.dev.java.net/spring/core
classpath:spring-jax-ws-core.xsd
http://jax-ws.dev.java.net/spring/servlet
classpath:spring-jax-ws-servlet.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd"
>
<wss:binding url="/industryAspectWS">
<wss:service>
<ws:service bean="#industryAspectWS"/>
</wss:service>
</wss:binding>
<!-- Web service methods -->
<bean id="industryAspectWS" class="com.example.ws.IndustryAspectWS"></bean>
<context:component-scan base-package="com.example" />
<beans:import resource="../HibernateTransaction.xml" />
<beans:import resource="../JaxbMarshaller.xml" />
</beans>
I copied the context:component-scan beans:import sections from servlet-context.xml
This configuration works okay since I was able to boot up the server, and call Web services and also access servlet and jsp. However, I notice that since I quoted the hibernateTransaction.xml in both context xml files, there are two session factories.
I want to share all services (such as hibernate) between Apache cxf and Spring MVC controllers, so I tried to put settings in root-context.xml, it didn't work. I also tried to search this online, but didn't find any complete examples on shared services. Is it possible that we can put a setting to share services among the two?
=================================================
I had experimented some settings after I post this, and figured that if I put the lines of
<context:component-scan base-package="com.example" />
and
<tx:annotation-driven transaction-manager="txManagerExample" />
in both servlet-context.xml and jaxwsServlet-context.xml, it will work just fine. all other settings can stay in the shared root-context.xml
WSSpringServlet is not CXF. It is Metro. I would recommend using CXF. In that case you will have a CXFServlet but then you would set up CXF in your main Spring context (the one created by ContextLoaderListener.
It would work as follows: your main context would have all of the shared beans including CXF. Your Servlet context would have just your controllers. Since the servlet context is a child of the main context your controllers would also have access to everything in the main context.
See the Embedding CXF inside of Spring page, the CXF Servlet Transport Page, and my answer to this question about sharing beans between servlet context and main context.
Thanks to https://stackoverflow.com/a/30758664/2615824:
Two dispatchers (Spring MVC REST Controller and CXF JAX-WS) with one Spring Context, Java Config (no xml stuff...) example:
WebApplicationInitializer:
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(MyServiceConfig.class);
servletContext.addListener(new ContextLoaderListener(rootContext));
AnnotationConfigWebApplicationContext webContext = new AnnotationConfigWebApplicationContext();
webContext.setParent(rootContext);
ServletRegistration.Dynamic restDispatcher = servletContext.addServlet("REST dispatcher", new DispatcherServlet(webContext));
restDispatcher.setLoadOnStartup(1);
restDispatcher.addMapping("/api/*");
ServletRegistration.Dynamic cxfDispatcher = servletContext.addServlet("CXF dispatcher", CXFServlet.class);
cxfDispatcher.setLoadOnStartup(1);
cxfDispatcher.addMapping("/services/*");
}
Config:
#Configuration
#ComponentScan("my.root.package")
#ImportResource(value = {"classpath:META-INF/cxf/cxf.xml"})
#PropertySource("classpath:app-env.properties")
#PropertySource("classpath:app.properties")
#EnableWebMvc
public class MyServiceConfig {
#Autowired
private Bus cxfBus;
#Autowired
private CxfEndpointImpl cxfEndpoint;
#Bean
public Endpoint cxfService() {
EndpointImpl endpoint = new EndpointImpl(cxfBus, cxfEndpoint);
endpoint.setAddress("/CxfEndpointImpl");
endpoint.setWsdlLocation("classpath:CxfService/CxfService-v1.0.wsdl");
endpoint.publish();
return endpoint;
}
#Bean
public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}
Sample CXF Endpoint (WSDL first):
#Component
#WebService(
endpointInterface = ".....v1_0.CxfServicePort",
targetNamespace = "http://..../service/CxfService/v1_0",
serviceName = "CxfService",
portName = "CxfServicePort",
wsdlLocation = "classpath:CxfService/CxfService-v1.0.wsdl")
#MTOM(enabled = true)
#SchemaValidation(type = SchemaValidationType.BOTH)
#InInterceptors(classes = NoBinaryContentLoggingInInterceptor.class)
#OutInterceptors(classes = NoBinaryContentLoggingOutInterceptor.class)
#EndpointProperty(key = "ws-security.callback-handler", ref = "cxfEndpointSecurityHandler")
public class CxfEndpointImpl implements CxfServicePort {
//...
}
Sample REST Controller:
#RestController
#RequestMapping(value = "/system", produces = MediaType.APPLICATION_JSON_VALUE)
public class RestController {
//...
}
CXF Endpoint deployment address:
ip:port/tomcat-context/services/CxfEndpointImpl?wsdl
Spring REST Controller deployment address:
ip:port/tomcat-context/api/system

Resources