How to send JSON from clinet and get DTO-Object on server? - angularjs

At client I have:
for (var i = 0; i < $files.length; i++) {
var file = $files[i];
var data = {f_name: 'test1', s_name: 'test2'};
var fd = new FormData();
fd.append('data', angular.toJson(data));
fd.append("file", file);
$http({
method: 'POST',
url: 'EmployeeService/employee/upload',
headers: {'Content-Type': undefined},
data: fd,
transformRequest: angular.identity
})
.success(function(data, status) {
alert("success");
});
}
And on server (Spring):
#ResponseBody
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public String postFile(#RequestParam(value="file", required=false) MultipartFile file,
#RequestParam(value="data") Object data) throws Exception {
System.out.println("data = " + data);
return "OK!";
}
But data is String: "{"f_name":"test1","s_name":"test2"}". A have DTO-class:
public class EmployeeDTO(){
private String f_name;
private String s_name;
//setters and getters
}
And on server I want to get:
#ResponseBody
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public String postFile(#RequestParam(value="file", required=false) MultipartFile file,
#RequestParam(value="data") EmployeeDTO employeeDTO) throws Exception {
//etc.
}
How to send data from client (file and data) and on server get file and EmployeeDTO object?

while you can use annotation #RequestBody to get Object from json string.
for example:
#ResponseBody
#RequestMapping(value = "/test", method = RequestMethod.POST)
public String test(#RequestBody EmployeeDTO employeeDTO){
//TODO do something;
return "success";
}
or you can receive string and then use ObjectMapper to convert string to object
for example:
EmployeeDTO employeeDTO = new ObjectMapper().readValue("here is json string", EmployeeDTO.class);

You could register a Converter<String, EmployeeDTO> that would use Json ObjectMapper and you could write you controller method as you want (I assume you use Jackson2)
If you need that in only this method, it may be simpler to do it explicitely :
#Autowired
private MappingJackson2HttpMessageConverter jsonConverter;
#ResponseBody
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public String postFile(#RequestParam(value="file", required=false) MultipartFile file,
#RequestParam(value="data") String data) throws Exception {
EmployeeDTO employeeDTO = jsonConverter.getObjectMapper().readValue(data,
EmployeeDTO.class);
return "OK!";
}
Alternatively, you could put the object directly in the FormData (angularJS side) and get it with #ModelAttribute spring side :
var fd = new FormData();
fd.append("file", file);
fd.append("f_name", 'test1');
fd.append("s_name", 'test2'};
and
#ResponseBody
#RequestMapping(value = "/upload", method = RequestMethod.POST)
public String postFile(#RequestParam(value="file", required=false) MultipartFile file,
#ModelAttribute EmployeeDTO employeeDTO) throws Exception {

Related

How can I Extract JSON Object that Holds Base64 and File Extension from application/json body in ASP.NET Core

I am passing a JSON object that holds 2 Keys from React to ASP.NET Core as Follows
formData = {
image: "Base64String Here",
type: "JPEG"
}
url,
method: "POST",
data: {image: formData.image, type: formData.type},
headers: {
'Content-Type': 'application/json'
}
})
it is then collected in my controller as follows
public async Task<ActionResult<IEnumerable<AppImage>>> UploadImage()
{
string jsonString;
using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
{
jsonString = await reader.ReadToEndAsync();
}
try
{
await using var transaction = await _context.Database.BeginTransactionAsync();
SQLAppImage sqlData = new SQLAppImage(_context);
ImageHelper ih = new ImageHelper(_configuration);
//String filePath = ih.UploadImage(image, type);
//AppImage appImage = new AppImage
//{
// ImagePath = filePath,
// FileType = type
//};
//sqlData.Add(appImage);
await transaction.CommitAsync();
return Ok();
}
catch (Exception e)
{
throw e;
}
}
but i cannot seem to get the JSON object through, is there any recommendations that you might have that can help me please
Thank you in Advance
To do this, create a class as shown below :
public class UploadPhotoDto
{
public string Image { get; set; }
public string Type { get; set; }
}
and use it as your method input Like This:
[HttpPost]
public async Task<ActionResult<IEnumerable<AppImage>>>UploadImage(UploadPhotoDto uploadPhotoDto)
{
//And you can access them
string base64 = uploadPhotoDto.Image;
string type = uploadPhotoDto.Type;
//Your Code
}

