Can we cache a JAX-RS Jersey Response for sending it multiple times? - jersey

I have to send the same Response over and over, like:
private Response abortWithUnauthorized() {
return Response.status(Response.Status.UNAUTHORIZED)
.header(HttpHeaders.WWW_AUTHENTICATE,
AUTHENTICATION_SCHEME + " realm=\"" + REALM + "\"")
.build();
}
Can I save this Response in a static field once and then only return it later, every time I need to send a 401 Response?

Related

OkHttp Api call to Okta Api end point hits {"successful":true,"redirect":false} instead of actual dataset

I am attempting to call okta to get the user info API endpoint with the Okhttp library. The application received {"successful": true,"redirect": false} when the call from java spring boot, instead of the actual dataset from the API endpoint using Postman. What am i missing in this case:
Request requestValue = new Request.Builder()
.url("https://dev-xxxxxxx.okta.com/api/v1/users/xxxxxx")
.addHeader("Accept-Encoding", "gzip, deflate, br")
.addHeader("Accept", "application/json")
.addHeader("Content-Type", "application/json")
.addHeader("Authorization", "SSWS " + apiKey.getCfgValue()).build();
try (Response response = httpClient.newCall(requestValue).execute()) {
if (response.code() == 200) {
return response;
}
}
Appreciate much that anyone could help.
Response response = httpClient.newCall(requestValue).execute()
**response.body()**
That's what you want.

Spring WebClient throw error based on response body

I am using Spring WebClient to call REST API. I want to throw an error based on the response. For example, if there is an error (400) with body
{"error": "error message1 "}
then I want to throw an error with "error message1". Same way if there is an error(400) with the body
{"error_code": "100020"}
then I want to throw an error with error_cde 100020. I want to do it in a non-blocking way.
public Mono<Response> webclient1(...) {
webClient.post().uri(createUserUri).header(CONTENT_TYPE, APPLICATION_JSON)
.body(Mono.just(request), Request.class).retrieve()
.onStatus(HttpStatus::isError, clientResponse -> {
//Error Handling
}).bodyToMono(Response.class);
}
A body from ClientResponse should be extracted in a reactive way (javadoc) and lambda in onStatus method should return another Mono (javadoc). To sum up, take a look at below example
onStatus(HttpStatus::isError, response -> response
.bodyToMono(Map.class)
.flatMap(body -> {
var message = body.toString(); // here you should probably use some JSON mapper
return Mono.error(new Exception(message));
})
);

SpringBoot simple multipart file upload with Advanced rest client (Chrome)

I want to upload a image to the file system. So I am using Multi-part file upload with spring boot. And also I am using Advance Rest Client(Chrome) tool to POST Multi part file. But I am facing an error even I do not specify any content type org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found.
Here my rest controller code,
#RestController
public class StringController {
#RequestMapping(value="/upload", method=RequestMethod.POST)
public #ResponseBody String singleSave(#RequestParam("file") MultipartFile file){
String fileName = null;
if (!file.isEmpty()) {
try {
fileName = file.getOriginalFilename();
byte[] bytes = file.getBytes();
BufferedOutputStream buffStream =
new BufferedOutputStream(new FileOutputStream(new File("F:/" + fileName)));
buffStream.write(bytes);
buffStream.close();
return "You have successfully uploaded " + fileName;
} catch (Exception e) {
return "You failed to upload " + fileName + ": " + e.getMessage();
}
} else {
return "Unable to upload. File is empty.";
}
}
}
Screenshot (Advance rest client tool)
Error
{
"timestamp": 1490678908517,
"status": 500,
"error": "Internal Server Error",
"exception": "org.springframework.web.multipart.MultipartException",
"message": "Could not parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found",
"path": "/upload"
}
The problem is in your request from advance rest client. It is working fine in the postman.The image is getting uploaded. Try with postman you will get it.
You lost in you client request headers value boundary.
Construct in PostMan header "Content-Type" like this:
Content-Type : multipart/form-data;boundary="12312313132132"

Enable authenticator manually

Currently my client authenticates request only on case of 401 response:
this.client.authenticator(new okhttp3.Authenticator() {
public Request authenticate(Route route, Response response) throws IOException {
String credentials = authenticator.getCredentials();
if (credentials.equals(response.request().header("Authorization"))) {
throw new TraversonException(401, "Unauthorized", response.request().url().toString());
} else {
defaultHeader("Authorization", credentials);
Request.Builder newRequest = response.request().newBuilder()
.headers(Headers.of(defaultHeaders));
return newRequest.build();
}
});
But I'd like to change this behavior and be able to call it either manually or auto per first call? Is it possible somehow?
If the authentication is predictably required and not related to a proxy, then the solution is to implement an Interceptor instead of Authenticator.
OkHttpClient.Builder clientBuilder = ...;
clientBuilder.networkInterceptors().add(0, myInterceptor);
client = clientBuilder.build();
Example Interceptor https://github.com/yschimke/oksocial/blob/48e0ca53b85e608443eab614829cb0361c79aa47/src/main/java/com/baulsupp/oksocial/uber/UberAuthInterceptor.java
n.b. There is discussion around possible support for this usecase in https://github.com/square/okhttp/pull/2458. One issue with current Authenticator API is that it assumes a Response from the failed (401) request.

Jetty Proxy Servlet : Handle Redirection

If the response from server is a redirection i.e. a 302 status with location header , Jetty's ProxyServlet does not handle that and the control redirects to original server . How can i resolve this ? Also how can i change the Response and Response headers ?
You can override a method in ProxyServlet that lets you rewrite headers. So you can, for example, see if there is a Location header, and if so remove the target URL and replace it with the URL that the client requested. This is how I did it:
#Override
protected String filterServerResponseHeader(HttpServletRequest clientRequest, Response serverResponse, String headerName, String headerValue) {
if (headerName.equalsIgnoreCase("location")) {
URI targetUri = serverResponse.getRequest().getURI();
String toReplace = targetUri.getScheme() + "://" + targetUri.getAuthority();
if (headerValue.startsWith(toReplace)) {
headerValue = clientRequest.getScheme() + "://" + clientRequest.getHeader("host")
+ headerValue.substring(toReplace.length());
log.info("Rewrote location header to " + headerValue);
return headerValue;
}
}
return super.filterServerResponseHeader(clientRequest, serverResponse, headerName, headerValue);
}

Resources