How to Configure a valid #ResponseBody for a POST with spring and angular 4 - spring

I'm getting this error:
core.js:1448 ERROR SyntaxError: Unexpected end of JSON input
I think the error is in the response , how i can correct create a #responseBody
for the front to understand that the object in the back end is created properly
the input is (license:"gd345") without the parentheses
Component file:
import { Component, OnInit } from '#angular/core';
import { Http, Headers } from '#angular/http';
#Component({
selector: 'posts',
templateUrl: './posts.component.html',
styleUrls: ['./posts.component.css']
})
export class PostsComponent {
posts: any[];
letter: any;
constructor(private http: Http) {
http.get('http://localhost:8183/api/vehiculespark')
.subscribe(response => {
this.posts = response.json();
});
}
createPost(input: HTMLInputElement) {
debugger;
let post = { license: input.value };
this.letter = post;
const headers = new Headers({ 'Content-Type': 'application/json' });
this.http.post('http://localhost:8183/api/vehicules', this.letter, { headers: headers })
.subscribe(response => {
console.log(response.json())
});
debugger;
}
}
spring Controller:
package com.api.kingspark.parking.controller;
import com.api.kingspark.parking.domain.Tickect;
import com.api.kingspark.parking.domain.Vehicule;
import com.api.kingspark.parking.repositories.TicketRepository;
import com.api.kingspark.parking.repositories.VehiculoRepository;
import com.api.kingspark.parking.services.PorteroServices;
import org.reactivestreams.Publisher;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.List;
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import static org.springframework.http.MediaType.APPLICATION_XML_VALUE;
#RestController
public class ParkingController {
private PorteroServices porteroServices;
private final VehiculoRepository vehiculoRepository;
private final TicketRepository ticketRepository;
public ParkingController(PorteroServices porteroServices, VehiculoRepository vehiculoRepository, TicketRepository ticketRepository) {
this.porteroServices = porteroServices;
this.vehiculoRepository = vehiculoRepository;
this.ticketRepository = ticketRepository;
}
#CrossOrigin
#GetMapping("/api/vehiculespark")
List<Tickect> listIn(){
return porteroServices.getInVehicules();
}
#GetMapping("/api/vehicules")
Flux<Vehicule> listAll(){
return vehiculoRepository.findAll();
}
#GetMapping("/api/vehicules/{id}")
Mono<Vehicule> getById(#PathVariable String id){
return vehiculoRepository.findById(id);
}
#CrossOrigin
#ResponseStatus(HttpStatus.CREATED)
#PostMapping(value = "/api/vehicules",consumes="application/json",produces={"application/json","application/xml"})
#ResponseBody
Mono<Void> createVehicule(#RequestBody Publisher<Vehicule> carstream){
Vehicule ca= Mono.fromDirect(carstream).cache().block();
return porteroServices.saveVehicule(ca);
//return ResponseEntity.created(location).build();
}
#PutMapping("/api/vehicules/{id}")
Mono<Tickect> update(#PathVariable String id, #RequestBody Vehicule vehicule){
return ticketRepository.save(porteroServices.drawVehicule(id));
}
}

Related

Modify response body in Spring Cloud gateway Post Filter

