My project is to processing data from my database. I got an input text for entering xml data(plain text format), this part works but now I need to process this data to extract the words I need and push them into a Graph (vis.js). I'm using spring-boot 2.1.4 and angular 8. Thanks in advance for investigating ! love
I'have not trying anything, I only searched in the web. But I need you for guide me. If you have source or anything. It could be nice !
I tried this in google : "data processing spring boot angular"
and this : creating-rest-api-using-spring-boot
My database
In springboot:
My Graph.java:
#Entity(name = "graphiques")
#Data
#NoArgsConstructor
#AllArgsConstructor
public class Graph {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name ="id")
private Long id;
#Column(name ="xml")
private String xml;
#Override
public String toString() {
return "GraphQuery{" +
"id" + id +
", xml ='" + xml + '\'' +
'}';
}
}
My GraphRepository.java:
#Repository
public interface GraphRepository extends CrudRepository<Graph, Long> {
}
My GraphController.java:
#RestController
#RequestMapping(value = "/graph")
#ResponseStatus(HttpStatus.CREATED)
public class GraphController {
private GraphRepository graphRepository;
#Autowired
GraphController(GraphRepository graphRepository){
this.graphRepository = graphRepository;
}
#PostMapping
public Graph post(#RequestBody Graph graph){
return this.graphRepository.save(graph);
}
//Ajout du xml dans la base
#GetMapping("/{graph_id}")
public Optional<Graph> get(#PathVariable Long graph_id) {
return this.graphRepository.findById(graph_id);
}
In angular:
My graph.component.ts
#ViewChild('siteConfigNetwork', { static: true }) networkContainer: ElementRef;
constructor() { }
ngOnInit() {
this.initGraph();
}
initGraph() {
let nodes = [
{ id: 1, label: 'Node 1' },
{ id: 2, label: 'Node 2' },
{ id: 3, label: 'Node 3' },
{ id: 4, label: 'Node 4' },
{ id: 5, label: 'Node 5' }
];
let edges = [
{ from: 1, to: 3 },
{ from: 1, to: 2 },
{ from: 2, to: 4 },
{ from: 2, to: 5 }
];
let container = this.networkContainer.nativeElement;
let data = {
nodes: nodes,
edges: edges
}
let options = {};
let network = new vis.Network(container, data, options);
}
I want my data be linked when multiple tag("to" and "from") are in one tag("note"). So the tag note will be the node and edges must start from this node and be linked to the node "to" and "from".
I don't know if I'm clear. Be indulgent I'm a little french who begin's in dev.
Thank's again for helping me !
Related
I'm developing APIs for an exam project, but I wanted their responses to be consistently using a wrapping class on all of them (Telegram Bot API style for those who know them).
So, for example, having these two classes:
public class User {
public int id;
public String name;
}
public class Item {
public int id;
public String itemName;
public User owner;
}
What Spring returns to me is this output:
{
"id": 1,
"itemName": "theItem",
"owner": {
"id": 2,
"name": "theUser"
}
}
What I want instead is for this output to be returned:
{
"ok": true,
"data": {
"id": 1,
"itemName": "theItem",
"owner": {
"id": 2,
"name": "theUser"
}
}
}
Maybe using a class wrapper like this:
public class ResponseWrapper<T> {
public boolean ok;
public T data;
}
Is it possible to do this?
I understand you need a global setting to convert all your responses into a standard one. For this you can implement ResponseBodyAdvice and have a common structure for all your api responses. Refer this link for a detailed example
Edit: For spring-webflux you can extend ResponseBodyResultHandler and override handleResult. An example is given in this answer
I thank #JustinMathew for the help, at the end, in my case (using Spring WebFlux with Kotlin), the ResponseBodyResultHandler class was more useful to me.
// File: /MicroserviceApplication.kt
#SpringBootApplication
class MicroserviceApplication {
#Autowired
lateinit var serverCodecConfigurer: ServerCodecConfigurer
#Autowired
lateinit var requestedContentTypeResolver: RequestedContentTypeResolver
#Bean
fun responseWrapper(): ResponseWrapper = ResponseWrapper(
serverCodecConfigurer.writers, requestedContentTypeResolver
)
}
// File: /wrapper/model/Response.kt
data class Response<T>(
val ok: Boolean,
val data: T?,
val error: Error? = null
) {
data class Error(
val value: HttpStatus,
val message: String?
)
}
// File: /wrapper/ResponseWrapper.kt
class ResponseWrapper(writers: List<HttpMessageWriter<*>>, resolver: RequestedContentTypeResolver) :
ResponseBodyResultHandler(writers, resolver) {
override fun supports(result: HandlerResult): Boolean =
(result.returnType.resolve() == Mono::class.java)
|| (result.returnType.resolve() == Flux::class.java)
#Throws(ClassCastException::class)
override fun handleResult(exchange: ServerWebExchange, result: HandlerResult): Mono<Void> {
val body = when (val value = result.returnValue) {
is Mono<*> -> value
is Flux<*> -> value.collectList()
else -> throw ClassCastException("The \"body\" should be Mono<*> or Flux<*>!")
}
.map { r -> Response(true, r, null) }
.onErrorMap { e ->
if (e !is Response.Error)
Response.Error(HttpStatus.INTERNAL_SERVER_ERROR, "Internal Server Error")
else e
}
.onErrorResume { e -> Mono.just(Response(false, null, e as Response.Error)) }
return writeBody(body, returnType, exchange)
}
companion object {
#JvmStatic
private fun methodForReturnType(): Mono<Response<Any>>? = null
private val returnType: MethodParameter = MethodParameter(
ResponseWrapper::class.java.getDeclaredMethod("methodForReturnType"), -1
)
}
Edit: I made of this answer a library for Spring WebFlux 2.7.3 here.
P.S. I also took a cue from this other question, which faces the same problem but with Java.
I use Angular as the front end of my application. For the backend I use glassfish. I currently use a Http GET verb to get a JSON object with an id and name and address. I only want to get the name of the object, how do I do that in a typescript file? How do I get the name of the newest added object of the rest server?
I want to get restaurantName from the object:
{ restaurantId: 1, restaurantName: 'Mcdonalds', restaurantAdres: 'Kalverstraat 5' },
Code that retrieves the object from the rest server:
ngOnInit() {
this.http.get('http://localhost:8080/aquadine-jee/resources/restaurant')
.subscribe(
val => {
const restStr = JSON.stringify(val);
console.log(restStr);
);
Backend code:
#GET
#Produces("application/json")
public Response all(){
List<Restaurant> all = repositoryService.getAllRestaurants();
return Response
.status(200)
.header("Access-Control-Allow-Origin", "*")
.entity(all)
.build();
}
public List<Restaurant> getAllRestaurants() {
EntityManager em = entityManagerFactory.createEntityManager();
List<Restaurant> restaurants = em.createQuery("SELECT r FROM Restaurant r").getResultList();
em.close();
return restaurants;
}
#Entity
#Table(name = "restaurant")
#NamedQueries({
#NamedQuery(name = "Restaurant.findOne", query = "select m from Restaurant m where m.id = :id"),
#NamedQuery(name = "Restaurant.getAll", query = "select m from Restaurant m")
})
public class Restaurant implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
// #Column(name="naam")
// #NotBlank
// private String naam;
// #NotBlank
String restaurantName;
// #NotBlank
String restaurantAdres;
int restaurantId;
public Restaurant(){
}
public Restaurant(int restaurantId, String restaurantName, String restaurantAdres) {
this.restaurantId = restaurantId;
this.restaurantName = restaurantName;
this.restaurantAdres = restaurantAdres;
}
First, I'd create a class and maybe an interface to give you strongly typed objects in your TypeScript:
Then you can return the object from your get request as that object and use that however you want like result.restaurantName
A quick mock of what that looks like (using a stub method instead of http) is here:
In short though:
the class and interface for Angular:
export interface IRestaurant {
restaurantId: number;
restaurantName: string;
restaurantAddres: string;
}
export class Restaurant implements IRestaurant {
restaurantId:number;
restaurantName:string;
restaurantAddres:string;
}
And then the component that gets the data via a method, and uses essentially the JSON as an object:
export class AppComponent {
favoriteRestaurant: IRestaurant;
retrieve(){
this.favoriteRestaurant = this.getRestaurant();
alert(this.favoriteRestaurant.restaurantName);
}
getRestaurant():IRestaurant {
var result: Restaurant = {
restaurantId: 1,
restaurantName: 'Mcdonalds',
restaurantAddres: 'Kalverstraat 5'
};
return result;
}
}
Making it more useful for you though, change the http.get method to something like this:
ngOnInit() {
this.http.get('http://localhost:8080/aquadine-jee/resources/restaurant')
.subscribe(
val:IRestaurant => {
this.favoriteRestaurant = val;
console.log(restStr.restaurantName);
);
You don't want to use JSON.stringify above, because that gives you a string!
Additionally, your restaurantAddress is mispelled, these would need to match exactly. So I would correct the backend.
I am planning to serialize list of JAXB objects to JSON response. Currently below is the format I am getting. In the below response I am seeing one more object in between is "systemInfoList" which actually is showing the array. Instead I want the dependent_systems_infos should directly show array []. Also if there is a single system info response also still it should should show in the array format. I am using the Jackson parser, cxf.
Format currently I am getting:
{
"dependent_systems_infos":{
"systemInfoList":[
{
"system_name":"PZ_Service",
"system_type":"Internal",
"service_infos":[
{
"service_name":"getPZAttributes",
"status":"DOWN",
"response_time_ms":50
}
]
},
{
"system_name":"OMS",
"system_type":"External",
"service_infos":[
{
"service_name":"CreateOrder",
"status":"UP",
"response_time_ms":2000
},
{
"service_name":"CancelOrder",
"status":"UP",
"response_time_ms":500
}
]
}
]
}
}
Format I need:
{
dependent_system_infos : [
{
system_name : 'OMS'
system_type: 'External'
services_infos: [
{
service_name : 'CreateOrder'
status : 'UP'
response_time_ms : 2000
},
{
service_name : 'CancelOrder'
status : 'UP'
response_time_ms : 2000
}
]
},
{
system_name : 'PZ_Service'
system_type: 'Internal'
services_infos: [
{
service_name : 'getPZAttributes'
status : 'UP'
response_time_ms : 2000
}
]
}
]
}
JAXB classes I wrote:
#XmlRootElement(name = "dependent_systems_infos")
#XmlAccessorType(XmlAccessType.FIELD)
public class ItineraryStatusResponse {
private List<SystemInfo> systemInfoList;
#XmlList
public List<SystemInfo> getSystemInfoList() {
return systemInfoList;
}
public void setSystemInfoList(List<SystemInfo> systemInfoList) {
this.systemInfoList = systemInfoList;
}
}
#XmlType(propOrder = {
"systemName",
"systemType",
"serviceInfoList"
})
#XmlAccessorType(XmlAccessType.FIELD)
public class SystemInfo {
#XmlElement(name = "system_name", required = true)
protected SystemName systemName;
#XmlElement(name = "system_type", required = true)
protected SystemType systemType;
#XmlElement(name = "service_infos", required = true)
protected List<ServiceInfo> serviceInfoList;
}
It would help to know how you're generating the output, but the main issue is that you are serializing a root object that contains a list when you really only want to serialize the list itself. What would you expect the outputted list to look like if ItineraryStatusResponse had other fields in it?
You can remove the #XmlRootElement annotation and mark the list as an element named "dependent_systems_infos":
#XmlAccessorType(XmlAccessType.FIELD)
public static class ItineraryStatusResponse {
private List<SystemInfo> systemInfoList;
#XmlElement(name = "dependent_systems_infos", required = true)
public List<SystemInfo> getSystemInfoList() {
return systemInfoList;
}
public void setSystemInfoList(List<SystemInfo> systemInfoList) {
this.systemInfoList = systemInfoList;
}
}
If you are doing the serialization yourself, another approach would be to drop the ItineraryStatusResponse object entirely (since it's just a wrapper around the list), and then serialize the list itself with SerializationFeature.WRAP_ROOT_VALUE = true and a root name you provide:
ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.WRAP_ROOT_VALUE, true);
AnnotationIntrospector introspector = new JaxbAnnotationIntrospector(TypeFactory.defaultInstance());
mapper.setAnnotationIntrospector(introspector);
ObjectWriter writer = mapper.writerWithDefaultPrettyPrinter().withRootName("dependent_systems_infos");
System.out.println(writer.writeValueAsString(systemInfoList));
Both of these approaches provide the desired output in my testing with Jackson 2.2.
I am building an app that uses Open Flash Chart 2. This chart is a flash object that accepts JSON with a specific structure.
"elements": [
{
"type": "bar_stack",
"colours": [
"#F19899",
"#A6CEE3"
],
"alpha": 1,
"on-show": {
"type": "grow-up",
"cascade": 1,
"delay": 0
},
...
I am using a simple anonymous type to return the JSON like so:
return Json(new
{
elements = new [] {
new
{
type = "bar_stack",
colours = colours.Take(variables.Count()),
alpha = 1,
on_show = new
{
type = "grow-up",
cascade = 1,
delay = 0
},
...
}
}
The problem is that several properties (like "on-show") use a dash and obviously I cannot use a dash when naming a property in C# code.
Is there a way to overcome this? Preferably without the need to declare a whole bunch of classes.
You can use a dictionary:
return Json(new {
elements = new [] {
new Dictionary<string, object>
{
{ "type", "bar_stack" },
{ "colours", new [] { "#F19899", "#A6CEE3" } },
{ "alpha", 1 },
{ "on-show", new
{
type = "grow-up",
cascade = 1,
delay = 0
} },
}
}
});
(Written in SO editor; I may have made some syntax errors, but you get the idea....)
Craig's solution is propably better, but in the meantime I implemented this:
public class UnderscoreToDashAttribute : ActionFilterAttribute
{
private readonly string[] _fixes;
public UnderscoreToDashAttribute(params string[] fixes)
{
_fixes = fixes;
}
public override void OnResultExecuting(ResultExecutingContext filterContext)
{
filterContext.HttpContext.Response.Filter = new ReplaceFilter(filterContext, s => _fixes.Aggregate(s, (current, fix) => current.Replace(fix, fix.Replace('_', '-'))));
}
public class ReplaceFilter : MemoryStream
{
private readonly Stream _stream;
private readonly Func<string, string> _filter;
public ReplaceFilter(ControllerContext filterContext, Func<string, string> filter)
{
_stream = filterContext.HttpContext.Response.Filter;
_filter = filter;
}
public override void Write(byte[] buffer, int offset, int count)
{
// capture the data and convert to string
var data = new byte[count];
Buffer.BlockCopy(buffer, offset, data, 0, count);
var s = _filter(Encoding.Default.GetString(buffer));
// write the data to stream
var outdata = Encoding.Default.GetBytes(s);
_stream.Write(outdata, 0, outdata.GetLength(0));
}
}
}
Then, if you decorate your action like so:
[UnderscoreToDash("on_show", "grid_colour")]
public JsonResult GetData()
It makes the appropriate "fixes".
P.S. That awesome moment when Resharper changes your code to Linq...
_fixes.Aggregate(s, (current, fix) => current.Replace(fix, fix.Replace('_', '-')))
I have a data structure BookCollection which has a Set of Books. Each book has a reference to the BookCollection that it's in. This is a standard one-to-many relationship. It works well on server side, but then I have to send it down to the client. The app uses Jackson ObjectMapper for serialization, set up as a Spring Bean. The problem, is that you can't trivially serialize a BookCollection and Books, since there are no references in standard JSON (and I do need standard JSON).
the current solution is to put #JsonIgnore on Book.collection field, or more advanced, #JsonManagedReference on BookCollection.books and #JsonBackReference on Book.collection. However this doesn't solve all my problems, some requests ask for a Book object, and want to get its BookCollection also.
Ultimately, I am looking for some way to tell the Serializer to only include each object once. Thus, a when I get a Book, the JSON would look something like this:
{
isbn: 125412416,
title: "Introduction to JSON",
collection: {
name: "Programming Books",
books: [
{
isbn: 18723425,
title: "Java for experts"
},
{
isbn: 82472347,
title: "C# and its extensions"
},
]
}
}
While "C# and it's extensions" and "Java for experts" also have a reference to the collection object, it is not serialized since it was serialized already. Also, the collection object doesn't include the "Introduction to JSON" book, since it was already serialized.
And when I ask for a BookCollection, I get this:
{
name: "Programming Book",
books: [
{
isbn: 125412416,
title: "Introduction to JSON"
},
{
isbn: 18723425,
title: "Java for experts"
},
{
isbn: 82472347,
title: "C# and its extensions"
},
]
}
Serialize fields once
While BookCollection serializes splendily, Book is a little confusing, since the catalog now has SOME books (missing the original). Even better would be to allow to specify to serialize each field once. Let Book.collection be allowed to serialize once
Serializing a Book will look like this:
{
isbn: 125412416,
title: "Introduction to JSON",
collection: {
name: "Programming Books",
books: [
{
isbn: 18723425,
title: "Java for experts"
},
{
isbn: 82472347,
title: "C# and its extensions"
},
{
isbn: 125412416,
title: "Introduction to JSON"
}
]
}
}
And serializng a book collection is similar:
{
name: "Programming Book",
books: [
{
isbn: 125412416,
title: "Introduction to JSON"
},
{
isbn: 18723425,
title: "Java for experts"
},
{
isbn: 82472347,
title: "C# and its extensions"
},
]
}
I recently encountered a similar problem: Jackson - serialization of entities with birectional relationships (avoiding cycles)
So the solution is to upgrade to Jackson 2.0, and add to classes the following annotation:
#JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class,
property = "#id")
public class SomeEntityClass ...
namespace ConsoleApplication4
{
public class Teacher
{
public int MyProperty { get; set; }
// [ScriptIgnore]
public ClassRoom working { get; set; }
}
public class ClassRoom
{
public ClassRoom()
{
}
public int sss { get; set; }
public int s2 { get; set; }
public int ddy { get; set; }
// [ScriptIgnore]
public Teacher teachers { get; set; }
}
class Program
{
static void Main(string[] args)
{
Console.ForegroundColor = ConsoleColor.Green;
ClassRoom #new = new ClassRoom();
Teacher #teacher = new Teacher();
#new.teachers = teacher;
#teacher.working = #new;
JavaScriptSerializer serializer = new JavaScriptSerializer();
List< ClassRoom> classrooms = new List<ClassRoom>();
classrooms.Add(#new);
classrooms.Add(#new);
classrooms.Add(#new);
classrooms.Add(#new);
classrooms.Add(#new);
var result = (from n in classrooms
select n).ToList();//tolist() to convert IEnumrable to list can be modified
for (int i = 0; i < result.Count; i++)
{
result[i].teachers.working = null;//making all child's parents =null to prevent circular refrencing
}
Console.WriteLine(serializer.Serialize(result));
Console.ReadLine();
}
}
}
I think this solution would solve your problem
it solved mine
( result[i].teachers.working = null;)
make the property that causes circular reference =null;