I've created a basic RESTful Roo application using the following Roo-script (Roo 1.1.5).
project --topLevelPackage com.roorest
persistence setup --provider HIBERNATE --database HYPERSONIC_IN_MEMORY
entity --class ~.domain.MyClass
field string --fieldName String1
web mvc setup
web mvc all --package ~.web
json all
When I access the RESTful WS asking for application/json the WS spits out a valid json body, however the content type is set to application/text (which makes perfect sense if one looks at the generated (aj) controller code ticking in the background).
Unfortunately, I need to have the WS return a content type of application/json. I've tried to push in the necessary methods from the json-controllers, however this seems 1) cumbersome, 2) not really working (I'm getting a LOT of errors with the pushed in source).
Can one force the WS return application/json on a general basis? For instance, is it possible to combine ContentNegotiatingViewResolver with the roo generated aj controllers? (And why does the roo generated code explicitly set application/text as it's content type in the first place? Is hacking the roo JSON addon a viable solution?)
I guess what I'm really asking is this: what do you think is the best way to make a roo scaffolded application return domain objects as application/json through a WS?
Did you solve the problem, because I just having the same one...?
Okay, I do have one solution: Add the methods to your controller and do not let the AOP Framework add them:
#RequestMapping(headers = "Accept=application/json")
#ResponseBody
public ResponseEntity<String> listJson() {
HttpHeaders headers = new HttpHeaders();
headers.add("Content-Type", "application/json; charset=utf-8"); //was app/text
return new ResponseEntity<String>(Customer.toJsonArray(Customer
.findAllCustomers()), headers, HttpStatus.OK);
}
Related
I am trying to develop a microservice using Spring MVC and Spring Boot. In my service I am giving result back as JSON encoded format. Currently I added action like:
#RequestMapping("/checkUsers")
public String checkLogin() throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
List<Users> useObj = (List<Users>) userRepo.findAll();
return(mapper.writeValueAsString(useObj));
}
And now I found the other options through the following method
produces={"application/json; charset=UTF-8"}
Here I am not sure which method is properly using for encoding the data into JSON format in Spring. How can I proceed?
Why don’t you just use
ResponseEntity
And return
new ResponseEntity<String>(“your message”, HttpStatus.OK);
#RequestMapping(method = GET, value = "my/random/uri", produces = "application/json;charset=UTF-8")
Here produces attribute inside my #RequestMapping annotation is the producible media types of the mapped request. The format is a single media type or a sequence of media types, with a request only mapped if mentioned one matches one of these media types. and here, my #RequestMapping annotation is already serving my purpose of encoding.
Now somewhere from Spring Boot documentation:
Spring Boot is a brand new framework designed to simplify the bootstrapping and development of a new Spring
application. The framework takes an opinionated approach to
configuration, freeing developers from the need to define boilerplate
configuration.
Please don't kill the purpose of Spring Boot. :)
Additionally, I would suggest you use org.springframework.http.MediaType class. It has got all encoding types you'll ever require. Happy coding.
Please let me know if you face any difficulty while going with suggested approach.
If you use #RestController on your controller, all request mappings will produce application/json by default.
Also, there is no need to to the object mapping yourself, just return the object without mapping and let Spring/Jackson do its thing.
#RestController
public class UsersController {
// #RequestMapping("/checkUsers")
// There is an even simpler and more concise
#GetMapping("/checkUsers")
public List<User> checkLogin() throws JsonProcessingException {
return userRepo.findAll();
}
}
I have spent two days on this with no luck. I have a project that uses jersey and jackson. It was working fine with JSON requests and tried to add XML also, after adding a couple of jars, it worked also with XML.
The problem was that for requests with no parameters (neither JSON nor XML), the API was retrieving XML instead JSON (we want JSON by default).
My code for requests looks like this:
#POST
#Produces({"application/json", "application/xml"})
#Consumes({"application/json", "application/xml"})
public TokenResponse authenticateUser(Credentials credentials) {//code here}
In another post a saw that this is a Jetty bug that is resolved in version 2.16, so I decided to migrate to 2.51.1 with no luck. The JSON request works fine, but when I send the xml post (with postman) the server returns an "Unsupported Media Type" error.
I have also tried with version jersey 2.17 because it works with the same jackson libraries than 2.7 and the result is the same than before.
I am not using maven so here it is a copy of the libraries I have used for the three cases:
1.- JSON and XML works but XML is always returned by default:
2.- JSON works but XML requests returns Unsupported Media Type
3.- JSON works but XML requests returns Unsupported Media Type
Thank you in advance
Finally, instead of updating the libraries I have decided to use the version I had already and add the solution below to #Produces annotation
How to set to default to json instead of xml in jersey?
Setting a qs factor to each media type as mentioned in this answer should work. It can take values between 0 (undesirable) and 1 (highly desirable):
#Produces({ "application/json; qs=1", "application/xml; qs=.5" })
If you don't want to change every single #Produces annotation, you can use a filter to add the Accept: application/json header if it's not present.
#Provider
#PreMatching
public class DefaultAcceptHeaderFilter implements ContainerRequestFilter {
#Override
public void filter(ContainerRequestContext requestContext) throws IOException {
MultivaluedMap<String, String> headers = requestContext.getHeaders();
if (!headers.containsKey(HttpHeaders.ACCEPT)) {
headers.putSingle(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON);
}
}
}
It will ensure that your resource methods will produce JSON even when the Accept header is not sent by the client.
I have been creating Spring RESTful services for a while and typically I am building my own services so I create domain objects and populate them and the framework takes care of the conversion to JSON.
I have a situation now where I simply need my service to act as a pass through to another system's service that is already RESTful and returns JSON.
URL https://:/service/serviceInfo
Method GET
HTTP Content Type Produces: application/json
I simply want to wrap this call (I will apply some security checks on the service) and pass that JSON returned straight back to my service without mapping it back to Java objects, only to return as JSON to the client. Is there a simple way to do this, with minimal code?
Thanks in advance.
Can you see if this works for you?
#RequestMapping("/child")
public String testMethod(#RequestParam String param) {
return new RestTemplate().exchange("https://api.twitter.com/1/statuses/user_timeline.json", HttpMethod.GET, null, String.class).getBody();
}
You just replace the url for your own. I can also guide you to using the RestTemplate with POST or DELETE requests etc. if you need. Also adding parameters or headers if you need. I've used it extensively in some projects.
I have a WCF service that allows me make a request using an DTO and replies with a DTO for a WPF application. For example I pass a filter object for products which has a few properties for things I want to filter on and a couple of extras for paging, (the server will take care processing the filter object and getting the data) an example is like this.
public async Task<ObservableCollection<ProductListItem>> GetProductList(ProductFilter filter, int startIndex, int pageSize, string sortBy)
I am wondering if there exists any other technologies beside WCF that allow such an operation, From my preliminary research which may be quite off is that WebAPI uses the GET, POST, PUT verbs and routing rules which is quite different.
ServiceStack looks like it might be able to do this I can see on slide 37 at https://servicestack.net/features
it says.
List<Product> productOver2Bucks = client.Get(new FindProducts{PriceGreaterThan = 2})
Which seems pretty close but might still require Rest verbs as it uses a Get().
I don't know it it is FUD or not but I have been reading that soap over WCF is believed by some to be a legacy technology and JSON is the way of the future. So is there a replacement technology that will work with a method signature to the one I have above? That i could call from platforms such as Windows universal applications.
In ServiceStack if you design your Service with the Any method name, e.g
public object Any(Request request)
{
return new Response { ... };
}
This will allow calling this Service from Any HTTP Verb on any Format or endpoint (e.g. JSON, XML, MsgPack, Protocol Buffers, SOAP, Message Queue's, etc).
Also you don't need to define any [Route] for your Request DTO's since it will automatically fallback into using the pre-defined Routes when none are available.
public class Request : IReturn<Response> { ... }
public class Response { }
So with the above Service you can use ServiceStack .NET ServiceClients to call the API's using any verb, e.g:
var client = new JsonServiceClient(baseUrl);
Response response = client.Get(new Request { ... });
Response response = client.Post(new Request { ... });
When preferred you can also use the async API's, e.g:
var response = await client.GetAsync(new Request { ... });
var response = await client.PostAsync(new Request { ... });
Which if you don't care for using verbs you can use the generic Send API, e.g:
Response response = client.Send(new Request { ... });
Which just uses POST underneath, although it's highly recommended to use Get for "read only" queries as it will allow the Services HTTP responses to be cached by any intermediate HTTP Middleware or proxies.
Add ServiceStack Reference
Also if you're coming from WCF you'll also enjoy ServiceStack's, Add ServiceStack Reference which provides a number of advantages over WCF's Add Service Reference feature but still provides the same utility in being able to generate a typed API from a remote url for:
C# Add Reference
F# Add Reference
VB.NET Add Reference
TypeScript Add Reference
With more languages to follow.
Advantages over SOAP
Whilst ServiceStack still enables WSDL's, XSD's for your Services so they can be called from SOAP 1.1/1.2 endpoints for legacy compatible reasons - there are a number of reasons why using clean HTTP and JSON/XML API's are preferred.
I've got a web application built over Spring MVC, already working. I'm planning to give mobile users an app for communicating with the server, so they will find easier to interact with it. I've got the Model, the Views and the Controllers working fine, but everything was designed from the web's perspective.
So, I'm building up a few new Controllers for the mobile app, and here comes the question: since the ultimate rresponsible of the View is going to be the mobile app in question, where should I delegate everything to the app, in the Controller (preparing there a JSON for each response)? Or should I have a JSP with some JSON taglib enabled, so that the Controller gives the pieces to the JSP, and then I build the JSON response in the JSP?
I'm not clear about the MVC architecture on this scenario.
Thanks in advance.
When all you are doing is creating a REST API which mobile (or other clients) are going to use, Views do not come into play. It's the responsibility of the Controller to prepare the appropriate response for the client.
Luckily since returning JSON is such a common scenario, Spring MVC transparantly handles the serialization into JSON (using the Jackson library) so you don't have to.
As JB Nizet showed, you can use the #ResponseBody annotation to tell Spring MVC that the response should be returned as is (serialized to JSON because of the produces = MediaType.APPLICATION_JSON_VALUE) or if you are using Spring 4, you can completely ditch the #ResponseBody annotation and annotate your Controller with #RestController (which makes Spring behave as if #ResponeBody was added to every method mapping) instead of #Controller.
The controller methods should simply return obejcts (or collections of objects), that will be serialized to JSON automatically thanks to the #ResponseBody annotation:
#RequestMapping(value = "/api/users",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseBody
public List<User> listUsers() {
...
}