I have some doubts on how to perform some tasks I use jackson to create a JSON, after I encrypt I need to do it sent to a service that will consume this JSON, the problem is that the file size (physical) is 3,571 KB and I need to send in batches of at most 1,000KB
each one, as I am newcomer with springBoot and web in general I saw that I have to do something called pagination, is that it?
I have a Dto (students) a class manager where I make access to the database that returns me a list of students
Then I create json, step to base 64 to finally configure the header and make the request
studentList= StudantManager.getAllStudants(con);
int sizeRecords = studentList.size();
try {
students= useful.convertToJson(studentList);
studentsWithSecurity = useful.securityJson(students);
} catch (JsonProcessingException e) {
log.error(e.toString());
}
RestTemplate restTemplate = new RestTemplate();
String url = "myRestService";
HttpHeaders headers;
headers=getHeaders(sizeRecords,students);
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>(studentsWithSecurity, headers);
String answer = restTemplate.postForObject(url, entity, String.class);
Taking advantage of my current code, how can I create a solution that solves the upload problem that I mentioned above?
Related
I have a URL with a large number of entries that I want to persist into the MySQL database so that I can use my rest API to call on them. I have set up the whole structure as if im ready to use my own api, with entities, dtos, controllers, resources etc.
What I cannot figure out is, how do I persist json from the external api call into my database? Do I need to convert the json to entities before i persist them, or can I parse them directly into my database? And how would I go about persisting such a large json string with so many entries?
I've made an endpoint that calls the api, so that I can update the database on call, but I don't really know what to do next here
#PostMapping(value = "/popDB")
private itemEntity getItemObject() throws IOException {
URL url = new URL("api url string");
InputStream inputStream = url.openConnection().getInputStream();
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> jsonMap = mapper.readValue(inputStream, Map.class);
articleService.save((ItemEntity) jsonMap);
return (ItemEntity) jsonMap;
}
I need to create a benchmark report regarding whether in the grand scheme of things: minifying + GZIP dynamic HTML responses (generated through GSPs) on every request, which will lead to an additional overhead due to parsing of the generated dynamic HTML string then compressing using a Java library (which results to a smaller response size) is actually better than GZIP without minifying (which results to faster response time but a little larger response size). I got the feeling that this "improvement" maybe is insignificant, but I need the benchmark report to back it up to the team.
To do that, I modify controller actions like so:
// import ...MinifyPlugin
class HomeController {
def get() {
Map model = [:]
String htmlBody = groovyPageRenderer.render(view: "/get", model: model)
// This adds a few milliseconds and reduce few characters.
htmlBody = MinifyPlugin.minifyHtmlString(htmlBody)
render htmlBody
}
}
But the Grails project has almost a hundred actions and doing this on every existing action is impractical and not maintainable, especially that after the benchmarking, we may decide to not minify the HTML response. So I was thinking of doing this inside an Interceptor instead:
void afterView() {
if(response.getContentType().contains("text/html")) {
// This throws IllegalStateException: getWriter() has already been called for this response
OutputStream servletOutputStream = response.getOutputStream()
String htmlBody = new String(servletOutputStream.toByteArray())
htmlBody = MinifyingPlugin.minifyHtmlString(htmlBody)
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()
byteArrayOutputStream.write(htmlBody.getBytes())
response.setCharacterEncoding("UTF-8")
response.setContentType("text/html")
response.outputStream << byteArrayOutputStream
}
}
But it seems that modification of the response body is impossible once it enters the afterView interceptor...? So is any other way to do this using Grails 3 Interceptors, or should I update every controller action we have manually and perform the modification there instead?
This is what I like to use Interceptors for.
The after() part of the interceptor can act on the model after it is returned from the controller (wherein 'before()' acts on the request before it is sent to the controller)
This allows you to manipulate all data for a set of endpoints (or one specific endpoint) prior to return to client
If you are wanting to render to a view, you do that in the interceptor rather than in the controller; you merely return data from the controller
I have been using Spring Integration DSL to implement some messaging processing flow.
How can I actually unit test a single IntegrationFlow, can anyone provide me with an example on how to unit test i.e. transform part of this bean:
#Bean
public IntegrationFlow transformMessage(){
return message -> message
.transform(new GenericTransformer<Message<String>, Message<String>>() {
#Override
public Message<String> transform(Message<String> message) {
MutableMessageHeaders headers =
new MutableMessageHeaders(message.getHeaders());
headers.put("Content-Type", "application/json");
headers.put("Accept", "application/json");
String payload = "Long message";
ObjectMapper mapper = new ObjectMapper();
HashMap<String, String> map = new HashMap<>();
map.put("payload", payload);
String jsonString = null;
try {
jsonInString = mapper.writeValueAsString(map);
} catch (JsonProcessingException e) {
logger.error("Error:" + e.getMessage());
}
Message<String> request = new GenericMessage<String>(jsonString
, headers);
return request;
}
})
.handle(makeHttpRequestToValidateAcdrMessage())
.enrichHeaders(h -> h.header("someHeader", "blah", true))
.channel("entrypoint");
}
How can I test it?
Regards!
Seems for me "unit testing" means check the behavior of the particular part of the system, some small component.
So, in your case it is about that new GenericTransformer.
so, just make it as a top-level component and perform tests against its isolated instances!
The integration tests can be performed against the target IntegrationFlow as well.
Each EIP-component in the flow definition is surrounded with
MessageChannels - input and output. Even if you don't declare .channel() there, the Framework build implicit DirrectChannel to wire endpoints to the flow.
Those implicit get the bean name like:
channelBeanName = flowNamePrefix + "channel" +
BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR + channelNameIndex++;
So, since your IntegrationFlow is from Lambda, the input channel form the .transform() is just input of the flow - transformMessage.input.
The channel between .transform() and the next .handle() has bean name like: transformMessage.channel#0, because it will be a first implicit channel declaration.
The idea that you can #Autowired both of this channels to your test-case and add ChannelInterceptor to them before testing.
The ChannelInterceptor may play verificator role to be sure that you send to the transformer and receive from the a proper data as it is expected.
More info can be found here: https://github.com/spring-projects/spring-integration-java-dsl/issues/23
The same techniques described in the testing-samples project in the samples repo can be used here.
The send a message to channel transform.input and subscribe to entrypoint to get the result (or change it to a QueueChannel in your test case.
Example of DSL IntegrationFlows testing is on github.
I'm kinda stuck on this topic.
This is what i already found out.
A good tutorial was :
Using MySQL in Spring Boot via Spring Data JPA and Hibernate
http://blog.netgloo.com/2014/10/27/using-mysql-in-spring-boot-via-spring-data-jpa-and-hibernate/
I also found some information how to make single page application with hsqldb.
But i really want to create something that permanent saves the users data to the database using mysql.
But in order to use angular http i need json. Can i convert the urls like
/create?email=[email]&name=[name]
To json how should i proceed. Does anyone knows good tutorials on this. Or are there better way's to proceed.
The simplest/handy way to consuming JSON with Spring Boot is using a Java class that resembles your JSON (https://stackoverflow.com/a/6019761).
So, you can follow the tutorial you linked, then use a controller like this one to handle JSONs:
#RestController
public class UserController {
#RequestMapping(
value = "/user/create",
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> createUser(#RequestBody User user) {
try {
// Handle the User object here
userDao.save(user);
}
catch (Exception ex) {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
return new ResponseEntity<>(HttpStatus.OK);
}
// ...
}
Receiving a JSON like this (at the url /user/create):
{email: "john#doe.com", name: "John Doe"}
An user will be saved in your database.
Responding with JSON
Moreover, if you want to send a response as JSON from your controller you should create a java object then send it back as response, within the ResponseEntity object.
For example, suppose to have this class:
public class SuccessDto {
private String success;
public SuccessDto(String success) {
this.success = success;
}
}
You can change your controller in this way:
public ResponseEntity<SuccessDto> createUser(#RequestBody User user) {
// ...
return new ResponseEntity<>(
new SuccessDto("true"),
HttpStatus.OK
);
}
and you will have this JSON as response
{success: "true"}
if you have already managed to use it with HSQLDB, it's juste a matter of database properties (like the JDBC URL) and schema initialization.
Can you provide the code sample of the controller, how you save the data (via a Repository or a simple DAO ?) and the application.properties
I am using Spring 3.0.6 and i have a single controller for uploading files to the server. I am using a script to upload using XmlHttpRequest for browsers that support it while the rest of the browsers submit a (hidden) multipart form. The problem however is that when a form is submitted it sends the following header:
Accept text/html, application/xhtml+xml, */*
I figure that due to this header the Controller which is marked with #ResponseBody replies with the response been converted to XML instead of JSON. Is there a way to get around this without hacking the form submit request?
You can force JSON using #RequestMapping(produces = "application/json"). I don't remember if this is available in 3.0 but it is available in 3.1 and 3.2 for sure.
As others noted, Jackson needs to be on your classpath.
Thank you! I was having exactly the same issue and your post resolved my problem.
On the UI I'm using JQuery with this file upload plugin:
https://github.com/blueimp/jQuery-File-Upload/wiki
Here's my completed method (minus the biz logic):
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public void handleUpload( #RequestParam("fileToUpload") CommonsMultipartFile uploadFile, ServletResponse response){
List<UploadStatus> status = new ArrayList<UploadStatus>();
UploadStatus uploadStatus = new UploadStatus();
status.add(uploadStatus);
if(uploadFile == null || StringUtils.isBlank(uploadFile.getOriginalFilename())){
uploadStatus.setMessage(new Message(MessageType.important, "File name must be specified."));
}else{
uploadStatus.setName(uploadFile.getOriginalFilename());
uploadStatus.setSize(uploadFile.getSize());
}
ObjectMapper mapper = new ObjectMapper();
try {
JsonGenerator generator = mapper.getJsonFactory().createJsonGenerator(response.getOutputStream(), JsonEncoding.UTF8);
mapper.writeValue(generator, status);
generator.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
If you want a JSON response, you can easily accomplish that by having the Jackson JARs on your classpath. Spring will auto-magically pick up on them being there and will convert your #ResponseBody to JSON.
I made it work by getting rid off #ResponseBody and instead doing manually the conversion (always using Jackson), i.e.
Response r = new Response();
ObjectMapper mapper = new ObjectMapper();
JsonGenerator generator = mapper.getJsonFactory().createJsonGenerator(response.getOutputStream(), JsonEncoding.UTF8);
try {
File f = uploadService.getAjaxUploadedFile(request);
r.setData(f.getName());
} catch (Exception e) {
logger.info(e.getMessage());
r = new Response(new ResponseError(e.getMessage(), ""));
}
mapper.writeValue(generator, r);
generator.flush();
Does anyone know another way? I tried setting up a ContentNegotiatingViewResolver but i don't want to break any other controllers by assigning all hmtl to json. Also, i tried to do it for this method only via a custom viewresolver but when i setup a jsonview and use BeanNameViewResolver although the response is correctly converted to JSON the server throws an
HttpRequestMethodNotSupportedException: exception, with Request method 'POST' not supported and set status to 404.