In my application I am using backbone.js and underscore template. I am planning to use jersey mvc feature for single page application.How to render the html page from jersey mvc viewable object?
here I am using jersey mvc feature, i am not using any third party libraries and client side i am using backbone-marrionette js and underscore template. Please find below code snippet.
public class testSubResource {
private Logger log = LoggerFactory.getLogger(getClass());
#Context
private UriInfo uriInfo;
#Inject
private TestService service;
public TestSubResource(TestService service, UriInfo uriInfo) {
super();
this.service = service;
this.uriInfo = uriInfo;
}
#GET
#Template
#Produces({MediaType.TEXT_HTML})
public Viewable details(#PathParam("id") String id) {
log.info("get test details:{}", id);
JsonObject response = null;
try{
response = service.getTestDetails(id);
}
catch(Exception ex) {
throw ex;
}
return new Viewable("/test", response);
}}
Here it return the json response. I need to pass the json response to jsp...
Related
I have an ASP.NET CORE application that sends a POST/GET request to a REST (Orthanc Rest API). The issue is I receive the result and convert it to a JSON, but postman shows as an empty array. here is my code:
// GET Method
public class PACSController : ControllerBase
{
// GET: api/PACS
[HttpGet]
public async Task<object> Get()
{
var result = await Orthanc.Orthanc.InstanceAsync();
return result;
}
}
public class Orthanc
{
public static string baseUrl = "https://demo.orthanc-server.com/";
public static async Task<object> InstanceAsync()
{
string url = baseUrl + "instances";
using (HttpClient client = new HttpClient())
using (HttpResponseMessage res = await client.GetAsync(url))
using (HttpContent content = res.Content)
{
string data = await content.ReadAsStringAsync();
if (data != null)
{
Console.WriteLine(data);
}
var jData = JsonConvert.DeserializeObject(new string[] { data }[0]);
return jData;
}
}
}
The result of request inside the code
Postman result
As part of the work to improve the ASP.NET Core shared framework, Newtonsoft.Json has been removed from the ASP.NET Core shared framework for asp.net core 3.x.
Follow the steps:
Install the Microsoft.AspNetCore.Mvc.NewtonsoftJson package on nuget.
Install-Package Microsoft.AspNetCore.Mvc.NewtonsoftJson
Update Startup.ConfigureServices to call AddNewtonsoftJson.
services.AddControllersWithViews().AddNewtonsoftJson();
Reference:
https://learn.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.1&tabs=visual-studio#use-newtonsoftjson-in-an-aspnet-core-30-mvc-project
I have the POST request api call to accept the json body request parameters and multipart file from client side(postman or java client).
I want to pass both the json data and multipart file in single request.
I have written the code like below.
#RequestMapping(value = "/sendData", method = RequestMethod.POST, consumes = "multipart/form-data")
public ResponseEntity<MailResponse> sendMail(#RequestPart MailRequestWrapper request) throws IOException
But, i could not accomplish it using postman rest client.
I'm using spring boot on server side.
Could anyone suggest me on this question.
Thanks in advance,
You cat use #RequestParam and Converter for JSON objects
simple example :
#SpringBootApplication
public class ExampleApplication {
public static void main(String[] args) {
SpringApplication.run(ExampleApplication.class, args);
}
#Data
public static class User {
private String name;
private String lastName;
}
#Component
public static class StringToUserConverter implements Converter<String, User> {
#Autowired
private ObjectMapper objectMapper;
#Override
#SneakyThrows
public User convert(String source) {
return objectMapper.readValue(source, User.class);
}
}
#RestController
public static class MyController {
#PostMapping("/upload")
public String upload(#RequestParam("file") MultipartFile file,
#RequestParam("user") User user) {
return user + "\n" + file.getOriginalFilename() + "\n" + file.getSize();
}
}
}
and postman:
UPDATE
apache httpclient 4.5.6 example:
pom.xml dependency:
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.6</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.6</version>
</dependency>
<!--dependency for IO utils-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
service will be run after application fully startup, change File path for your file
#Service
public class ApacheHttpClientExample implements ApplicationRunner {
private final ObjectMapper mapper;
public ApacheHttpClientExample(ObjectMapper mapper) {
this.mapper = mapper;
}
#Override
public void run(ApplicationArguments args) {
try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
File file = new File("yourFilePath/src/main/resources/foo.json");
HttpPost httpPost = new HttpPost("http://localhost:8080/upload");
ExampleApplication.User user = new ExampleApplication.User();
user.setName("foo");
user.setLastName("bar");
StringBody userBody = new StringBody(mapper.writeValueAsString(user), MULTIPART_FORM_DATA);
FileBody fileBody = new FileBody(file, DEFAULT_BINARY);
MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
entityBuilder.addPart("user", userBody);
entityBuilder.addPart("file", fileBody);
HttpEntity entity = entityBuilder.build();
httpPost.setEntity(entity);
HttpResponse response = client.execute(httpPost);
HttpEntity responseEntity = response.getEntity();
// print response
System.out.println(IOUtils.toString(responseEntity.getContent(), UTF_8));
} catch (Exception e) {
e.printStackTrace();
}
}
}
console output will look like below:
ExampleApplication.User(name=foo, lastName=bar)
foo.json
41
You can use both of them.
#RequestPart : This annotation associates a part of a multipart request with the method argument, which is useful for sending complex multi-attribute data as payload, e.g., JSON or XML.
In other words Request Part parse your json string object from request to your class object. On the other hand, Request Param just obtain the string value from your json string value.
For example, using Request Part:
#RestController
#CrossOrigin(origins = "*", methods= {RequestMethod.POST, RequestMethod.GET,
RequestMethod.PUT})
#RequestMapping("/api/api-example")
public class ExampleController{
#PostMapping("/endpoint-example")
public ResponseEntity<Object> methodExample(
#RequestPart("test_file") MultipartFile file,
#RequestPart("test_json") ClassExample class_example) {
/* do something */
}
}
and postman would be configured like:
#RequestParam : Another way of sending multipart data is to use #RequestParam. This is especially useful for simple data, which is sent as key/value pairs along with the file, as I said, just key/value. Also is used to get value from query params, I think that is its main goal.
I was stuck with this problem for past few hours
So I came across this question.
Summary:
Use #ModelAttribute instead of #RequestBody.
#ModelAttriute will work just like other normal(without multipart property in entity) Entity mapping.
You have two options -
Send a MultipartFile along with json data
public void uploadFile(#RequestParam("identifier") String identifier, #RequestParam("file") MultipartFile file){
}
OR
Send Json data inside a MultipartFile and then parse Multipart file as mentioned below and thats it.
public void uploadFile(#RequestParam("file") MultipartFile file){
POJO p = new ObjectMapper().readValue(file.getBytes(), POJO.class);
}
I explain all here in answer part:
enter link description here
I implement a client application. This application consume a Rest webservice and these service return and html page as a variable in a model.
I take these html page successfully from Rest Service and try to write to a blank html page.
My code to write html page.
public void writeToHtml(ResponseModel response) {
FileWriter fWriter = null;
BufferedWriter writer = null;
try {
fWriter = new FileWriter(src/main/resources/templates/test.html);
writer = new BufferedWriter(fWriter);
writer.write(response.getHtmlPage());
writer.newLine();
writer.close();
} catch (Exception e) {
}
}
These function can take htmlPage from ResponseModel and write successfully to test.html
Untill there everthing work properly and my controller display it on secreen.
However, if I again call same Rest service, it can again write to "test.html" but, on the screen it shows the first created html page.
Probably it cache the first html and if I rewrite again. I just take cache one.
My Controller
#RequestMapping(value = "/testPath", method = RequestMethod.POST)
public String payment(RequestModel paymentInfoModel, BindingResult bindingResult, Model model) {
RestTemplate restTemplate = new RestTemplate();
ResponseModel response = restTemplate.postForObject(url, request, ResponseModel.class);
writeToHtml(response);
return "test";
}
Could you help me to solve these issue ?
IDEA : Inteliji
I solved my problem a bit differently:
#RequestMapping(value = "/testPath", method = RequestMethod.POST, produces = "text/html")
#ResponseBody
public String payment(RequestModel paymentInfoModel, BindingResult bindingResult, Model model) {
RestTemplate restTemplate = new RestTemplate();
ResponseModel response = restTemplate.postForObject(url, request, ResponseModel.class);
writeToHtml(response);
return response.getHtmlPage();
}
So I don't need to create an HTML page.
I have the following situation:
My REST API one:
#RestController
#RequestMapping("/controller1")
Public Class Controller1{
#RequestMapping(method = RequestMethod.POST)
public void process(#RequestBody String jsonString) throws InterruptedException, ExecutionException
{
............
}
}
JSON POST request, request1, for the REST API(Controller1):
{
"key1":"value1",
"key2":"value2"
}
My REST API two:
#RestController
#RequestMapping("/controller2")
Public Class Controller2{
#RequestMapping(method = RequestMethod.POST)
public void process(#RequestBody String jsonString) throws InterruptedException, ExecutionException
{
............
}
}
JSON request, request2, for the REST API(Controller2):
{
"key1":"value1",
"key2":"value2",
"key3":"value3"
}
I have several such "primitive" requests.
Now, I am expecting a JSON request, let's call it request3, which is a combination of such "primitive" queries- something that looks like below:
{
{
"requestType":"requestType1",
"request":"[{"key1":"value1","key2":"value2"}]"
},
{
"requestType":"requestType2",
"request":"[{"key1":"value1","key2":"value2","key3":"value3"}]"
}
}
Here, I need to trigger the respective API (one or two) upon identifying the query type. I wanna know how I can forward the request to the corresponding REST API. I wrote the REST API for request3 like below:
#RestController
#RequestMapping("/controller3")
Public Class Controller3{
#RequestMapping(method = RequestMethod.POST)
public void process(#RequestBody String jsonString) throws InterruptedException, ExecutionException
{
..................
..................
switch(request){
case request1: //how to call REST API 1?
case request2: //how to call REST API 2?
}
}
}
You can call a utility method which posts request to controller using Rest Template as below. Since you are using POST method it's easy to send parameters using Rest Template. You may need to edit this code a bit to work in your environment with exact syntax.
#RequestMapping( value= "/controller3" method = RequestMethod.POST)
public #ResponseBody void process(#RequestBody String jsonString){
String request = requestType //Get the request type from request
String url = "";
MultiValueMap<String, String> params= null;
switch(request){
case request1: //how to call REST API 1?
url = "/controller1";
params = request1param //Get the parameter map from request
case request2: //how to call REST API 2?
url = "/controller2";
params = request2Param //Get the parameter map from request
}
//Now call the method with parameters
getRESTResponse(url, params);
}
private String getRESTResponse(String url, MultiValueMap<String, String> params){
RestTemplate template = new RestTemplate();
HttpEntity<MultiValueMap<String, String>> requestEntity=
new HttpEntity<MultiValueMap<String, String>>(params);
String response = "";
try{
String responseEntity = template.exchange(url, HttpMethod.POST, requestEntity, String.class);
response = responseEntity.getBody();
}
catch(Exception e){
response = e.getMessage();
}
return response;
}
Redirect from one controller method to another controller method
Alternatively you also can call the rest method using Rest Template
Spring MVC - Calling a rest service from inside another rest service
You may find how to send POST request with params in this post
https://techie-mixture.blogspot.com/2016/07/spring-rest-template-sending-post.html
While implementing a File Uploader controller in Spring MVC I stucked with one problem. My code snap is given below.
#Controller
public class FileUploader extends AbstractBaseController implements HandlerExceptionResolver
{
#RequestMapping(value = "/uploadFile", method = RequestMethod.POST)
#ResponseBody
public JSONObject handleFileUpload(#RequestParam("file") MultipartFile file)
{
JSONObject returnObj = new JSONObject();
if (file.isEmpty())
{
returnObj.put("success", "false");
returnObj.put("message", "File is empty");
}
else
{
try
{
//my file upload logic goes here
}
catch (Exception e)
{
returnObj.put("success", "false");
returnObj.put("message", "File not uploaded.");
}
}
return returnObj;
}
#Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object obj, Exception exception)
{
ModelAndView model = new ModelAndView();
Map map = new HashMap();
if (exception instanceof MaxUploadSizeExceededException)
{
// I want to return JSONObject from here like given below.
/**
* { "message":"File size exceeded", "success":"false" }
* */
map.put("message", "File size exceeded");
map.put("success", "false");
model.addObject(map);
}
return model;
}
}
and my spring configuration look likes
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver" >
<property name="maxUploadSize" value="300000"/>
</bean>
now In my controller I want to return JSONObject instead of ModelAndView in resolveException method in my controller as given in code snap because I am developing some like REST method to upload file.
any ideas?
Thanks
If you use the Spring 3.2 above, I recommend this way.
At first, declare the ControllerAdvice.
#Controller
#ControllerAdvice
public class JAttachfileApi extends BaseApi
And make the Exception Handler to response JSON Object as following.
#ExceptionHandler(MaxUploadSizeExceededException.class)
public #ResponseBody Map<String,Object> handleMaxUploadSizeExceededException(
MaxUploadSizeExceededException ex)
{
Map<String,Object> result = getResult();
JFileUploadJsonResponse errorResult = new JFileUploadJsonResponse();
errorResult.setError("Maximum upload size of "+ex.getMaxUploadSize()+" bytes exceeded.");
List<JFileUploadJsonResponse> resultData = new ArrayList<JFileUploadJsonResponse>();
resultData.add(errorResult);
result.put("files", resultData);
return result;
}
You simply can annotate the method resolveException as #ExceptionHandler() and then you can have its signature like any other controller method. So placing #ResponseBody before the return type should work.
"Much like standard controller methods annotated with a #RequestMapping annotation, the method arguments and return values of #ExceptionHandler methods can be flexible. For example, the HttpServletRequest can be accessed in Servlet environments and the PortletRequest in Portlet environments. The return type can be a String, which is interpreted as a view name, a ModelAndView object, a ResponseEntity, or you can also add the #ResponseBody to have the method return value converted with message converters and written to the response stream."