Could someone help me build a test apex for an opportunity closed/won trigger?

I'm not a developer and we don't have one currently on our staff. So I looked all over the web and modified this Apex Class to suit my needs so that when an opportunity is marked as closed/won I get a small message in Slack.
It works great and I'd like to send this to Production. However, I didn't realize that I need to include a test for this and I am stuck on what that means.
Here's my Apex Class:
public with sharing class SlackPublisher {
private static final String SLACK_URL = 'https://hooks.slack.com/services/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';
public class Oppty {
#InvocableVariable(label='Opportunity Name')
public String opptyName;
#InvocableVariable(label='Opportunity Owner')
public String opptyOwnerName;
#InvocableVariable(label='Account Name')
public String acctName;
#InvocableVariable(label='Amount')
public String amount;
}
public class UrlMethods {
String BaseUrl; // The Url w/o the page (ex: 'https://na9.salesforce.com/')
String PageUrl; // The Url of the page (ex: '/apex/SomePageName')
String FullUrl; // The full Url of the current page w/query string parameters
// (ex: 'https://na9.salesforce.com/apex/SomePageName?x=1&y=2&z=3')
String Environment; // Writing code that can detect if it is executing in production or a sandbox
// can be extremely useful especially if working with sensitive data.
public UrlMethods() { // Constructor
BaseUrl = URL.getSalesforceBaseUrl().toExternalForm(); // (Example: 'https://na9.salesforce.com/')
}
}
#InvocableMethod(label='Post to Slack')
public static void postToSlack ( List<Oppty> opps ) {
Oppty o = opps[0]; // bulkify the code later
Map<String,Object> msg = new Map<String,Object>();
msg.put('text','Deal ' + o.opptyName + ' was just Closed/Won' + ':champagne:' + '\n' + 'for a total of ' + '$' + o.amount);
msg.put('mrkdwn', true);
String body = JSON.serialize(msg);
System.enqueueJob(new QueueableSlackPost(SLACK_URL, 'POST', body));
}
public class QueueableSlackPost implements System.Queueable, Database.AllowsCallouts {
private final String url;
private final String method;
private final String body;
public QueueableSlackPost(String url, String method, String body) {
this.url = url;
this.method = method;
this.body = body;
}
public void execute(System.QueueableContext ctx) {
HttpRequest req = new HttpRequest();
req.setEndpoint(url);
req.setMethod(method);
req.setBody(body);
Http http = new Http();
HttpResponse res = http.send(req);
}
}
}
and what I found online as a base for a test was this:
#isTest
private class SlackOpportunityPublisherTest {
private class RestMock implements HttpCalloutMock {
public HTTPResponse respond(HTTPRequest req) {
String fullJson = 'your Json Response';
HTTPResponse res = new HTTPResponse();
res.setHeader('Content-Type', 'text/json');
res.setBody(fullJson);
res.setStatusCode(200);
return res;
}
}
static testMethod void service_call() {
Test.setMock(HttpCalloutMock.class, new RestMock());
Test.startTest();
//your webserive call code
Database.GetUpdatedResult r =
Database.getUpdated(
'amount',
Datetime.now().addHours(-1),
Datetime.now());
Test.StopTest();
}
}
When I try to validate this in production it says it only gives me 68% coverage and I need 75%. Can someone help me write the test so that I can put into Prod?

POST405 (Method Not Allowed)

