I am newbie in Spring Webflow and I am migrating and old Java MVC application to Spring MVC + WebFlow.
Navigation in our old application worked with URLs like this /MyServlet?action=myAction&status=1 and we need to mantain them in the new application. So we have create a Controller that controls all requests to MyServlet with
#RequestMapping(value="/MyServlet", method = {RequestMethod.POST, RequestMethod.GET})
In this controller we have old servlet code who execute actions. This solution permit us use old code under Spring control.
Now we want to use WebFlow, but all views are expressed with URLs mention above and when I try to create a flow, it seems to be invalid. I have the following error:
The reference to entity "action" must end with the ';' delimiter
This is my XML flow file:
<view-state id="idIn" view="/MyServlet?action=myAction&status=1">
<transition on="list" to="idList" />
</view-state>
<view-state id="idList" view="/MyServlet?action=myAction&status=2">
<transition on="new" to="idNew" />
</view-state>
<view-state id="idNew" view="/MyServlet?action=myAction&status=3">
<transition on="out" to="idOut" />
</view-state>
<end-state id="idOut" view="/MyServlet">
</end-state>
Is it possible to use URL with parameters in Spring WebFLow? How could I do it?
Thanks a lot in advance.
Spring WebFlow has its own URL structure, with all states within a flow sharing a single URL for the whole flow. So you're not going to be able to maintain your current URL structure and use Spring WebFlow at the same time.
Thus, individual states within the flow are not directly accessible, even if you could transform the URLs with something like mod_rewrite, you'd be trying to jump into the middle of a flow, which is not how Spring WebFlow works.
Also, the view in the view-state is supposed to be a view-rendering technology like a JSP or Tile definition. It's an internal reference to a specific view, not the URL visible to the external user.
The reference to entity "action" must end with the ';' delimiter
This error uses to appear when character & is written to pass paramters in the URL. Just write & instead that character and the error should be fixed.
Hope this helps.
Related
I am having trouble using the Pax Web Whiteboard service to register a javax.servlet.Filter to a running JaxRS endpoint registered through CXF. I have tried a few different approaches, namely registering the Filter as a service, and using the org.ops4j.pax.web.service.WebContainer to register the filter directly.
For my test, i booted karaf, and installed pax-web, webconsole, cxf and the pax-web whiteboard service.
I the registered a bundle with a blueprint:
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxrs="http://cxf.apache.org/blueprint/jaxrs"
xmlns:cxf="http://cxf.apache.org/blueprint/core"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd
http://cxf.apache.org/blueprint/jaxrs http://cxf.apache.org/schemas/blueprint/jaxrs.xsd
http://cxf.apache.org/blueprint/core http://cxf.apache.org/schemas/blueprint/core.xsd
">
<cxf:bus>
<cxf:features>
<cxf:logging/>
</cxf:features>
</cxf:bus>
<jaxrs:server id="webfiltersample" address="/webfilter">
<jaxrs:serviceBeans>
<ref component-id="serviceBean" />
</jaxrs:serviceBeans>
</jaxrs:server>
<service id="servletFilterService" interface="javax.servlet.Filter">
<service-properties>
<entry key="filter-name" value="BasicWebFilter"/>
<entry key="urlPatterns" value="/*"/>
<entry key="initParams" value=""/>
</service-properties>
<bean class="test.webfilter.BasicWebFilter"/>
</service>
<bean id="serviceBean" class="test.webfilter.WebFilterSample" init-method="init" destroy-method="destroy">
<property name="bundleContext" ref="blueprintBundleContext"/>
</bean>
</blueprint>
However, this filter is never called. I have tried both using servlet names and urlpatterns, going so far as to attempt the urlpattern /*
I then tried a slightly different approach, removing the service declaration from the blueprint, and adding the filter directly though the init method of the blueprint instead:
public void init(){
logger.info("Starting Sample");
filter = new WebFilter();
ServiceReference<WebContainer> ref = bundleContext.getServiceReference(BasicWebFilter.class);
WebContainer container = bundleContext.getService(ref);
logger.info("Registering "+ filter + " with "+ container);
container.registerFilter(filter, new String[]{"/cxf/*"}, new String[]{""}, null, null);
bundleContext.ungetService(ref);
}
The method is indeed called, as reflected by the log statements, but the filter is still not executed.
So am i completely wrong in how this works? My "Application" is really just an endpoint registered to the CXF servlet. This part is working, and i can call the REST services defined therein. But no matter what i do, the filter is not executing. I am working with a few libraries here that i don't really know that well (Servlets/Filters, Pax-Web and the Writeboard extender) do i have no idea why exactly this isn't working? My guess is that there are different httpcontexts for each bundle, and that i can't simply register a filter for another bundle (CXF) in my own test bundle.
If this is true, can someone tell me how to properly go about this problem? I could get the CXF bundles bundlecontext and register the filter to that, but that seems like a terrible horrible hack.
If that is NOT the case, can someone tell me why this is not working?
You are right, every bundle should have it's own httpContext. With Pax-Web it's possible to have shared httpContextes. For this you need to enable it for the bundle initially registering the httpContext. Though in this case it's the cxf bundle that does take care of it. As the shared context is a pax-web only feature (till v6 where OSGi R6 is implemented), this won't be added to cxf as cxf tends to rely on the smallest possible solution, which is the HttpService.
Basically even though it's possible to share httpContextes with different bundles, it's not possible for you with this scenario.
I propose to use JAAS instead of shiro as a way to login and store the authentication information. You can then use this in shiro as well as in other security implementations to do the authorization.
For CXF there is a JAASLoginFeature. It can receive basic auth as well as UserNameToken. See https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=42568988
This also has the advantage that it works the same way as the standard karaf authentication. So by default you can define users and groups in etc/users.properties but you can also for example attach karaf to ldap.
If you use blueprint then you can use blueprint-authz do role based authorization using annotations. See https://github.com/apache/aries/tree/trunk/blueprint/blueprint-authz and https://github.com/apache/aries/blob/trunk/blueprint/blueprint-itests/src/test/java/org/apache/aries/blueprint/itests/authz/testbundle/impl/SecuredServiceImpl.java
I have a CAS 3.4.9 using the login webflow.
I need to call directly the login webflow at a particular action/view.
How can it be done?
If it is not possible (I believe a security reason), How can have on CAS another "service" using another webflow?
And in this manner, what is the link I must use to call it?
Thank you.
You have two options. Extending the class in which you want to make the call, for instance at generateServiceTicket, or create a new class and inject your class into the CAS login webflow.
I have injected a trap in my CAS login webflow to check to see if a user has accepted a policy in the last 365 days.
Normally in the warn decision state, it will return the redirect action state, but instead I am trapping the user so the policy will be checked.
<decision-state id="warn">
<if test="flowScope.warnCookieValue" then="showWarningView" else="checkPolicy" />
</decision-state>
It then transitions into my checkPolicy state
<action-state id="checkPolicy">
<evaluate expression="checkPolicyAction"/>
<transition on="success" to="redirect"/>
<transition on="error" to="viewLoginForm"/>
<transition on="redirectPolicy" to="redirectPolicy"/>
<transition on="gateway" to="redirectPolicy"/>
</action-state>
The expression checkPolicyAction is defined in the cas-servlet.xml to the java class which executes the doExecute method and returns back to the webflow various states as you see in the previous xml. Just to top it off, redirectPolicy redirects the user to a new service that will then have them accept the policy and they can then continue on to what they intended to do.
Take a look at https://github.com/Unicon/cas-password-manager - This is where a company has extended the login-webflow of CAS to trap for password updates. This is where I got most of my ideas on how to trap the user. Also the CAS User Manual https://wiki.jasig.org/display/CASUM/ is a great resource.
I want to remove logged out user from a Hashmap I have for logged in users but I don't find the way to do this as when I press the logout link. It just redirected to login page.
In spring security I have
<logout invalidate-session="true"
logout-success-url="/"
logout-url="/logout.htm"/>
logout link is like
Logout
When I press this link it just go to my login mapping
#RequestMapping("login")
public ModelAndView login(){}
and when I try to get user detail using
SecurityContextHolder.getContext()
.getAuthentication().getPrincipal();
it returns me anonymous user. So how can I get the logged out user detail.
Please let me know if you need more details.
Add an implementation of org.springframework.security.web.authentication.logout.LogoutSuccessHandler interface as a bean to your security context.
Then you can use it:
<logout success-handler-ref="yourLogoutSuccessHandler" />
EDIT.
As mentioned by Marcel this solution will not work out of the box because you can't mix success-handler-ref and logout-success-url attributes (reference). I prefer slightly different solution : instead of inheritance, you can use composition:
Prepare configuratio for SimpleUrlLogoutSuccessHandler bean.
Set up logout-success-url via corresponding defaultTargetUrl property.
Inject SimpleUrlLogoutSuccessHandler bean into your CustomUrlLogoutSuccessHandler using LogoutSuccessHandler interface and call it after doing your stuff.
Advantage is that you will be less coupled with a framework code. So you will have less problems in a case of migration from Spring Security 3.1 to Spring Security Y.Y
The hint about the LogoutSuccessHandler is correct. However, you have to consider that configuring success-handler-ref and logout-success-url are mutually exclusive if I'm not mistaken. Hence, you need to implement the forwarding to URL manually in your success handler. Pointer: https://stackoverflow.com/a/6770785/131929
Authentication authentication = SecurityContextHolder.getContext().getAuthentication()
authentication.getName()
In your applicationContext-security.xml file add the success-handler like below
< logout logout-url="/resources/j_spring_security_logout" success-handler-ref="com.mycompany.security.SpringSecurityLogoutHandler" />
Create the Class which will be implemneting org.springframework.security.web.authentication.logout.LogoutHandler interface and in it's logout method do all the stuff you want at the time of logout.
I am using Spring-MVC LightCouch and CouchDB and I have custom Views that need to be inserted into the DB on deployment. I have found the LightCouch has a method for pulling documents "from desk" as noted on their website:
DesignDocument designDoc = dbClient.design().getFromDesk("example");
Response response = dbClient.design().synchronizeWithDb(designDoc);
This Works good from within JAVA code, however I need to be able to do it in the Spring ApplicationContext.xml I have more than one so I would like to mimick the call of:
dbClient.dessign().synchronizeAllWithDB()
How would I do this in the bean definition of the ApplicationContext I already have this:
<bean id="dbClient" class="org.lightcouch.CouchDbClient" lazy-init="false" destroy- method="shutdown">
<constructor-arg value="couchdb.properties" />
</bean>
It seems you can't do it with Spring xml config, as the init method falls under a different instance; that is returned by the call to design() factory method. Maybe you can try Java code equivalence, i.e. #PostConstruct.
I ended up having to make a bean that synchronized the database on init and created that when the app starts
I use filenames in my REST API (example: GET http://xxx/api/myImage.jpg)
problem is #PathVariable dropped ".jpg".
this problems already asked few times in here and answered. but not worked to me.
so I searched then found at the
https://jira.springsource.org/browse/SPR-6524
"... is simply not supposed to be combined with manual DefaultAnnotationHandlerMapping instances; this is designed as an either-or choice at present, quite similar to and ."
"mvc namespace are make simplifed configurations".
Real question is mvc what does do? and changed?
I found my self these things..
intercepter configuration changed. (mvc namspace required in bean configuation)
useDefaultSuffixPattern is not working.
adds JSON message converter. if jackson library is available
#PathVariable arguments are auto added to model
Any others?
Thanks in advance!
The mvc:annotationDriven tag essentially sets you your Spring context to allow for dispatching requests to Controllers.
The tag will configure two beans DefaultAnnotationHandlerMapping and AnnotationMethodHandlerAdapter.
You can find more information from the spring documents:
http://static.springsource.org/spring/docs/current/spring-framework-reference/html/mvc.html
Before I provide certain points let me clear up the answer provided by Roy is not accurate. You don't have to provide mvc:annotation-driven tag to instantiate default beans. This tag can be used Spring 3.0+ to enable new feature introduced from Spring 3.0
(Do not use it if you want backward compatibility, especially if you are using old controller based classes like MultiActionController, SimpleFormController)
Now lets come to what this tag actually does -
Prior to Spring 3.1 default beans used where
DefaultAnnotationHandlerMapping
AnnotationMethodHandlerAdapter
AnnotationMethodHandlerExceptionResolver
These are deprecated in Spring 3.1 and if you use above mentioned tag it will be replaced by -
RequestMappingHandlerMapping
RequestMappingHandlerAdapter
ExceptionHandlerExceptionResolver
DefaultAnnotationHandlerMapping decided which controller to use and the AnnotationMethodHandlerAdapter selected the actual method that handled the request. RequestMappingHandlerMapping does both the tasks. Therefore the request is directly mapped right to the method.
There are other infrastructure beans that are instantiated by these tag (chained in addition to defaults) like - MappedInterceptor, ConfigurableWebBindingInitializer, SessionFlashManager, ContentNegociationManager etc. I am not going to explain these :) as they each are long answers themselves, so google it for more info.
PS : And yes Spring 3.1+ automatically expose #PathVariables to the model. Also you have mvc:interceptors tag. But I think it is not related to <mvc:annotation-driven />. I would highly recommend read - http://spring.io/blog/2009/12/21/mvc-simplifications-in-spring-3-0/
To enable MVC Java config add the annotation #EnableWebMvc to one of your #Configuration classes:
#Configuration
#EnableWebMvc
public class WebConfig {
}
To achieve the same in XML use the
mvc:annotation-driven
element in your DispatcherServlet context (or in your root context if you have no DispatcherServlet context defined):
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven/>
</beans>
The above registers a RequestMappingHandlerMapping, a RequestMappingHandlerAdapter, and an ExceptionHandlerExceptionResolver (among others) in support of processing requests with annotated controller methods using annotations such as #RequestMapping, #ExceptionHandler, and others.
For details refer the below link :
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html#mvc-config
mvc:annotation-driven tag do extra work from context:component-scan tag
The tag registers the Handler Mapping and Handler Adapter required to dispatch requests to your #Controllers:
tag helps registering the following components.
DefaultAnnotationHandlerMapping - This is a HandlerMapping implementation which maps the HTTP requests to the handler methods defined using the #RequestMapping annotation.
AnnotationMethodHandlerAdapter - It is responsible for scanning the controllers to identify methods (and parameters) annotated with #MVC annotations. It scans and caches handler methods annotated with #RequestMapping. Also handles the #RequestParam, #ModelAttribute, #SessionAttributes and #InitBinder annotations.
ConfigurableWebBindingInitializer - The initializer for the Web Data Binder. Helps in declaratively configuring the Web Binder with validators, conversion services, property editors, etc.
LocalValidatorFactoryBean - Implements the validator interface and enables JSR303 validation. This is injected into ConfigurableWebBindingInitializer.
FormattingConversionServiceFactoryBean - A conversion factory that returns conversion services for basic objects like date and numbers. This factory is again injected into ConfigurableWebBindingInitializer.
Message Converters
ByteArrayHttpMessageConverter - A HTTP request message converter that reads a HTTP message body and returns a byte stream. It can also read a byte stream and construct a response body. Used for receiving and sending documents like PDF, XLS, etc.
StringHttpMessageConverter - A HTTP request message converter that reads a plain text request body and binds it to a String object. And vice-versa with response.
FormHttpMessageConverter - A HTTP request message converter that reads a form encoded request body and binds it to a form Binding object.
SourceHttpMessageConverter - A HTTP request converter that converts a XML message body to/from Binding Object.
If we do not use mvc:annotation-driven tag then we have to do register these components manually in xml file in order to use them , which results in too much extra work.