I'm writing a spring rest method to get details from database and set it in a response POJO and then return it. Currently I need to produce this response in CSV instead of default json when the URL is hit using POSTMAN or RC like a downloadable CSV file with data. I googled many sites but am not sure of few logics.
Do we need to write business logic to convert pojo class values to csv format or does spring has any conversion mechanism ?
Produces = "text/csv" is being mentioned on many places, does this convert response properly ?
Currently I haven't written any code for CSV conversion.
#GetMapping("/batch/export" , produces="text/csv")
public ResponseEntity<ApplicationResponse> getBatchDetails(
HttpServletRequest request) {
ApplicationRequest appRequest = ApplicationServiceMapper.mapRequestFromHttpRequest(request);
ApplicationResponse response = appService.getDBDetails(appRequest);
return new ResponseEntity<>(response, HttpStatus.OK);
}
Here response is the one that service returns with all the data in its pojo format and if we do not give produces in annotation then by default spring will return response json. Can someone guide me? Thanks in advance.
Just using the #GetMapping with produces="text/csv" is not enough. It is only responsible for setting the response header Content-Type: text/csv.
You'll need to add the response as a parameter HttpServletResponse response, convert your POJO into a valid csv file, and only then, write the csv file into the HttpServletResponse.
Related
I am using React as frontend and Java Spring Boot as backend.
React sends JSON form data as GET/PUT/POST requests to my backend url (http://localhost:8080/test). Now, I wan't to send this JSON forward to another interfaces GET endpoint (https://another/interface/add?id={id}). This interface then queries database based on the id and answers 200 OK message with a JSON reply which I need to display (send back to frontend).
1. What is the correct way of sending a request to another interface from Spring Boot backend? In the same method I catched the frontends data?
2. I also have to set HTTP headers to the GET request, how would I go on about this?
Example of how Frontend is sending an id field as a JSON to backend:
React POST
addId = async (data) => {
return this.post(/localhost:8080/test/id, data)
}
Example of how Backend is receiving the id field:
Spring Boot POST
#PostMapping("test/id")
public String test(#RequestBody String id) {
return id;
}
As I understand you want to get data from backend with json body and httpstatuscode 200 . Am i right?
May be you can try this
#GetMapping(/interface/add)
public ResponseEntity<?> test(#RequestParam("id") String id){
//write code you want
return ResponseEntity.status(HttpStatus.OK).body("string" or dto possible);
}
ResponseEntity send body with httpstatus code and if you want to send requestparam you set #RequestParam annotation to set .
When I do project with springboot and react. I use json type to exchange data. And Most Services usually exchange data with json data type.
2.I confused about this Question if you send data React to springboot your code is right
Axios.get("localhost....", data) you can change http type with
Axios.(get, post, delete)
I have looked at the various answers and they do not resolve my issue. I have a very specific client need where I cannot use the body of the request.
I have checked these posts:
Trying to use Spring Boot REST to Read JSON String from POST
Parsing JSON in Spring MVC using Jackson JSON
Pass JSON Object in Rest web method
Note: I do encode the URI.
I get various errors but illegal HTML character is one. The requirement is quite simple:
Write a REST service which accepts the following request
GET /blah/bar?object=object11&object=object2&...
object is a POJO that will come in the following JSON format
{
"foo": bar,
"alpha": {
"century": a,
}
}
Obviously I will be reading in a list of object...
My code which is extremely simplified... as below.
#RequestMapping(method=RequestMethod.GET, path = "/test")
public Greeting test(#RequestParam(value = "object", defaultValue = "World") FakePOJO aFilter) {
return new Greeting(counter.incrementAndGet(), aFilter.toString());
}
I have also tried to encapsulate it as a String and convert later which doesnt work either.
Any suggestions? This should really be extremely simple and the hello world spring rest tut should be a good dummy test framework.
---- EDIT ----
I have figured out that there is an underlying with how jackson is parsing the json. I have resolved it but will be a write up.. I will provide the exact details after Monday. Short version. To make it work for both single filter and multiple filters capture it as a string and use a json slurper
If you use #RequestParam annotation to a Map<String, String> or MultiValueMap<String, String> argument, the map will be populated with all request parameters you specified in the URL.
#GetMapping("/blah/bar")
public Greeting test(#RequestParam Map<String, String> searchParameters) {
...
}
check the documentation for a more in depth explanation.
I'm working on a Spring MVC application and have a client that I have no control over. This client is POSTing JSON data but transmitting a application/x-www-form-urlencoded header. Spring naturally trusts this header and tries to receive the data but can't because its JSON. Has anyone had experience overriding the header that Spring receives or just specifying exactly what type of data is coming, regardless of the headers?
You can do two things;
Change the client to send the Content-Type:
application/json header
Write a Servlet Filter or Spring Interceptor which is on top of the Spring Controller and checks for the header Content-Type. If it is not application/json then it changes it to application/json.
Why don't you write a separate controller to handle application/x-www-form-urlencoded requests. If the request is a valid JSON, then you can parse it and forward it to to appropriate service.
This way you can also handle a case in future where you get request of same type which is not a valid JSON.
#RequestMapping(value = "/handleURLEncoded", method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public #ResponseBody Object handleURLEncoded(HttpEntity<String> httpEntity) {
String json = httpEntity.getBody();
//now you have your request as a String
//you can manipulate it in any way
if(isJSONValid(json)) {
JSONObject jsonObj = new JSONObject(json);
//forward request or call service directly from here
//...
}
//other cases where it's not a valid JSON
}
Note: isJSONValid() method copied from this answer
I already search tutorial in spring for method POST, insert the data with response entity (without query) and I getting error in ajax. I want to confirm, What is format url from ajax to java? below my assumption:
localhost:8080/name-project/insert?id=1&name=bobby
is the above url is correct? because I failed with this url. the parameter is id and name.
mycontroller:
#PostMapping(value={"/insertuser"}, consumes={"application/json"})
#ResponseStatus(HttpStatus.OK)
public ResponseEntity<?> insertUser(#RequestBody UserEntity user) throws Exception {
Map result = new HashMap();
userService.insertTabelUser(user);
return new ResponseEntity<>(result, HttpStatus.CREATED);
}
my daoimpl:
#Transactional
public String insertUser(UserEntity user) {
return (String) this.sessionFactory.getCurrentSession().save(user);
}
the code running in swagger (plugin maven) but not run in postman with above url.
Thanks.
Bobby
I'm not sure, but it seems that you try to pass data via get params (id=1&name=bobby), but using POST http method implies to pass data inside body of http request (in get params, as you did, data is passed in GET method) . So you have to serialize your user data on client side and add this serialized data to request body and sent it to localhost:8080/name-project/insert.
As above answer suggest. You are trying to pass data as query parameters.but you are not reading those values in your rest API.either you need to read those query parameters in your API and then form an object or try to pass a json serialized object to your Post api as recommendation. Hope it helps.
I have a web service method as follow (deployed on WebLogic 12.2.1), which I can receive the JSON request body in the POJO object "requestParameters":
#POST
#SessionChecker
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
#Path("LogIn")
public Response logIn(#Context HttpServletRequest request, Parameters requestParameters) {
....
}
I have a filter that I want to intercept the request before the above web service method is called.
#Provider
#SessionChecker
public class CheckSessionFilter implements ContainerRequestFilter {
#Context
private HttpServletRequest servletRequest;
#Override
public void filter(ContainerRequestContext requestContext) throws WebApplicationException {
....
}
}
In the filter() method, how do I get the JSON message body into the POJO object of type Parameters? I just need to get one attribute from the JSON message. After the filter is done, the JSON message should pass on to the web service method without change.
Thanks in advance.
Here's the problem. When your filter is hit, the request stream (InputStream) hasn't been read yet. So if you try to read it, then Jersey will not be able to read it, as a stream can only be read once, so it will be empty.
Jersey actually offers a solution to this. The ContainerRequestContext, is actually an instance of Jersey specific ContainerRequest. If you look at the linked API, you will find a bufferEntity() method. This allows us to read the entity, and Jersey will be able to read it again. So your first step is to make that call
#Override
public void filter(ContainerRequestContext requestContext)
ContainerRequest cr = (ContainerRequest) requestContext;
cr.bufferEntity();
}
Now you can get the entity. If you look at the API for ContainerRequest, there are also methods to readEntity(..). If you are familiar with the JAX-RS Client API, you may have before used Response#readEntity(...class) to read the response entity. The ContainerRequest#readEntity(..) works pretty much the same way.
So if you know what the JSON format is supposed to be, and you have the POJO, you could do
POJO pojo = cr.readEntity(POJO.class);
Otherwise, if the format will change from request to request, you could extract the data as a map
Map<String, Object> json = cr.readEntity(new GenericType<Map<String, Object>>(){});
UPDATE
If you are using one JAX-RS APIs, and not Jersey specific APIs, then the above is not doable. You will instead need to read the stream to get the JSON, and set the stream back, so that Jersey can read it. If might look something like
InputStream entityIn = requestContext.getEntityStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// write `entityIn` to `baos`
byte[] bytes = baos.toByteArray();
POJO pojo = new ObjectMapper().readValue(bytes, POJO.class);
// do something with POJO
requestContext.setEntityStream(new ByteArrayInputStream(bytes));
Of course you will need to some JSON deserializer to do this. I just used Jackson in the example.
It's not as elegant as the first example, but you don't have much option if you are strictly sticking the JAX-RS APIs. If you can I would suggest just adding the Jersey dependencies to your project as provided (compile-time) so that you can use the APIs, since you are using Jersey with WebLogic anyway.