Websocket Stomp - Broadcast(Topic,queue) - spring

How do I broadcast to all subscribers(Topic) and the specified user(Channel).
this.messagingTemplate.convertAndSend(destination, message);
this.messagingTemplate.convertAndSendToUser(userId, destination, message);
Is that correct?
What is WebSocketConnectHandlerDecoratorFactory class for?
public final class WebSocketConnectHandlerDecoratorFactory implements WebSocketHandlerDecoratorFactory {
private static final Log logger = LogFactory.getLog(WebSocketConnectHandlerDecoratorFactory.class);
private final ApplicationEventPublisher eventPublisher;
/**
* Creates a new instance
*
* #param eventPublisher the {#link ApplicationEventPublisher} to use. Cannot be null.
*/
public WebSocketConnectHandlerDecoratorFactory(ApplicationEventPublisher eventPublisher) {
Assert.notNull(eventPublisher, "eventPublisher cannot be null");
this.eventPublisher = eventPublisher;
}
#Override
public WebSocketHandler decorate(WebSocketHandler handler) {
return new SessionWebSocketHandler(handler);
}
private final class SessionWebSocketHandler extends WebSocketHandlerDecorator {
public SessionWebSocketHandler(WebSocketHandler delegate) {
super(delegate);
}
#Override
public void afterConnectionEstablished(WebSocketSession wsSession)
throws Exception {
super.afterConnectionEstablished(wsSession);
publishEvent(new SessionConnectEvent(this,wsSession));
}
private void publishEvent(ApplicationEvent event) {
try {
eventPublisher.publishEvent(event);
}
catch (Throwable ex) {
logger.error("Error publishing " + event + ".", ex);
}
}
}
}

Correct.
See its JavaDocs:
/**
* Ensures that a {#link SessionConnectEvent} is published in
* {#link WebSocketHandler#afterConnectionEstablished(WebSocketSession)}. This
* is necessary so that the {#link WebSocketSession} can be mapped to the
* corresponding Spring {#link Session} to terminate any
* {#link WebSocketSession} associated with a Spring {#link Session} that was
* destroyed.
*
* #author Rob Winch
* #since 1.0
*
* #see WebSocketRegistryListener
*/

Related

How to handle different type of Exception in Spring Integration using java DSL?

