Spring Boot and ConfigServer - spring-boot

We have a SpringBoot application which is successfully comunicating with config server.
The question I have is... say we have a application properties file and a csv file in config server.
when application starts if we want to get the contents of csv file too whats the better approach.
We are able to get it by doing a direct http connection to configserver and retreive the csv file contents
String url = configServerURL+"/*/*/*/example.csv";
byte[] encoded = Base64.encode((uname + ":" + password).getBytes());
URL obj = new URL(url);
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
con.setRequestProperty("Authorization", "Basic "+encoded);
int responseCode = con.getResponseCode();
wanted to check what options are there.

Related

SpringBoot how to get full URL of application

Basically, I want to log everything that happens in the life cycle of my SpringBoot REST API, and I'd like to log something like App started at [ip]:[port]/[everything else]
I had already seen a question like this but it was using the embedded Tomcat, I use another web server, can it be done? It would be real cool.
You can retrieve these informations using the ServletUriComponentsBuilder in your Controller :
URI currentUri = ServletUriComponentsBuilder.fromCurrentRequestUri()
.build()
.toUri();
String asString = currentUri.toString(); // "http://localhost:8080/orders/1/items/18"
String host = currentUri.getHost(); // "localhost"
int port = currentUri.getPort(); // 8080
String path = currentUri.getPath(); // "/orders/1/items/18"

Spring boot embedded tomcat - 413 Request Entity Too Large

I'm running on the IBM public cloud. I have apu connect to access the cloud foundry microservice. I've gone through many of the posts and tried various things and I can't seem to get this to work. Here are my property file config settings for spring boot:
# The name of the application
spring.application.name=xxxxx
# web base path
management.endpoints.web.base-path=/
# Embedded tomcat config
server.tomcat.max-swallow-size=256MB
server.tomcat.max-http-post-size=256MB
# File size values
spring.servlet.multipart.max-file-size=256MB
spring.servlet.multipart.max-request-size=256MB
spring.servlet.multipart.enabled=true
# Server specific values
input.server=xxx
input.rtm.bucket=xxx
storage.server.base=xxx
# Cloudant database info
input.events.db.name=xxxx
input.ait.info.db.name=xxxx
letter.number.db.name=xxxx
letter.gen.data.db.name=xxxx
# Query index design documents
query.pad.ait.info.index.name=xxxx
query.pad.ait.info.deisgn.doc=_xxxx
query.rfa.ltr.index.name=xxxx
query.rfa.ltr.design.doc=xxxx
# The logging levels of the application
logging.level.application=DEBUG
#logging.level.root=DEBUG
#logging.level.org.springframework.web=INFO
# Testing
unit.testing=false
integration.testing=true
# Jackson json config
spring.jackson.mapper.accept-case-insensitive-properties=true
Here is the REST api function for POSTing the file
#PostMapping(value = "/send/rtm/document/{errata}")
public #ResponseBody ResponseEntity<Object> receiveRtmDocument(#PathVariable("errata") String errata, #RequestParam("file") MultipartFile file)
I'm using spring boot 2.1.6 and have not updated anything in the POM file. I'm attempting to send a 5.8 MB file to the api and it gives me this error:
com.ibm.tools.cloud.exceptions.DataNotJsonException: <html>
<head><title>413 Request Entity Too Large</title></head>
<body bgcolor="white">
<center><h1>413 Request Entity Too Large</h1></center>
<hr><center>openresty</center>
</body>
</html>
at com.ibm.msc.gasm.sapt.input.AitInputManagement.sendRtmDocument(AitInputManagement.java:182)
at com.ibm.msc.gasm.sapt.test.InputServiceTester.performTest(InputServiceTester.java:142)
at com.ibm.msc.gasm.sapt.test.InputServiceTester.main(InputServiceTester.java:96)
Here is the send code I am using in java for the multipart. The only other headers I use that are not listed here are my authorization headers.
// Create the URL connection
HttpURLConnection conn = (HttpURLConnection) (new URL(requestUri)).openConnection();
if (content != null || multipartFile) conn.setDoOutput(true);
conn.setRequestMethod(method.toString());
// Set the headers
Enumeration<String> keys = headers.keys();
while (keys.hasMoreElements())
{
// Pull out the key
String key = keys.nextElement();
// Set the header
conn.setRequestProperty(key, headers.get(key));
}
// Set the accept header
if (acceptHeader != null) conn.setRequestProperty("Accept", acceptHeader);
// Set the content header
if (contentTypeHeader != null) conn.setRequestProperty("Content-Type", contentTypeHeader);
if (content != null)
{
// Set the content
DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
if (content.isFileContent()) dos.write(content.getFileContentAsByteArray());
else if (content.isByteArrayContent()) dos.write(content.getContentAsByteArray());
else if (content.isStringContent()) dos.write(content.getStringContentAsByteArray());
// close the stream
dos.flush();
dos.close();
}
// Set the multipart file
if (multipartFile)
{
// Set the properties
conn.setUseCaches(false);
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("Cache-Control", "no-cache");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundry=" + MP_BOUNDRY);
// Set the content
DataOutputStream dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(MP_HYPHENS + MP_BOUNDRY + StringUtils.crlf);
dos.writeBytes("Content-Disposition: form-data: name=\"" + this.mpName + "\";filename=\"" + this.mpFileName + "\"" + StringUtils.crlf);
dos.writeBytes(StringUtils.crlf);
dos.write(IOUtils.toByteArray(new FileInputStream(this.mpFileNamePath)));
dos.writeBytes(StringUtils.crlf);
dos.writeBytes(MP_HYPHENS + MP_BOUNDRY + MP_HYPHENS + StringUtils.crlf);
// close the stream
dos.flush();
dos.close();
}
// Get the response
HttpResponseMessage response = null;
try
{
// Extract the stream
InputStream is = (conn.getResponseCode() >= HttpURLConnection.HTTP_BAD_REQUEST) ? conn.getErrorStream() : conn.getInputStream();
// Pull out the information
byte[] data = IOUtils.toByteArray(is);
// Set the response
response = new HttpResponseMessage(requestUri, HttpStatusCode.getType(conn.getResponseCode()), acceptHeader, data, conn.getResponseMessage());
}
catch (Throwable e)
{
throw new IOException(String.format("Error reading results from %s", requestUri), e);
}
// Close the request
conn.disconnect();
// Send request
return response;
I've tried several things, but I am not sure what I am missing. Anyone have any ideas how to fix this?
You need to change NGINX settings;
Add to config file next line
client_max_body_size 20M;
Use the form form to submit the file and accept it with MultipartFile. In this case (the other situation is not clear), the default file size is limited to 2M. If you want to upload a large file, you need to configure the file size.
https://www.cyberciti.biz/faq/linux-unix-bsd-nginx-413-request-entity-too-large/
Try these two in your application.properties
server.tomcat.max-swallow-size=XMB //maximum size of the request body/payload
server.tomcat.max-http-post-size=XMB //maximum size of entire POST request
X is your desired integer representing megabyte.