I am using AngularJS to send a POST request from my controller and I'm getting this error:
POST not supported
The JS function is the following:
addUserDetails: function(addUser) {
alert("M into add user function in service");
return restClientTemplate.execute({
method: 'POST',
url: 'json/user-add',
data: addUser
});
}
My Java Spring Controller is the following:
#Controller
public class AddUserController {
#Resource
private Settings settings;
#Resource
private RestOperations rest;
private static final String ORGANIZATION_URL_KEY = "configuration.organization.service.endpointUrl";
private static final String ORG_PRODUCT_LIST_URL_KEY = "configuration.org.product.list.service.endpointUrl";
#RequestMapping(value = "/json/user-add", method = RequestMethod.POST, produces = "application/json")
public ServiceResponse addOrganization(#RequestBody SaveOrganizationForm request) {
System.out.println("M into controllerrrr");
ObjectMapper objectMapper = new ObjectMapper();
ObjectNode requestBody = objectMapper.createObjectNode();
populateRequestObject(request, objectMapper, requestBody);
String url = MessageUtil.format(settings.getString(ORGANIZATION_URL_KEY) + "/s2");
ServiceResponse response = rest
.exchange(url, HttpMethod.POST, new HttpEntity<>(requestBody), ServiceResponse.class).getBody();
return response;
}

AngularJS send data to spring mvc method

Hi everyone i'm trying to send data as param to spring mvc method that should catch param using #RequestParam :
#ResourceMapping(value="send")
public void send(ResourceResponse response,#RequestParam("message") String message) throws JsonGenerationException, JsonMappingException, IOException{
System.out.println("send method invocked");
System.out.println("message === >" + message);
.........
and my angular JS script (not work) is as follow
var message = "message="+JSON.stringify({
"name" : $scope.message.name ,
"email" : $scope.message.email ,
"tel": $scope.message.tel,
"id_subject":$scope.message.selectedSubject ,
"content" : $scope.message.content
});
console.log("valid");
$http.post('${send}', message)
.success(function(data, status, headers, config) {
})
.error(function(data, status, headers, config) {
});
method from controller throw exception (Required String parameter 'message' is not present)
please help
Controller.java:
#RequestMapping(value = "/send",
method = {RequestMethod.POST},
consumes = MimeTypeUtils.APPLICATION_JSON_VALUE)
#ResponseStatus(value = HttpStatus.OK)
public void place(#RequestBody Message msg) {
//do something with msg
}
Message.java:
public class Message {
//All your fields
private String name;
private String email
//and so on...
/*
* Getters and setters for the fields.
* You can use #Data annotation from Lombok library
* to generate them automatically for you.
*/
public String getName() { return name; }
public String getEmail() { return email; }
}
Angular part:
var message = {name: $scope.message.name, email: $scope.message.email};
$http.post('/send', message)
.success(function() {
console.log("msg sent");
})
.error(function() {
console.log("msg failed");
});
You may also need to configure Spring to use Jackson for JSON conversion:
Is it possible to convert from JSON to domain object with #RequestParam

Get a pdf (iText) through api REST using Spring MVC and AngularJS

I have a interface in Java:
#RequestMapping(value = "/api/getPdf", method = RequestMethod.POST, headers = {"content-type=application/json"}
#ResponseBody public ResponseEntity<byte[]> getPdf(#RequestBody final DatosPdf datosPdf);
Implementation:
public ResponseEntity<byte[]> getPdf(#RequestBody final DatosPdf datosPdf) {
ByteArrayOutputStream archivo = new ByteArrayOutputStream();
Document documento = new Document();
PdfWriter.getInstance(documento, archivo);
documento.open();
documento.add(new Paragraph("Hello world"));
documento.close();
archivo.close();
String filename = "hello.pdf";
byte[] documentContent = archivo.toByteArray();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.parseMediaType("application/pdf"));
headers.setContentDispositionFormData(filename, filename);
headers.setCacheControl("must-revalidate, post-check=0, pre-check=0");
ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(documentContent, headers, HttpStatus.OK);
return response;
}
Function Javascript
HttpSrv.post('api/getPdf', datosPdf).then(function(pdf) {
//CODE TO OPEN PDF FILE
}, function(errorResponse){
});
In the FRONT I receive the byte[]
The Java implementation is correct?
How I can open the pdf in the browser?
Thanks!!

Resources