I want to fetch the response received from microservice in gateway and add that response to a new ConsumerResponse Object and set that as the new response to my UI in Post Filter of Gateway.
Say my response from microservice is a ResponseEntity of Object, Json Object like below,
{
"userDetails": {
"userId": 24,
"userName": "ABC",
"description": "ABC from ZZZ",
"registrationStatus": "REGISTERED",
"registrationTime": [
2022,
5,
23,
21,
17,
41,
465000000
],
"lastUpdatedTime": [
2022,
5,
23,
21,
17,
41,
465000000
]
}
}
Below is my ConsumerResponse Class, in which i want to set the above Json data in T data,
#JsonInclude(JsonInclude.Include.NON_NULL)
#Data
public class ConsumerResponse implements Serializable {
private static final long serialVersionUID = 1L;
private ConsumerResponse() {}
public static <T> ResponseEntity<ResponseEnvelope<Object>> ok(
T data, String apiVersion, Status status, HttpStatus httpStatus) {
return ResponseEntity.status(httpStatus)
.body(ResponseEnvelope.builder().apiVersion(apiVersion).data(data).status(status).build());
}
}
Below is my Gateway Filter class,
Took reference from this link How to get Original response body in Spring cloud gateway (Webflux) Post filter
In the above link, its creating a new String response body, but i want the response received from the microservice.
package org.xyz.gateway.filter;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.stream.Collectors;
import org.reactivestreams.Publisher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DefaultDataBuffer;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.http.server.reactive.ServerHttpResponseDecorator;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
#Component
public class AuthFilter implements GlobalFilter {
private final Logger logger = LoggerFactory.getLogger(AuthFilter.class);
#Autowired
private IdService idService;
#Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// code to fetch id from request
MyResult response = idService.getEntitlements(id);
ArrayList<String> rolesList = response.getRoles()
.values()
.stream()
.distinct()
.collect(Collectors.toCollection(ArrayList::new));
ServerHttpRequest httpRequest = exchange.getRequest()
.mutate()
.header("id", id)
.header("roles", rolesList.toString())
.build();
ServerWebExchange mutatedExchange = exchange
.mutate()
.request(httpRequest)
.build();
return chain.filter(mutatedExchange).then(Mono.fromRunnable(() -> {
ServerHttpResponse serverHttpResponse = exchange.getResponse();
HttpStatus responseStatus = serverHttpResponse.getStatusCode();
DataBuffer dataBuffer = null;
String path = exchange.getRequest().getPath().toString();
ServerHttpRequest serverHttpRequest = exchange.getRequest();
DataBufferFactory dataBufferFactory = serverHttpResponse.bufferFactory();
ServerHttpResponseDecorator decoratedResponse = getDecoratedResponse(path, serverHttpResponse, serverHttpRequest, dataBufferFactory);
try {
dataBuffer = dataBufferFactory.wrap(
new ObjectMapper().writeValueAsBytes(
// need to set the response data here in ConsumerResponse Object below
ConsumerResponse.ok(decoratedResponse.toString(), GatewayConstants.VERSION, Status.OK, responseStatus)));
} catch (JsonProcessingException e) {
dataBuffer = serverHttpResponse.bufferFactory().wrap("".getBytes());
}
logger.info("decoratedResponse = {}", decoratedResponse);
exchange.getResponse().getHeaders().setContentType(MediaType.APPLICATION_JSON);
serverHttpResponse.getHeaders().setContentLength(decoratedResponse.toString().length());
serverHttpResponse.writeWith(Mono.just(dataBuffer)).subscribe();
exchange.mutate().response(serverHttpResponse).build();
}));
}
private ServerHttpResponseDecorator getDecoratedResponse(String path, ServerHttpResponse response, ServerHttpRequest request, DataBufferFactory dataBufferFactory) {
return new ServerHttpResponseDecorator(response) {
#Override
public Mono<Void> writeWith(final Publisher<? extends DataBuffer> body) {
logger.info("writeWith entering(...)---> with body = {} ", body);
if (body instanceof Flux) {
logger.info("Body is Flux");
Flux<? extends DataBuffer> fluxBody = (Flux<? extends DataBuffer>) body;
return super.writeWith(fluxBody.buffer().map(dataBuffers -> {
DefaultDataBuffer joinedBuffers = new DefaultDataBufferFactory().join(dataBuffers);
byte[] content = new byte[joinedBuffers.readableByteCount()];
joinedBuffers.read(content);
String responseBody = new String(content, StandardCharsets.UTF_8);//MODIFY RESPONSE and Return the Modified response
logger.debug("requestId: {}, method: {}, url: {}, \nresponse body :{}", request.getId(), request.getMethodValue(), request.getURI(), responseBody);
return dataBufferFactory.wrap(responseBody.getBytes());
})).onErrorResume(err -> {
logger.error("error while decorating Response: {}",err.getMessage());
return Mono.empty();
});
}
return super.writeWith(body);
}
};
}
}
Any help would be greatly appreciated.
Thanks in advance.

Hystrix Command property ignoreExceptions is not working expectedly