I have following simple proxy integration flow. The main task of which is to take request from the proxy send it to the actual endpoint, get the respond and send it back to the client. I would like to handle different type of exceptions.
#SpringBootApplication
#EnableIntegration
public class IntegrationApp {
#Value("${narko.pin}")
private String pinUrl;
public static void main(String[] args) {
SpringApplication.run(MinzdravApplication.class, args);
}
#Bean
public DirectChannel requestPinChannel() {
return new DirectChannel();
}
#Bean
public DirectChannel replyPinChannel() {
return new DirectChannel();
}
#Bean
public IntegrationFlow httpProxyFlowPin() throws Exception {
return IntegrationFlows
.from(Http.inboundGateway("/narko/api/patient/by-pinpp")
.requestChannel(requestPinChannel())
.mappedRequestHeaders("activityid")
.errorChannel("httpProxyErrorFlow.input")
)
.wireTap(sf->sf.handle(new InwardMessageHandler()))
.enrichHeaders(h -> h.header("Content-Type", "application/json"))
.handle(Http.outboundGateway(pinUrl).charset("utf-8")
.expectedResponseType(String.class))
.get();
}
#Bean
public IntegrationFlow httpProxyErrorFlow() {
return f -> f
.transform(Throwable::getCause)
.<RuntimeException>handle(
(p, h) ->
MessageBuilder.fromMessage(new Message<ErrorDto>() {
final Map<String, Object> headers=new HashMap<>();
#Override
public ErrorDto getPayload() {
if(p instanceof JSONException){
headers.put(HttpHeaders.STATUS_CODE,HttpStatus.BAD_REQUEST);
return new ErrorDto(HttpStatus.BAD_REQUEST.value(),p.getMessage());
}else if(p instanceof MethodNotAllowedException){
headers.put(HttpHeaders.STATUS_CODE,HttpStatus.METHOD_NOT_ALLOWED);
return new ErrorDto(HttpStatus.METHOD_NOT_ALLOWED.value(),p.getMessage());
}
else{
headers.put(HttpHeaders.STATUS_CODE,HttpStatus.INTERNAL_SERVER_ERROR);
return new ErrorDto(HttpStatus.INTERNAL_SERVER_ERROR.value(),p.getMessage());
}
}
#Override
public MessageHeaders getHeaders() {
return new MessageHeaders(headers);
}
})
).transform(Transformers.toJson())
;
}
As you can see the code above I have to check every possible exception type, then form corresponding ErrorDto, which makes the code difficult to maintain. Is it possible to handle them as one can do it with #ControllerAdvice? For instance :
#ControllerAdvice
public class ApiExceptionHandler {
#ExceptionHandler(JSONException.class)
#ResponseStatus(HttpStatus.BAD_REQUEST)
public ResponseEntity<ApiError> onRuntimeException(JSONException ex) {
ErrorDto apiError = new ErrorDto(HttpStatus.BAD_REQUEST, ex.getMessage(), ex);
return buildResponseEntity(apiError);
}
#ExceptionHandler(MethodNotAllowedException.class)
#ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
public ResponseEntity<ApiError> onIllegalException(MethodNotAllowedException ex) {
ErrorDto apiError = new ErrorDto(HttpStatus.METHOD_NOT_ALLOWED, ex.getMessage(), ex);
return buildResponseEntity(apiError);
}
...
}
Sure! You can do something similar with Spring Integration. See an ErrorMessageExceptionTypeRouter and its Java DSL routeByException():
/**
* Populate the {#link ErrorMessageExceptionTypeRouter} with options from the {#link RouterSpec}.
* Typically, used with a Lambda expression:
* <pre class="code">
* {#code
* .routeByException(r -> r
* .channelMapping(IllegalArgumentException.class, "illegalArgumentChannel")
* .subFlowMapping(MessageHandlingException.class, sf ->
* sf.handle(...))
* )
* }
* </pre>
* #param routerConfigurer the {#link Consumer} to provide {#link ErrorMessageExceptionTypeRouter} options.
* #return the current {#link BaseIntegrationFlowDefinition}.
* #see ErrorMessageExceptionTypeRouter
*/
public B routeByException(
Consumer<RouterSpec<Class<? extends Throwable>, ErrorMessageExceptionTypeRouter>> routerConfigurer) {
https://docs.spring.io/spring-integration/docs/current/reference/html/message-routing.html#router-implementations-exception-router
You also can just throw those exceptions back to the proxy and have that #ControllerAdvice for handling them on the MVC level.

Reference to a bean in a constructor of a different class

I am trying to migrate a legacy project into Spring Boot. There is an auto-generated class I've been struggling with. Please see below the original class that provides the interface for a web service.
/**
* This class was generated by the JAX-WS RI. JAX-WS RI 2.2.9-b130926.1035 Generated source version: 2.2
*
*/
#WebServiceClient(name = "SomeWebService", targetNamespace = "http://www.somewebservice.com")
public class SomeWebService extends Service {
private final static URL SomeWebService_WSDL_LOCATION;
private final static WebServiceException SomeWebService_EXCEPTION;
private final static QName SomeWebService_QNAME = new QName("http://www.somewebservice.com", "SomeWebService");
static {
URL url = null;
WebServiceException e = null;
try {
url = new URL(DataAccessLayer.systemProps.getProperty("configurable_service_url"));
} catch (MalformedURLException ex) {
e = new WebServiceException(ex);
}
SomeWebService_WSDL_LOCATION = url;
SomeWebService_EXCEPTION = e;
}
public SomeWebService() {
super(__getWsdlLocation(), SomeWebService_QNAME);
}
public SomeWebService(WebServiceFeature... features) {
super(__getWsdlLocation(), SomeWebService_QNAME, features);
}
public SomeWebService(URL wsdlLocation) {
super(wsdlLocation, SomeWebService_QNAME);
}
public SomeWebService(URL wsdlLocation, WebServiceFeature... features) {
super(wsdlLocation, SomeWebService_QNAME, features);
}
public SomeWebService(URL wsdlLocation, QName serviceName) {
super(wsdlLocation, serviceName);
}
public SomeWebService(URL wsdlLocation, QName serviceName, WebServiceFeature... features) {
super(wsdlLocation, serviceName, features);
}
/**
*
* #return returns SomeWebService
*/
#WebEndpoint(name = "SomeWebServicePort")
public SomeWebService getSomeWebServicePort() {
return super.getPort(new QName("http://www.somewebservice.com", "SomeWebServicePort"), SomeWebService.class);
}
/**
*
* #param features
* A list of {#link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in
* the <code>features</code> parameter will have their default values.
* #return returns SomeWebService
*/
#WebEndpoint(name = "SomeWebServicePort")
public SomeWebService getSomeWebServicePort(WebServiceFeature... features) {
return super.getPort(new QName("http://www.somewebservice.com", "SomeWebServicePort"), SomeWebService.class, features);
}
private static URL __getWsdlLocation() {
if (SomeWebService_EXCEPTION != null) {
throw SomeWebService_EXCEPTION;
}
return SomeWebService_WSDL_LOCATION;
}
}
Please note the line:
url = new URL(DataAccessLayer.systemProps.getProperty("configurable_service_url"));
This is how it is configured in the legacy code, in a static block...
The first thing I did is add a config class to pick up properties from a file as follows:
#Configuration
#PropertySource({"classpath:someWebservice.properties"})
public class SomeWebserviceConfiguration {
}
However, I am not able to figure out a way to create a bean (a url), and then use the bean in the constructors.
Can someone give me some ideas or point me in the right direction? Thanks so much!
OK. I have found a solution. The code looks a bit unseemly. But it works.
First I need to add a config class, and make it ApplicationContextAware.
#Configuration
#PropertySource({ "classpath:somewebservice.properties" })
public class WebServiceConfiguration implements ApplicationContextAware {
private static ApplicationContext ctx;
#Value("${configurable_service_url}")
private String serviceUrlProp;
#Bean
#Qualifier("serviceUrl")
public URL getServiceUrl() throws MalformedURLException {
return new URL(serviceUrlProp);
}
#Override
public void setApplicationContext(ApplicationContext appContext) throws BeansException {
ctx = appContext;
}
public static ApplicationContext getApplicationContext() {
return ctx;
}
}
This is where the property "configurable_service_url" gets picked up. We also create a URL bean and make it available in the container. The static ApplicationContext is for the web service class to grab and then it will get hold of the bean.
/**
* This class was generated by the JAX-WS RI. JAX-WS RI 2.2.9-b130926.1035 Generated source version: 2.2
*
*/
#WebServiceClient(name = "SomeWebService", targetNamespace = "http://www.somewebservice.com")
public class SomeWebService extends Service {
private final static QName SomeWebService_QNAME = new QName("http://www.somewebservice.com", "SomeWebService");
public SomeWebService() {
super((URL) BlazeConfiguration.getApplicationContext().getBean("getServiceUrl"), SomeWebService_QNAME);
}
public SomeWebService(WebServiceFeature... features) {
super((URL) BlazeConfiguration.getApplicationContext().getBean("getServiceUrl"), SomeWebService_QNAME, features);
}
public SomeWebService(URL wsdlLocation) {
super(wsdlLocation, SomeWebService_QNAME);
}
public SomeWebService(URL wsdlLocation, WebServiceFeature... features) {
super(wsdlLocation, SomeWebService_QNAME, features);
}
public SomeWebService(URL wsdlLocation, QName serviceName) {
super(wsdlLocation, serviceName);
}
public SomeWebService(URL wsdlLocation, QName serviceName, WebServiceFeature... features) {
super(wsdlLocation, serviceName, features);
}
/**
*
* #return returns SomeWebService
*/
#WebEndpoint(name = "SomeWebServicePort")
public SomeWebService getSomeWebServicePort() {
return super.getPort(new QName("http://www.somewebservice.com", "SomeWebServicePort"), SomeWebService.class);
}
/**
*
* #param features
* A list of {#link javax.xml.ws.WebServiceFeature} to configure on the proxy. Supported features not in
* the <code>features</code> parameter will have their default values.
* #return returns SomeWebService
*/
#WebEndpoint(name = "SomeWebServicePort")
public SomeWebService getSomeWebServicePort(WebServiceFeature... features) {
return super.getPort(new QName("http://www.somewebservice.com", "SomeWebServicePort"), SomeWebService.class, features);
}
}
In the constructor
public SomeWebService() {
super((URL) BlazeConfiguration.getApplicationContext().getBean("getServiceUrl"), SomeWebService_QNAME);
}
I first tried to use the name "serviceUrl". But it complained that it could not find it in the application context. I had to print out all the available beans in the container to see that I needed to use "getServiceUrl", which is the method name, to retrieve the bean.

AbstractMongoEventListener is not getting invoked

I have the following class
class MongoCascadeSaveEventListener extends AbstractMongoEventListener<Object> {
#Override
public void onBeforeConvert(final BeforeConvertEvent<Object> event) {
}
}
Bean definition
#Bean
public MongoCascadeSaveEventListener mongoCascadeSaveEventListener() {
return new MongoCascadeSaveEventListener();
}
onBeforeConvert is never being called.
When i check the class of MongoTemplate the event publisher is set like following
eventPublisher = new MongoMappingEventPublisher(indexCreator);
The class from spring mongo package. When i see the class i dont think the implementation is correct and that explains why listener is not invoked.
public class MongoMappingEventPublisher implements ApplicationEventPublisher {
private final MongoPersistentEntityIndexCreator indexCreator;
/**
* Creates a new {#link MongoMappingEventPublisher} for the given {#link MongoPersistentEntityIndexCreator}.
*
* #param indexCreator must not be {#literal null}.
*/
public MongoMappingEventPublisher(MongoPersistentEntityIndexCreator indexCreator) {
Assert.notNull(indexCreator, "MongoPersistentEntityIndexCreator must not be null!");
this.indexCreator = indexCreator;
}
/*
* (non-Javadoc)
* #see org.springframework.context.ApplicationEventPublisher#publishEvent(org.springframework.context.ApplicationEvent)
*/
#SuppressWarnings("unchecked")
public void publishEvent(ApplicationEvent event) {
if (event instanceof MappingContextEvent) {
indexCreator.onApplicationEvent((MappingContextEvent<MongoPersistentEntity<?>, MongoPersistentProperty>) event);
}
}
/*
* (non-Javadoc)
* #see org.springframework.context.ApplicationEventPublisher#publishEvent(java.lang.Object)
*/
public void publishEvent(Object event) {}
}
is this a bug or am i missing something here ? Using 2.0.5.Release version of spring data mongo.
Your config looks fine and the listener should be called, MongoTemplate implements ApplicationContextAware and hence after construction it sets eventPublisher to the applicationContext

JSF PrimeFaces ajax request after logout and session invalidation

In my Spring Boot1.2.7/JSF2.2.12/PrimeFaces5.2/Tomcat 8 application I'm trying to implement redirect to login page after AJAX call on a website where /logout has been performed.
In order to do this I have added JsfRedirectStrategy:
/**
* Inspired by <a href=
* "http://stackoverflow.com/questions/10143539/jsf-2-spring-security-3-x-and-richfaces-4-redirect-to-login-page-on-session-tim">StackOverflow.com</a>
* and by <a href=http://www.icesoft.org/wiki/display/ICE/Spring+Security#SpringSecurity-Step4%3AConfigureYourSpringSecurityredirectStrategy">
* Spring Security 3 and ICEfaces 3 Tutorial</a>.
*
* #author banterCZ
*/
public class JsfRedirectStrategy implements InvalidSessionStrategy {
final static Logger logger = LoggerFactory.getLogger(JsfRedirectStrategy.class);
private static final String FACES_REQUEST_HEADER = "faces-request";
private String invalidSessionUrl;
/**
* {#inheritDoc}
*/
#Override
public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
boolean ajaxRedirect = "partial/ajax".equals(request.getHeader(FACES_REQUEST_HEADER));
if (ajaxRedirect) {
String contextPath = request.getContextPath();
String redirectUrl = contextPath + invalidSessionUrl;
logger.debug("Session expired due to ajax request, redirecting to '{}'", redirectUrl);
String ajaxRedirectXml = createAjaxRedirectXml(redirectUrl);
logger.debug("Ajax partial response to redirect: {}", ajaxRedirectXml);
response.setContentType("text/xml");
response.getWriter().write(ajaxRedirectXml);
} else {
String requestURI = getRequestUrl(request);
logger.debug(
"Session expired due to non-ajax request, starting a new session and redirect to requested url '{}'",
requestURI);
request.getSession(true);
response.sendRedirect(requestURI);
}
}
private String getRequestUrl(HttpServletRequest request) {
StringBuffer requestURL = request.getRequestURL();
String queryString = request.getQueryString();
if (StringUtils.hasText(queryString)) {
requestURL.append("?").append(queryString);
}
return requestURL.toString();
}
private String createAjaxRedirectXml(String redirectUrl) {
return new StringBuilder().append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
.append("<partial-response><redirect url=\"").append(redirectUrl)
.append("\"></redirect></partial-response>").toString();
}
public void setInvalidSessionUrl(String invalidSessionUrl) {
this.invalidSessionUrl = invalidSessionUrl;
}
}
This is my WebSecurityConfig
#Configuration
#EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
private UserDetailsServiceImpl userDetailsService;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService);
}
#Override
#Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
#Override
protected void configure(HttpSecurity http) throws Exception {
// #formatter:off
http
.addFilterBefore(sessionManagementFilter(), AnonymousAuthenticationFilter.class)
.csrf().disable()
.authorizeRequests()
.antMatchers("/invite.xhtml").permitAll()
.antMatchers("/forgotpassword.xhtml").permitAll()
.antMatchers("/resetpwd.xhtml").permitAll()
.antMatchers("/admin/**").hasRole(Roles.ROLE_ADMIN.getSpringSecName())
.antMatchers("/**").authenticated()
.antMatchers("/actuator/**").permitAll()
.and()
.formLogin()
.loginPage("/login.xhtml").permitAll()
//.failureUrl("/login?error").permitAll()
.and()
.logout()
.logoutUrl("/logout")
.logoutRequestMatcher( new AntPathRequestMatcher("/logout"))
.logoutSuccessUrl("/login.xhtml")
.invalidateHttpSession(true)
.deleteCookies("JSESSIONID")
.permitAll();
http.headers().frameOptions().disable();
// #formatter:on
}
#Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers("/javax.faces.resource/**");
}
#Bean
public SessionManagementFilter sessionManagementFilter() {
SessionManagementFilter sessionManagementFilter = new SessionManagementFilter(httpSessionSecurityContextRepository());
sessionManagementFilter.setInvalidSessionStrategy(jsfRedirectStrategy());
return sessionManagementFilter;
}
public HttpSessionSecurityContextRepository httpSessionSecurityContextRepository() {
return new HttpSessionSecurityContextRepository();
}
#Bean
public JsfRedirectStrategy jsfRedirectStrategy() {
JsfRedirectStrategy jsfRedirectStrategy = new JsfRedirectStrategy();
jsfRedirectStrategy.setInvalidSessionUrl("/login.xhtml");
return jsfRedirectStrategy;
}
}
This is logout link:
<div id="LogoutContainer" class="PFTopLinks floatRight boldFont">
<h:form rendered="#{not empty request.remoteUser}">
<h:graphicImage name="main/images/pfPush.svg" />
<h:outputLink value="${pageContext.request.contextPath}/logout">
<span class="PFDarkText">Logout</span>
</h:outputLink>
</h:form>
</div>
The problem: Right now JsfRedirectStrategy.onInvalidSessionDetected is never invoked on AJAX JSF call because request.isRequestedSessionIdValid() in SessionManagementFilter.doFilter() always returns true.
There after logout I have an instance of org.apache.catalina.session.StandardSessionFacade
Whats wrong with my code ?
I have reimplemented this approach with a following code(based on this topic http://forum.primefaces.org/viewtopic.php?f=3&t=33380):
I have added AjaxTimeoutPhaseListener phase listener:
public class AjaxTimeoutPhaseListener implements PhaseListener {
private static final long serialVersionUID = 2639152532235352192L;
public static Logger logger = LoggerFactory.getLogger(AjaxTimeoutPhaseListener.class);
#Override
public void afterPhase(PhaseEvent ev) {
}
#Override
public void beforePhase(PhaseEvent ev) {
FacesContext fc = FacesUtils.getContext();
RequestContext rc = RequestContext.getCurrentInstance();
HttpServletResponse response = FacesUtils.getResponse();
HttpServletRequest request = FacesUtils.getRequest();
if (FacesUtils.getExternalContext().getUserPrincipal() == null) {
if (FacesUtils.getExternalContext().isResponseCommitted()) {
// redirect is not possible
return;
}
try {
if (((rc != null && rc.isAjaxRequest())
|| (fc != null && fc.getPartialViewContext().isPartialRequest()))
&& fc.getResponseWriter() == null && fc.getRenderKit() == null) {
response.setCharacterEncoding(request.getCharacterEncoding());
RenderKitFactory factory = (RenderKitFactory) FactoryFinder
.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
RenderKit renderKit = factory.getRenderKit(fc,
fc.getApplication().getViewHandler().calculateRenderKitId(fc));
ResponseWriter responseWriter = renderKit.createResponseWriter(response.getWriter(), null,
request.getCharacterEncoding());
responseWriter = new PartialResponseWriter(responseWriter);
fc.setResponseWriter(responseWriter);
FacesUtils.redirect("/login.xhtml");
}
} catch (IOException ex) {
StringBuilder error = new StringBuilder("Redirect to the specified page '");
error.append("/login.xhtml");
error.append("' failed");
logger.error(error.toString(), ex);
throw new FacesException(ex);
}
} else {
return; // This is not a timeout case . Do nothing !
}
}
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
}
Also added FacesUtils class(extracted from OmniFaces lib):
public class FacesUtils {
public static Logger logger = LoggerFactory.getLogger(FacesUtils.class);
/**
* Returns the current faces context.
* <p>
* <i>Note that whenever you absolutely need this method to perform a general task, you might want to consider to
* submit a feature request to OmniFaces in order to add a new utility method which performs exactly this general
* task.</i>
* #return The current faces context.
* #see FacesContext#getCurrentInstance()
*/
public static FacesContext getContext() {
return FacesContext.getCurrentInstance();
}
/**
* Returns the HTTP servlet response.
* <p>
* <i>Note that whenever you absolutely need this method to perform a general task, you might want to consider to
* submit a feature request to OmniFaces in order to add a new utility method which performs exactly this general
* task.</i>
* #return The HTTP servlet response.
* #see ExternalContext#getResponse()
*/
public static HttpServletResponse getResponse() {
return getResponse(getContext());
}
/**
* {#inheritDoc}
* #see Faces#getResponse()
*/
public static HttpServletResponse getResponse(FacesContext context) {
return (HttpServletResponse) context.getExternalContext().getResponse();
}
/**
* Returns the HTTP servlet request.
* <p>
* <i>Note that whenever you absolutely need this method to perform a general task, you might want to consider to
* submit a feature request to OmniFaces in order to add a new utility method which performs exactly this general
* task.</i>
* #return The HTTP servlet request.
* #see ExternalContext#getRequest()
*/
public static HttpServletRequest getRequest() {
return getRequest(getContext());
}
/**
* {#inheritDoc}
* #see Faces#getRequest()
*/
public static HttpServletRequest getRequest(FacesContext context) {
return (HttpServletRequest) context.getExternalContext().getRequest();
}
/**
* Returns the current external context.
* <p>
* <i>Note that whenever you absolutely need this method to perform a general task, you might want to consider to
* submit a feature request to OmniFaces in order to add a new utility method which performs exactly this general
* task.</i>
* #return The current external context.
* #see FacesContext#getExternalContext()
*/
public static ExternalContext getExternalContext() {
return getContext().getExternalContext();
}
/**
* Returns the HTTP request context path. It's the webapp context name, with a leading slash. If the webapp runs
* on context root, then it returns an empty string.
* #return The HTTP request context path.
* #see ExternalContext#getRequestContextPath()
*/
public static String getRequestContextPath() {
return getRequestContextPath(getContext());
}
/**
* {#inheritDoc}
* #see Faces#getRequestContextPath()
*/
public static String getRequestContextPath(FacesContext context) {
return context.getExternalContext().getRequestContextPath();
}
/**
* Does a regular or ajax redirect.
*/
public static void redirect(String redirectPage) throws FacesException {
checkViewRoot(FacesUtils.getContext(), FacesUtils.getRequestContextPath());
FacesContext fc = FacesUtils.getContext();
ExternalContext ec = fc.getExternalContext();
try {
if (ec.isResponseCommitted()) {
// redirect is not possible
return;
}
// fix for renderer kit (Mojarra's and PrimeFaces's ajax redirect)
if ((RequestContext.getCurrentInstance().isAjaxRequest() || fc.getPartialViewContext().isPartialRequest())
&& fc.getResponseWriter() == null && fc.getRenderKit() == null) {
ServletResponse response = (ServletResponse) ec.getResponse();
ServletRequest request = (ServletRequest) ec.getRequest();
response.setCharacterEncoding(request.getCharacterEncoding());
RenderKitFactory factory = (RenderKitFactory) FactoryFinder
.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
RenderKit renderKit = factory.getRenderKit(fc,
fc.getApplication().getViewHandler().calculateRenderKitId(fc));
ResponseWriter responseWriter = renderKit.createResponseWriter(response.getWriter(), null,
request.getCharacterEncoding());
fc.setResponseWriter(responseWriter);
}
ec.redirect(ec.getRequestContextPath() + (redirectPage != null ? redirectPage : ""));
} catch (IOException e) {
logger.error("Redirect to the specified page '" + redirectPage + "' failed");
throw new FacesException(e);
}
}
public static void checkViewRoot(FacesContext ctx, String viewId) {
if (ctx.getViewRoot() == null) {
UIViewRoot viewRoot = ctx.getApplication().getViewHandler().createView(ctx, viewId);
if (viewRoot != null) {
ctx.setViewRoot(viewRoot);
}
}
}
}
also added following lines to faces-config.xml:
<lifecycle>
<phase-listener>com.domain.AjaxTimeoutPhaseListener</phase-listener>
</lifecycle>
Now everything works fine

How to use CodePro Analytix with Spring MVC project for jUnit generation?

We are evaluating CodePro analytix to generate jUnits. We are working on a web project in spring3.0. As of now CodePro is generating useless jUnits. It generates identical testcase. ( I have already specified spring-test.jar as the manual suggests ).
If you have used this tool for jUnit generation in Spring project, then please help. I assume we have to specify our spring-configuration xml somewhere or else how it will get to know about DI. Also, we might require to mock few of the required object, not sure though.
Once done the codepro plugin setup, Right Click on the class or package ->select generate Junit test cases.
It will generate test class for your class. Then inside setup method you have to set the spring config XML.
ServiceFacadeImpl.Java:
public class ServiceFacadeImpl implements ServiceFacade {
private ServiceDAO serviceDAO;
#Override
public ServiceVO getService(int serviceId) {
return (ServiceVO) serviceDAO.getById(serviceId);
}
#Override
public List<ServiceVO> getServices() {
String criteria = " WHERE activeSwitch='Y' ORDER BY lastUpdatedDt DESC";
return (List<ServiceVO>) serviceDAO.getAll(criteria);
}
/**
* #return the serviceDAO
*/
public ServiceDAO getServiceDAO() {
return serviceDAO;
}
/**
* #param serviceDAO
* the serviceDAO to set
*/
public void setServiceDAO(ServiceDAO serviceDAO) {
this.serviceDAO = serviceDAO;
}
}
*Codepro Generated Class *
ServiceFacadeImplTest.java:
public class ServiceFacadeImplTest {
private ServiceFacadeImpl serviceFacadeImpl;
ServiceFacadeImpl fixture = null;
/**
* Run the ServiceVO getService(int) method test.
*
* #throws Exception
*
* #generatedBy CodePro at 7/7/13 10:34 PM
*/
#Test
public void testGetService_1() throws Exception {
List<ServiceVO> result = fixture.getServices();
int serviceId = 0;
ServiceVO result1 = fixture.getService(1);
assertNotNull(result1);
}
/**
* Run the List<ServiceVO> getServices() method test.
*
* #throws Exception
*
* #generatedBy CodePro at 7/7/13 10:34 PM
*/
#Test
public void testGetServices_1() throws Exception {
List<ServiceVO> result = fixture.getServices();
assertNotNull(result);
}
/**
* Perform pre-test initialization.
*
* #throws Exception
* if the initialization fails for some reason
*
* #generatedBy CodePro at 7/7/13 10:34 PM
*/
#SuppressWarnings("resource")
#Before
public void setUp() throws Exception {
this.setServiceFacadeImpl((ServiceFacadeImpl) new ClassPathXmlApplicationContext(
"applicationContext-facade.xml").getBean("serviceFacade"));
fixture = this.getServiceFacadeImpl();
}
/**
* Perform post-test clean-up.
*
* #throws Exception
* if the clean-up fails for some reason
*
* #generatedBy CodePro at 7/7/13 10:34 PM
*/
#After
public void tearDown() throws Exception {
// Add additional tear down code here
}
/**
* Launch the test.
*
* #param args
* the command line arguments
*
* #generatedBy CodePro at 7/7/13 10:34 PM
*/
public static void main(String[] args) {
new org.junit.runner.JUnitCore().run(ServiceFacadeImplTest.class);
}
/**
* #return the serviceFacadeImpl
*/
public ServiceFacadeImpl getServiceFacadeImpl() {
return serviceFacadeImpl;
}
/**
* #param serviceFacadeImpl
* the serviceFacadeImpl to set
*/
public void setServiceFacadeImpl(ServiceFacadeImpl serviceFacadeImpl) {
this.serviceFacadeImpl = serviceFacadeImpl;
}
}
In the setup() method, we have to load the spring config xml, the above one i have loaded applicationContext-facade.xml

Resources