Spring MyBatis conversion error - mybatis

I am quite new to Spring with MyBatis, and I encountered this error. I am trying to upload an image to my database which is MySQL
Failed to convert value of type 'java.lang.String' to required type 'org.springframework.web.multipart.commons.CommonsMultipartFile'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [org.springframework.web.multipart.commons.CommonsMultipartFile]: no matching editors or conversion strategy found
This is my controller:
#RequestMapping(value = "/GalleryResults", method = RequestMethod.GET)
public String insert(Model model,
#RequestParam(value = "photo", required = false) CommonsMultipartFile photo,
#RequestParam(value = "caseNo", required = false) String caseNo,
#RequestParam(value = "date", required = false) String date,
#RequestParam(value = "offenseIncident", required = false) String offenseIncident,
#RequestParam(value = "nameAKA", required = false) String nameAKA,
#RequestParam(value = "height", required = false) String height,
#RequestParam(value = "built", required = false) String built,
#RequestParam(value = "otherInfo", required = false) String otherInfo,
#RequestParam(value = "describedBy", required = false) String describedBy,
#RequestParam(value = "requestingParty", required = false) String requestingParty,
#RequestParam(value = "investOnCase", required = false) String investOnCase,
#RequestParam(value = "interviewer", required = false) String interviewer,
#RequestParam(value = "age", required = false) String age,
#RequestParam(value = "weight", required = false) String weight,
#RequestParam(value = "complexion", required = false) String complexion,
#RequestParam(value = "rating", required = false) String rating) {
try {
GalleryResults input = new GalleryResults();
input.setCaseNo(caseNo);
input.setDate(date);
input.setOffenseIncident(offenseIncident);
input.setNameAKA(nameAKA);
input.setHeight(height);
input.setBuilt(built);
input.setOtherInfo(otherInfo);
input.setDescribedBy(describedBy);
input.setRequestingParty(requestingParty);
input.setInvestOnCase(investOnCase);
input.setInterviewer(interviewer);
input.setAge(age);
input.setWeight(weight);
input.setComplexion(complexion);
input.setRating(rating);
input.setPhoto(photo);
input.setPhotoBytes(photo.getBytes());
input.setPhotoContentType(photo.getContentType());
input.setPhotoName(photo.getOriginalFilename());
galleryService.create(input);
} catch (Exception e) {
}
return "galleryResults";
}
My POJO
private CommonsMultipartFile photo;
private byte[] photo;
private byte[] photoBytes;
private String photoName;
private String photoContentType;
Is there anything that I did wrong? Or am I missing anything?

When a file upload, the HTTP request which is sended to web server like
POST /someUrl
Content-Type: multipart/mixed
--edt7Tfrdusa7r3lNQc79vXuhIIMlatb7PQg7Vp
Content-Disposition: form-data; name="meta-data"
Content-Type: application/json; charset=UTF-8
Content-Transfer-Encoding: 8bit
{
"name": "value"
}
--edt7Tfrdusa7r3lNQc79vXuhIIMlatb7PQg7Vp
Content-Disposition: form-data; name="file-data"; filename="file.properties"
Content-Type: text/xml
Content-Transfer-Encoding: 8bit
... File Data ...
The part named "File Data" represent the real file data stream. It is convert to "MultipartFile" by #RequestPart("file-data"). The method which handle the upload logic should be like this:
#RequestMapping("/../upload")
public void uploadFile(#RequestPart("file-data") MultipartFile uploadedFile, ..) {
......
}

Add the conversion strategy for
org.springframework.web.multipart.commons.CommonsMultipartFile
in bean

Related

How to send POST request to another microservice containing enum #RequestParam in kotlin?

I tried to send request to another service containing enum #RequestParam but it always fails.
Here's the example of my request;
fun upsertExclusionOverride(
request: request
): ExcOve? {
val builder = UriComponentsBuilder.fromUriString("/v1/p-b/e/bulk")
val httpEntity = RestTemplateUtils.getHttpEntityCustomHeaders(request, headers)
try {
val body = restTemplate
.exchange(
builder.toUriString(),
HttpMethod.POST,
httpEntity,
Response::class.java
)
.body
?: throw Exception("Fail")
return body.toDomain()
} catch (e: RestClientException) {
log.error(e.message)
throw Exception("Fail")
}
}
This is the other microservice;
#PostMapping("/e/bulk")
#ApiOperation("Exclude")
fun exclusionsInBulk(
#RequestParam(name = "operation", required = true) operation: Operation,
#RequestPart("file") #ApiParam(
value = "File",
required = true,
format = "byte"
) file: MultipartFile
): ResponseEntity<Response> {
.....
}
How should I prevent 400 Bad Request?
I added enum converter but it didn't work.
I expect it to not to get 400 Bad Request.

In Jersey, how to return an object with 400 response code different than the 200 response object

I am new to Jersey and to REST in general, so this might be a stupid question....
In my code, I send a request (TemplateValidationRequest) to try to validate an object. If the object fails to validate, I want to return a String. How do I do this?
In the second code snippet at the bottom, you can see that I'm looking for TemplateValidationResponse object. How can I change my code so that:
I can return a string, and
I can get a String instead of a TemplateValidationResponse object.
Is this possible?
#POST
#Path("validate/modelTemplate")
#Produces({MediaType.APPLICATION_JSON})
#Consumes({MediaType.APPLICATION_JSON})
#Operation(
summary = "Convert model template to AMBOS interaction model and validate the result",
tags = { BLUEPRINTS_TAG },
requestBody = #RequestBody(
content = #Content(
schema = #Schema(
implementation = TemplateValidationRequest.class
)
)
),
responses = {
#ApiResponse(
responseCode = "200",
description = "Success.",
content = #Content(
schema = #Schema(
implementation = TemplateValidationResponse.class
)
)
),
#ApiResponse(
responseCode = "400",
description = "Failure",
content = #Content(
schema = #Schema(
implementation = String.class
)
)
)
}
)
#CustomerIdentityRequired
#AcceptsLanguageRequired
#AAA(serviceName = SERVICE_NAME, operationName = BLUEPRINTS_GET)
ModelTemplateValidationResponse validateModelTemplate(TemplateValidationRequest);
 