Using Hystrix command to invoke a default functionality and also have an API exception handler which is handling the exceptions and letting user/client know about the error that happened but while my server is UP, #HystrixCommand function is still getting called while my custom exception handler is being ignored instead of using ignoreExceptions property of #HystrixCommand annotation.
Please guide me how to make this work.
package com.example.demo.controller;
import java.util.List;
import javax.validation.ConstraintViolationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.TypeMismatchException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.example.demo.exception.FactorNotCreatedException;
import com.example.demo.exception.NotFoundException;
import com.example.demo.feignClient.ConversionFactorProxyClient;
import com.example.demo.model.ConversionFactor;
import com.example.demo.model.CurrencyConversion;
import com.example.demo.model.FactorResponse;
import com.example.demo.service.ConvertService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixException;
import feign.FeignException;
#RestController
public class ConvertCurrencyController {
private Logger logger = LoggerFactory.getLogger(this.getClass());
#Autowired
private ConversionFactorProxyClient cnvFacCl;
#Autowired
private ConvertService convertServ;
#GetMapping(value = "/currency-converter/from/{from}/to/{to}/quantity/{quantity}")
#HystrixCommand(fallbackMethod = "fallbackConvertCurrency")
public ResponseEntity<?> convertCurrency(#PathVariable String from, #PathVariable String to,
#PathVariable double quantity) {
logger.info("Inside convertCurrency() :: get Conversion factor ");
FactorResponse fr = cnvFacCl.getConversionFactor(from, to).getBody();
logger.info("{}", fr);
return ResponseEntity.ok(convertServ.getCurrencyConverted(from, to, fr, quantity));
}
#PostMapping(value = "/add_exchange_detail")
#HystrixCommand(fallbackMethod = "fallbackAddConversionFactor",
ignoreExceptions = { FactorNotCreatedException.class,
HttpMessageNotReadableException.class, MissingPathVariableException.class,
TypeMismatchException.class, MethodArgumentNotValidException.class,
ConstraintViolationException.class,
HttpRequestMethodNotSupportedException.class, NotFoundException.class,
FeignException.class},
raiseHystrixExceptions =
{HystrixException.RUNTIME_EXCEPTION} )
public ResponseEntity<?> addConversionFactor(#RequestBody ConversionFactor cf) {
;
logger.info("Inside addConversionFactor() :: add conversion factory for a country ");
List<ConversionFactor> list = cnvFacCl.addConversionFactor(cf).getBody();
return ResponseEntity.ok(list);
}
// ******************************FALLBACK Methods*****************************************
#SuppressWarnings("unused")
private ResponseEntity<?> fallbackConvertCurrency(#PathVariable String from, #PathVariable String to, #PathVariable double quantity) {
return ResponseEntity.ok(new CurrencyConversion(from, to, 0.00, quantity, 0.00));
}
#SuppressWarnings("unused")
private ResponseEntity<?> fallbackAddConversionFactor(#RequestBody ConversionFactor cf){
return ResponseEntity.ok(new ConversionFactor(0000l, "US", "IN", 75.64));
}
} /*
inside exception handler class */
package com.example.demo.exception;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolationException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import com.example.demo.feignClient.model.ApiException;
import feign.FeignException;
//import feign.Response;
#RestControllerAdvice
public class GlobalExceptionHandler {
//incase content is not created due to some internal error
#ExceptionHandler(value = {FactorNotCreatedException.class})
public ResponseEntity<Object> handleFactorNotCreatedException(FactorNotCreatedException ex){
HttpStatus error = HttpStatus.INTERNAL_SERVER_ERROR;
int status = error.value();
ApiException apiException = new ApiException
(
ZonedDateTime.now(ZoneId.of("Asia/Kolkata")),
status,
error,
ex.getMessage()
);
return new ResponseEntity<>(apiException, error);
}
//incase content not found
#ExceptionHandler(value = {NotFoundException.class})
public ResponseEntity<Object> handleNotFoundException(NotFoundException ex){
HttpStatus error = HttpStatus.NOT_FOUND;
int status = error.value();
ApiException apiException = new ApiException
(
ZonedDateTime.now(ZoneId.of("Asia/Kolkata")),
status,
error,
ex.getMessage()
);
return new ResponseEntity<>(apiException, error);
}
#ExceptionHandler(FeignException.class)
public ResponseEntity<Object> handleFeignStatusException(FeignException e, HttpServletResponse response) {
// response.setStatus(e.status());
int status = e.status();
HttpStatus error = HttpStatus.resolve(status);
ApiException apiException = new ApiException
(
ZonedDateTime.now(ZoneId.of("Asia/Kolkata")),
status,
error,
e.getMessage()
);
return new ResponseEntity<>(apiException, error);
}
//incase of updation, constraint voilation (i.e. #PathVariable and #Requestbody)
#ExceptionHandler({
HttpMessageNotReadableException.class,
MissingPathVariableException.class,
TypeMismatchException.class,
MethodArgumentNotValidException.class,
ConstraintViolationException.class,
HttpRequestMethodNotSupportedException.class
})
public ResponseEntity<Object> handleBadRequestException(Exception ex){
HttpStatus error = null;
if(ex instanceof HttpRequestMethodNotSupportedException) {
error = HttpStatus.METHOD_NOT_ALLOWED;
}
else {
error = HttpStatus.BAD_REQUEST;
}
int status = error.value();
ApiException apiException = new ApiException
(
ZonedDateTime.now(ZoneId.of("Asia/Kolkata")),
status,
error,
ex.getMessage()
);
return new ResponseEntity<>(apiException, error);
}
}