FileNotFoundException: cert\jssecacerts and sessionId = 0

I am trying to connect to our server via websocket. I was able to get the session when I run in IDE. However, the session id is 0.
Also, when I compile and run this using java -jar, I got the following error. When running in IDE, I don't get this error as I set the working directory to src/main/resources where the cert folder is located:
java.io.FileNotFoundException: cert\jssecacerts (The system cannot find the path specified)
...
at org.apache.tomcat.websocket.WsWebSocketContainer.createSSLEnginer(WsWebSocketContainer.java:893)
Please advise.
WebSocketClient client = new StandardWebSocketClient();
WebSocketHandler handler = new TextWebSocketHandler();
WebSocketHttpHeaders headers = new WebSocketHttpHeaders();
headers.add("Authorization", "Bearer " + getSignedToken());
URI uri = new URI("wss://<some server>");
((StandardWebSocketClient) client).getUserProperties().put(Constants.SSL_TRUSTSTORE_PROPERTY, "cert/jssecacerts");
((StandardWebSocketClient) client).getUserProperties().put(Constants.SSL_TRUSTSTORE_PWD_PROPERTY, Constants.SSL_TRUSTSTORE_PWD_DEFAULT);
WebSocketSession session = client.doHandshake(handler, headers, uri).get();
Regarding filenotfound, I figured it out.
Resource resource = new ClassPathResource("cert/jssecacerts");
...
((StandardWebSocketClient) client).getUserProperties().put(Constants.SSL_TRUSTSTORE_PROPERTY, resource.getFile().getAbsolutePath());

I need the Jersey Multipart Client and server code to Upload more than one file.?

I need the Jersey Multipart Client to Upload more than one file.
I am able to upload a Single file but how can i upload more than one file.
In the client i set the two filedatabody parts.
final FileDataBodyPart filePart = new FileDataBodyPart("file", new File("path"));
FormDataMultiPart formDataMultiPart = new FormDataMultiPart();
FileDataBodyPart filePart2 = new FileDataBodyPart("file", new File("path2"));
final FormDataMultiPart multipart =
(FormDataMultiPart) formDataMultiPart.field("foo", "bar").bodyPart(filePart).bodyPart(filePart2);
How to write the server side code.
The "file" you're using here new FileDataBodyPart("file", new File("path2")); is the name of the body part. If you are going to name them the same (which is allowed), then use a List for your parameter type
public Response upload(#FormDataParam("file") List<InputSream> files)
Otherwise if you want to change the name of one of the parts, then just add another #FormDataParam parameter using that part's name
public Response upload(#FormDataParam("file1") InputStream file1,
#FormDataParam("file2") InputStream file2)

Sending Images to the client from tomcat server

I am building a framework for e-commerce site. I have used jersey to create REST APIs. I need to send images to the clients as per the request.
How can I do so from my application server as Tomcat and jersey as REST API?
Since I am new to this, I have no clue how to send images to an Android client when they are shown as item.
Every resource is identified by the URI, client will ask for a particular image or a bunch of images by quering the URL, So you just need to expose a service, following service is an example to send single image to client.
#GET
#Path("/images/{imageId}")
#Produces("image/png")
public Response downloadImage(#PathParam("imageId") String imageId) {
MultiMediaDB imageDb = new MultiMediaDB();
String filePath = imageDb.getImage(imageId);
File file = new File(filePath);
ResponseBuilder response = Response.ok((Object) file);
response.header("Content-Disposition",
"attachment; filename=\"fileName.png\"");
return response.build();
}
MultiMediaDB is my custom class to get the file location from the DB, you can hardcode it as of now for testing purpose like D:\server_image.png.
You need to mention Content-Disposition as an attachment so that file will not be downloaded, instead attached to the form. In android you just need to read inputstream from a HttpURLConnection object and send that to bitmap as shown below
URL url = new URL(BaseUrl + "/images/" + imageId);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.connect();
iStream = urlConnection.getInputStream();
bitmap = BitmapFactory.decodeStream(iStream);
The you can set that bitmap to imageview or what ever you have as a container.

Resources