fun validateModelTemplate(modelTemplate: InteractionModel,
sampleData: Map<String, Any>): TemplateValidationResponse {
val request = TemplateValidationRequest()
request.modelTemplate = modelTemplate
request.sampleData = sampleData
return temp.validateModelTemplate(request)//this is where I call the above code
//If this request fails and results in a 400 error, I want to get a String
}
What about something like:
public Class YourResponse {
private boolean isError;
private String setThisWhenThereIsError;
private YourObject setThisWhen200;
}

Query Parameters in case class - Swagger Docs

I am writing an API for my application.
The application allows administrators to search for users with query params.
My problem
There are a lot of query parameters which are using a lot space in my controllers. Currently I have solved it by having all the QueryParameters as parameters in the method, like this:
def findUser (
#ApiParam(name = "firstName", value = "First name", `type` = "query")
#RequestParam(value = "firstName", required = false) firstName: String,
#ApiParam(name = "surname", value = "Surname", `type` = "query")
#RequestParam(value = "surname", required = false) surname: String,
#ApiParam(name = "email", value = "Email adress", `type` = "query")
#RequestParam(value = "email", required = false) email: String,
#ApiParam(name = "telephoneNumber", value = "Phone number", `type` = "query")
#RequestParam(value = "telephoneNumber", required = false) telephoneNumber: String,
#ApiParam(name = "landlineNumber", value = "Land line number", `type` = "query")
#RequestParam(value = "landlineNumber", required = false) landlineNumber: String,
#ApiParam(name = "dateOfBirth", value = "Date of Birth", `type` = "query")
#RequestParam(value = "dateOfBirth", required = false) dateOfBirth: String,
#ApiParam(name = "postalAddress", value = "Postal adress", `type` = "query")
#RequestParam(value = "postalAddress", required = false) postalAddress: String,
#ApiParam(name = "postCode", value = "Post code", `type` = "query")
#RequestParam(value = "postCode", required = false) postCode: String
) = {
// doing stuff
}
Question:
Is there a way to extract all the query params into a class or a object in Swagger Docs? Like illustrated below:
def allQueryParamsInACaseClass (
queryParams : AllQueryParams
)
I fixed it by using #ModelAttribute and then created a case class with #BeanProperties.
def allQueryParamsInACaseClass (
#ModelAttribute queryParams: AllQueryParams
)
case class AllQueryParams (
...
#ApiParam(name = "firstName", value = "First name", `type` = "query")
#RequestParam(value = "firstName", required = false) #BeanProperty firstName: String,
..
)

Passing a map in GET, JAVA

How do i Pass a Map of Key Value pairs to a GET REST API,
Here is the call to the resource .. I am getting a method not allowed
String queryMap= String.format("{'softwareversion':'%s','peril':'%s','analysistype':'%s', 'region':'%s'}", "HD18", "Flood", "EP", "USFL");
String url = String.format("http://localhost:%d/templates/modelprofile?queryMap=%s", API_APPLICATION_RULE.getLocalPort(),queryMap);
Response response = ClientBuilder.newClient()
.target(url)
.request()
.header("Authorization", getToken())
.get();
I have the resource as below
#GET
#Path("/{templateType}")
#Timed
#Produces(MediaType.APPLICATION_JSON)
#ApiOperation(value = "Get templates based on peril/region,version and type",
httpMethod = ApiConstants.GET)
#ApiResponses(value = {
#ApiResponse(code = ApiConstants.INT_200,
message = "TemplateReader was retrieved successfully from the database."),
#ApiResponse(code = ApiConstants.INT_400,
message = "Bad request (wrong or missing inputs)"),
#ApiResponse(code = ApiConstants.INT_500,
message = ApiConstants.INTERNAL_SERVER_ERROR)
})
public Template getTemplate(#ApiParam(hidden = true) #Auth User user,
#ApiParam(name = "templateType", value = "templateType")
#PathParam("templateType") String templateType,
#ApiParam(name = "queryMap", value = "queryMap")
#RequestParameters Map<String,String> queryMap
) throws ApiException
You can pass it using request parameter as below.
#RequestMapping(name = "/url/", method = RequestMethod.GET)
public void method_name(#RequestParam(name = "map_name")Map<String, Object> requestMap){
//Process map and perform your logic
}

Saving PDF with Devdefined's IConsumerRequest

I'm trying to save a PDF from QBO however I'm stuck on this bit:
How do i get the IConsumerRequest to return a stream instead of a string? ReadBody only seems to send string rather than binary data...
IConsumerRequest conReq = oSession.Request();
conReq = conReq.Get().WithRawContentType("application/pdf");
string outURL = base_url + "invoice-document/v2/" + realmId + "/" + customerInvoicesWithinDateRange[0].Id.Value;
conReq = conReq.ForUrl(outURL);
conReq = conReq.SignWithToken();
string serviceResponse = conReq.ReadBody();
Thanks
instead of conReeq.ReadBody(), you can do this:
conReq.ToWebResponse().GetResponseStream();
in fact, ReadBody() is simply an extension method on IConsumerRequest, defined as:
public static string ReadBody(this IConsumerRequest request)
{
HttpWebResponse response = request.ToWebResponse();
return response.ReadToEnd();
}