CORS policy issue while hitting the rest service(Spring Boot) from Angular5 Application

I am getting below error when I try to hit post service from Angular 5
Failed to load resource: the server responded with a status of 403
(Forbidden) Access to XMLHttpRequest at
'https://xxxx/xxxx/services/exportVarianceHome' from origin
'http://localhost:4200' has been blocked by CORS policy:
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
Below is my interceptor configuration in Angular 5
import { Injectable, NgModule} from '#angular/core';
import { Observable } from 'rxjs/Observable';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse} from '#angular/common/http';
import { HTTP_INTERCEPTORS } from '#angular/common/http';
import 'rxjs/add/operator/do';
#Injectable()
export class HttpsRequestInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const dupReq = req.clone({ headers: req.headers
.set('Access-Control-Allow-Origin','*')
.set('Content-Type', 'application/json')
.set('Authorization', 'Basic XXXXXXXXXXXXXXXXXXXXXX')
.set('Access-Control-Allow-Credentials','true') });
return next.handle(dupReq);
}
};
#NgModule({
providers: [
{ provide: HTTP_INTERCEPTORS, useClass: HttpsRequestInterceptor, multi: true }
]
})
And Angular Post Call
import { HttpClient} from '#angular/common/http';
constructor(private httpClient:HttpClient){
getLookupDetails();
}
getLookupDetails(){
this.httpClient.get(this.servicsUrl).subscribe(
(data:any) => {
console.log("JSON Response " + JSON.stringify(data));
}
)
}
And the Cross origin Setup at server side (SpringBoot)
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
#SpringBootApplication(scanBasePackages = {"com.controller.gtm"})
public class BrokerValidationApplication extends SpringBootServletInitializer implements WebMvcConfigurer {
#Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(BrokerValidationApplication.class);
}
public static void main(String[] args) {
SpringApplication.run(BrokerValidationApplication.class, args);
}
#Override
public void addCorsMappings(CorsRegistry registry) {
System.out.println(">=== Inside Cors Orgin Mapping addCorsMappings ===>");
registry.addMapping("/services/**")
.allowedOrigins("*")
.allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(4800);
}
}

Spring Get Mapping isn't working

