I am working on the Spring Boot web application. I am running two different application one for service (Rest Resource) and other one is UI which show the request on HTML page on the bases of response got on the rest request.
My all rest services are created by
#Component
#Api(value = "/api/1/registration", description = "Access and manage your information")
#Path("/api/1/registration")
#Produces(MediaType.APPLICATION_JSON)
#Slf4j
public class RegistrationResource {
...
...
#ApiOperation(value = "Find user by id", notes = "Return a user by id", response = Registration.class)
#Path("/{id}")
#GET
#Timed
#Override
public Registration get(#PathParam("id") String id) {
// my logic
}
}
Restangular Request
Restangular.one("registration/1").get().then(function (data) {
...
},function(error) {
...
});
When I do restangular request from ui, its working fine. Now I need to have a servlet resource. For that I create new resource class
#Slf4j
#RestController
#RequestMapping("/api/1/test")
public class DownloadResource{
#RequestMapping(value = "/downloadtesting", method = RequestMethod.GET)
public void download(HttpServletResponse response, HttpServletRequest request){
// I need to call this method... How can I
}
}
FYI: All my resources are registered as following...
Reflections reflections = new Reflections("com.sample.resource");
Set<Class<? extends Object>> resources =
reflections.getTypesAnnotatedWith(Path.class); //
resources.forEach(r -> {
log.debug("Registering resource " + r);
register(beanFactory.getBean(r));
});
// Same I did for RequestMapping.class also but I am getting 404 error for downloadtesting api.
NOTE: If I try with following version for downloadtesting in RegistrationResource then I am getting HttpServletRequest / Response null.
public class RegistrationResource{
#Path("/downloadtesting")
public void download(HttpServletResponse response, HttpServletRequest request){
// I need to call this method... How can I
}
}
Can any one help me?
Related
I am using Quarkus framework with RestEasy to REST communication.
Everything works great when response code is 200 etc. When client gets an error code e.g. 400 Bad Request resteasy returns WebApplicationException and I can`t reach response body.
MyService.java
#Path("/")
#RegisterRestClient
#RegisterProvider(value = ClientLoggingFilter.class, priority = 100)
public interface MyService {
#POST
#Path("/foo")
#Consumes(MediaType.APPLICATION_JSON)
MyRespnse create(MyRequest request);
I`ve been trying to read entity from WebApplicationException but entity is always null. In Postman service returns body like:
{
"error" : {
"id" : "id does not exist"
}
}
Look into http://download.eclipse.org/microprofile/microprofile-rest-client-1.0/apidocs/org/eclipse/microprofile/rest/client/ext/ResponseExceptionMapper.html
#Provider
public class CustomResponseExceptionMapper implements ResponseExceptionMapper<RuntimeException> {
public CustomResponseExceptionMapper () {
}
public boolean handles(int statusCode, MultivaluedMap<String, Object> headers) {
}
public CusomExceptionMapper toThrowable(Response response) {
try {
String responseString = (String)response.readEntity(String.class);
............
}
}
}
Or
public class CustomExceptionMapper
implements ResponseExceptionMapper<Throwable> {
}
Register the ResponseExceptionMapper Provider:
#Path("/xyz")
#RegisterProvider(CustomResponseExceptionMapper.class)
#RegisterRestClient
#Timeout
I am trying to create an account controller using Spring Boot. I have an html file for the login page located under static/login.html. The page loads perfectly fine when I do not map a POST request to the same path.
I have an AccountController class:
#RestController
public class AccountController {
#RequestMapping(value = "/login", method = RequestMethod.POST)
public Account login(#RequestBody Map<String, Object> body) {
// code
}
}
This controller disables the GET request to the html page. When trying to access the page, I receive;
There was an unexpected error (type=Method Not Allowed, status=405).
Request method 'GET' not supported
So my question is essentially, how do I get both the POST and GET request working at the same time. If there is a better file structure I can use for the static content, please suggest it.
This should work
#RequestMapping(value = "/login", method = { RequestMethod.GET, RequestMethod.POST })
public Account login(#RequestBody Map<String, Object> body) {
// code
}
This way, the controller mapping will be available for both methods
UPDATE
#RequestMapping(value = "/login", method = RequestMethod.GET)
public String serveLogin(... (if needed) ) {
// code to serve your static content
return "index.html";
}
#RequestMapping(value = "/login", method = RequestMethod.POST)
public Account login(#RequestBody Map<String, Object> body) {
// code to handle your login form POST submit
}
I wrote a REST Call which will return health status when called
#RestController
#RequestMapping(value = "/account")
public class HealthCheckController {
protected final Logger log = LoggerFactory.getLogger(this.getClass());
#RequestMapping(value = "/health", method = RequestMethod.GET, produces = { "application/json" })
#ResponseStatus(HttpStatus.OK)
#ApiOperation(value = "Returns the health status of the application", notes = "Load balancer user this to confirm the health of the node")
public #ResponseBody String getHealth(HttpServletRequest request, HttpServletResponse response) throws Exception {
log.info("***" + RequestCorrelation.getId() + "***" + "HealthCheckController - getHealth () Called");
return "{\"health\":{\"SERVICES\":\"OK\"}}";
}
}
When I open this in swagger or postman it returns proper response. But when i hit this URL in chrome browser i am seeing
This page contains the following errors:
error on line 1 at column 1: Document is empty
Below is a rendering of the page up to the first error.
Why so? and how to fix this?
Having the same issue. Have an object with the following class annotations and method:
#Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
#Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
#GET
#Path("version")
public String getVersion() { return "v1"; }
Added MediaType.TEXT_PLAIN to the end of the #Produces annotation. Didn't work.
Moved it the beginning of the #Produces annotation. Didn't work.
Moving/Adding it to the method resolved the issue for me. Your client will need to be able to accept that media type as well.
#GET
#Path("version")
#Produces({MediaType.TEXT_PLAIN})
public String getVersion() { return "v1"; )
HTH
In your getHealth() method, you're returning a String but in your #RequestMapping annotation, you specify that your method will produce JSON.
Try one of these:
#RequestMapping(value = "/health", method = RequestMethod.GET, produces = { "text/plain" })
//Now, pass Accept = "text/plain" in the request header:
or
#RequestMapping(method = RequestMethod.GET, produces = { MediaType.APPLICATION_JSON_VALUE })
public List<String> getHealth(..) {
/*
...
*/
ArrayList<String> list=new ArrayList();
list.add("Health OK");
return list;
}
This would give you
["Health OK"] in the response.
Try to return not a String but
return new ResponseEntity<>(yourString, HttpStatus.OK);
and also change this
public #ResponseBody String getHealth(HttpServletRequest request, HttpServletResponse response) throws Exception {
to this
public #ResponseBody ResponseEntity<String> getHealth(HttpServletRequest request, HttpServletResponse response) throws Exception {
And if it doesn't work, try to add .xml or .json to the end of your URL, when you accessing it in browser.
I'm using Java 8, Tomcat 8, Spring-WebMVC 4.2.2.RELEASE, FasterXML 2.6.3.
I have the following method in my controller
#RequestMapping(method = RequestMethod.POST)
#ResponseBody
public void updateCurrentUserDetails(#RequestBody final UserDTO userDTO) {
final UserWithId user = SecurityUtil.getCurrentUser();
this.userAccountService.updateUserDetails(user.getUserId(), user.getUsername(), userDTO);
}
This method returns void which resolves in an empty (0 byte) response. However the clients connecting to the server always expect JSON reponses even, if its an empty response.
So I would like to configure Spring/Jackson to return {} (2 byte) in that case.
I already thought about returning new Object() everywhere in the calls that would return void otherwise but IMO this is a dirty soution and there must be something better.
There shouldn't be any need to do all that. You can just use a 204 response code, which is made for the situation you are describing. You don't even need the ResponseBody annotation, just use:
#RequestMapping(method = RequestMethod.POST)
#ResponseStatus(HttpStatus.NO_CONTENT)
public void updateCurrentUserDetails(#RequestBody final UserDTO userDTO) {
final UserWithId user = SecurityUtil.getCurrentUser();
this.userAccountService.updateUserDetails(user.getUserId(), user.getUsername(), userDTO);
}
204 response code:
The 204 (No Content) status code indicates that the server has
successfully fulfilled the request and that there is no additional
content to send in the response payload body.
Its quite easy.
Just add the following to your spring xml/java config
<mvc:interceptors>
<bean class="de.st_ddt.util.VoidResponseHandlerInterceptor" />
</mvc:interceptors>
And add this class to your classpath
public class VoidResponseHandlerInterceptor extends HandlerInterceptorAdapter {
private static final String voidResponse = "{}";
#Override
public void postHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler,
final ModelAndView modelAndView) throws IOException {
// Returned void?
if (!response.isCommitted()) {
// Used ModelAndView?
if (modelAndView != null) {
return;
}
// Access static resource?
if (DefaultServletHttpRequestHandler.class == handler.getClass()) {
return;
}
response.setStatus(200);
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
try (final Writer writer = response.getWriter()) {
writer.write(voidResponse);
}
response.flushBuffer();
}
}
}
I have wrote spring rest Async controller, that return String JSON response,
When I request the browser complete the response, while the controller have not completed the processing hence the response is not ready.
I am using Spring Boot, Apache as inbuilt server.
In EmbeddedServletContainerFactory I have set AsyncTimeout too.
TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();
factory.addConnectorCustomizers(new TomcatConnectorCustomizer() {
#Override
public void customize(Connector connector) {
connector.setAsyncTimeout(10000000);
}
});
so How I make the browser wait while the controller Async'ly complete the response?
And the controller is
#Async
#RequestMapping(value = "/id", method = RequestMethod.GET)
public String getDetails(#PathVariable("id") String id) {
// wrote logic for JSON response....
}