I'm using Angular 4 with Spring backend. And.... My post request working fine. But the get request don't work. Look the code:
Frontend Service:
import { Injectable } from '#angular/core';
import 'rxjs/add/operator/toPromise';
import { Aluno } from '../models/aluno.model';
import {HttpClient} from "#angular/common/http";
import {Observable} from "rxjs/Observable";
#Injectable()
export class UserDataService {
private url = 'http://localhost:8080/getAluno';
constructor(private http: HttpClient){}
getAluno():Observable<Aluno>{
return this.http.get<Aluno>(this.url);
}
}
My spring backend provider:
import com.google.gson.Gson;
import com.ifmg.tcc.TADs.Aluno;
import com.ifmg.tcc.TADs.LoginObject;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
#CrossOrigin(origins = "http://localhost:4200")
#RestController
public class LoginProvider {
Gson gson = new Gson();
private boolean verify(LoginObject lo){
if(lo.getCode().equals("lucas") && lo.getPassword().equals("12345")){
return true;
}else{
return false;
}
}
#PostMapping(value = "login")
public ResponseEntity<?> verifyLogin(#RequestBody String login){
System.out.println("LOGIN REALIZADO");
LoginObject loginO = gson.fromJson(login, LoginObject.class);
if(verify(loginO)){
return new ResponseEntity<Boolean>(true,HttpStatus.OK);
}else{
return new ResponseEntity<Boolean>(false,HttpStatus.OK);
}
}
#GetMapping(value = "/getAluno")
public #ResponseBody ResponseEntity<?> getAluno() {
System.out.println("PEGANDO ALUNO");
Aluno aluno = new Aluno("0001","Lucas Alves de Faria","2018/1","10/12/1995",true,"luke#email.com","(37) 999597899","127.831.956-58","MG-19.319.265");
return new ResponseEntity<Aluno>(aluno, HttpStatus.OK);
}
}
The function verify login in my backend working fine(I'm call this function in other service). But the fontend don't call the other function (getAluno)
I'm not sure about what you mean when you say "But the fontend don't call the other function (getAluno)". You may look at your network calls and verify the calls.
In your front component which calls your service, you need to have a subscribe, something like this :
this.yourService.getAluno().subscribe(
(res: ResponseEntity) => {
this.aluno = res.json;
},
(res: ResponseEntity) => this.onError(res.json)
);
Hope it helps you.

How can I register JSR-356 Websocket in PAX-Web? (In bundle, not WAR)

I have a problem with the PAX-Web. I've tried to register a Websocket service as declrarative, but it is unaccessible from web. I've tried the given websocket-jsr356-6.0.3.war and it works fine. As I see the WAR file handles differently the org.osgi.service.http.HttpContext. I've tried the following scenarios:
Scenario 1 - OSGi R6 Whiteboard HTTP method
Creating a ServletContextHelper:
package hu.blackbelt.judo.common.rest.regular;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.osgi.service.http.context.ServletContextHelper;
import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
#Component(immediate = true)
#Service(ServletContextHelper.class)
#Properties(value = {
#Property(name = HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME, value = "chat"),
#Property(name = HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH, value = "/test")
})
public class ChatServletContext extends ServletContextHelper {
}
And adding the Websocket Endpoint:
package hu.blackbelt.judo.common.rest.regular;
import lombok.extern.slf4j.Slf4j;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import javax.websocket.EncodeException;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
#Component(immediate = true)
#Service(Object.class)
#Properties(value = {
#Property(name = HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT,
value = "=(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=chat)")
})
#Slf4j
public class ChatEndpoint {
public static final String ROOM = "room";
#OnOpen
public void onOpen(final Session session, #PathParam(ROOM) final String room) {
LOGGER.info("session openend and bound to room: " + room);
session.getUserProperties().put(ROOM, room);
}
#OnMessage
public void onMessage(final Session session, final ChatMessage chatMessage) {
String room = (String) session.getUserProperties().get(ROOM);
try {
for (Session s : session.getOpenSessions()) {
if (s.isOpen()
&& room.equals(s.getUserProperties().get(ROOM))) {
s.getBasicRemote().sendObject(chatMessage);
}
}
} catch (IOException | EncodeException e) {
LOGGER.warn("onMessage failed", e);
}
}
}
The logs show me that the Endpoint is catched. I've debugged and Pax-Web is registering it.
The log shows the following line:
2017-05-04 02:36:02,698 | INFO | Thread-70 | WebSocketTracker | 330 - org.ops4j.pax.web.pax-web-extender-whiteboard - 6.0.3 | found websocket endpoint!!
But the websocket is unaccessible with the following URL: ws://localost:8181/test/chat/testroom
Scenario 2 - Pax-Web properties on registered HttpContext (with JAX-RS it works)
Creating HttpContext instance: (Utilizing the OSGi given Helper abstract class):
package hu.blackbelt.judo.common.rest.regular;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.osgi.service.http.HttpContext;
import org.osgi.service.http.context.ServletContextHelper;
#Component(immediate = true)
#Service(HttpContext.class)
#Properties(value = {
#Property(name = "httpContext.id", value = "chat"),
#Property(name = "httpContext.path", value = "test")
})
public class ChatHttpContext extends ServletContextHelper implements HttpContext {
}
And the Websocket Endpoint:
package hu.blackbelt.judo.common.rest.regular;
import lombok.extern.slf4j.Slf4j;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
import javax.websocket.EncodeException;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
#SuppressWarnings({"checkstyle:missingctor", "checkstyle:illegaltoken"})
#Component(immediate = true)
#Service(Object.class)
#Properties(value = {
#Property(name = "httpContext.id", value = "chat")
})
#ServerEndpoint(value = "/chat/{room}", encoders = ChatMessageEncoder.class, decoders = ChatMessageDecoder.class)
#Slf4j
public class ChatEndpoint {
public static final String ROOM = "room";
#OnOpen
public void onOpen(final Session session, #PathParam(ROOM) final String room) {
LOGGER.info("session openend and bound to room: " + room);
session.getUserProperties().put(ROOM, room);
}
#OnMessage
public void onMessage(final Session session, final ChatMessage chatMessage) {
String room = (String) session.getUserProperties().get(ROOM);
try {
for (Session s : session.getOpenSessions()) {
if (s.isOpen()
&& room.equals(s.getUserProperties().get(ROOM))) {
s.getBasicRemote().sendObject(chatMessage);
}
}
} catch (IOException | EncodeException e) {
LOGGER.warn("onMessage failed", e);
}
}
}
But the websocket is unaccessible with the following URL: ws://localost:8181/test/chat/testroom
How can I achive that webcsocket be available? I do not want to repackage my bundle as WAB. Is there any way?

Resources