springtoolsuite rest service not referencing function - java

I am new to java and trying to implement a rest web service with spring tool suite. I successfully ran an example from a guide and tried to add a POST function to the basic Hello World service. The web service is running using the Spring boot App and all I can trace is that the function is not found. 404 status. Here is code:
public class GreetingController {
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
private static final Logger logger = LoggerFactory.getLogger(RestController.class);
#RequestMapping(value = "/greeting", method = RequestMethod.GET)
public #ResponseBody Greeting greeting(#RequestParam(value="name", defaultValue="World") String name, HttpServletResponse httpResponse_p,
WebRequest request_p) {
return new Greeting(counter.incrementAndGet(),
String.format(template, name));
}
// #Secured({ "ROLE_USER" })
#RequestMapping(method=RequestMethod.POST, value= {"/addNewPage/{customername}/{streamname}/{name}"})
public Greeting addName(#RequestBody String body, #PathVariable("customername") String customername, #PathVariable("streamname") String streamname,
#PathVariable("name") String name, HttpServletResponse httpResponse_p, WebRequest request_p) {
if (customername.isEmpty() || streamname.isEmpty()) {
String eMessage = "ERROR - NO PARAMETERS INCLUDED!";
httpResponse_p.setStatus(HttpStatus.BAD_REQUEST.value());
return new Greeting (counter.incrementAndGet(), String.format(template, "BAD PARAMETERS"));
}
return new Greeting(counter.incrementAndGet(), String.format("WORKING - ADDED " + name));
}
So if I paste the following in my browser:
http://localhost:8080/greeting?name=Al
I get the following correct response:
{"id":2,"content":"Hello, Al!"}
But if I try
http://localhost:8080/addNewPage/something/stream1/ABC
I get the following:
Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing
this as a fallback.
Tue Mar 24 17:19:29 EDT 2015
There was an unexpected error (type=Not Found, status=404).
No message available
could someone see what I am missing here? Or be so kind to suggest a good step by step tutorial that goes through the following functions GET/POST/PUT/DELETE?

When you paste the url in the browser you are doing a GET. Your mapping is for POST so a 404 error is what expected.
Normally when you POSTing you should have some data in the request body but anyway just for testing you can use curl to send post requests.
Here is a tutorial on how to use it for testing rest apis

Related

Spring boot returning 200 status code for custom error pages

I want to override the whitelabel error page. So as an example I have done this simple class:
#RestController
public class MyCustomErrorController implements ErrorController {
private static final String PATH = "/error";
#RequestMapping(value = PATH)
public String error() {
return "This is the error page";
}
#Override
public String getErrorPath() {
return PATH;
}
}
I have taken my example from here:
https://gist.github.com/jonikarppinen/662c38fb57a23de61c8b
According to that gist, it actually has a comment like this:
// Appropriate HTTP response code (e.g. 404 or 500) is automatically set by Spring.
// Here we just define response body.
However that's not what I'm seeing. For instance if I hit to a URL that I know that it should respond me a 500 status code (intentional NullPointerException), then that's what I should see, but when I hit to that URL I get a 200 response back with my error message ("This is the error page")
If I don't use this custom controller, then it shows me a 500 error page with the stacktrace on it, which is the default behavior. I have seen an old issue opened in 2014 here:
https://github.com/spring-projects/spring-boot/issues/684 that someone mentioning the same problem, however their solution is to show explicitly 500 responses, which does not really pass through the HTTP response code.
Just for the record, I actually put a breakpoint to org.apache.catalina.connector.Response.sendError() method. When this custom error controller does not exist, I can clearly see that sendError() method is being called with a status 500. However if I were to add HttpServletResponse argument to my error() method I do not see that the instance has 500 status code set.
Explanation
In the website example you provided, the HttpStatus is retrieved from the injected HttpServletResponse.
So the following:
Appropriate HTTP response code (e.g. 404 or 500) is automatically set by Spring.
means
Spring sets it on the HttpServletResponse that he gets injected into his method as
argument.
He then has to retrieve the status and set it on his model ErrorJson.
Solution
To follow your example, you could change your method to this:
#RequestMapping(value = ERROR_MAPPING)
public ResponseEntity<String> error(HttpServletResponse response) {
return new ResponseEntity<String>("This is the error page",
HttpStatus.valueOf(response.getStatus()));
}
I used ResponseEntity<String> instead of defining a custom object (a.k.a. ErrorJson).
As I believe you know, alternatively to using the HttpServletResponse's status, you could just set yours with HttpStatus.
Here you are simply returning a message from one method, which is not an error as per SpringBoot.
Following method will help you to return http status code as you want :
#RequestMapping(value = PATH)
public ResponseEntity<Map<String, Object>> error() {
Map<String, Object> map = new HashMap<>();
String statusMessage = "This is the error page";
String statusCode = HttpStatus.BAD_REQUEST.value();
map.put(STATUS_CODE, statusCode);
map.put(STATUS_MESSAGE, statusMessage);
return ResponseEntity.badRequest().body(map);
}

Failed to load resource: the server responded with a status of 405 | Spring MVC

Im facing a an issue while Im adding a method to the controller class with #RequestMapping(method = RequestMethod.POST) annotation. The issue is when I add this method and start application. Application unable to load resources (css,JS etc). On the browser I get:
Failed to load resource: the server responded with a status of 405 (Method Not Allowed)
and on the Run logs I get this message:
org.springframework.web.servlet.PageNotFound handleHttpRequestMethodNotSupported
WARNING: Request method 'GET' not supported
When I remove this method from the controller class, all works fine. Dont know why is this happening. Im sure its nothing to do with Configuration or resources in Dispatcher Servlet mapping because without this method every thing works perfectly fine.
I need to use this method because of some business requirement, which otherwise is not possible.
Can any body help me in Identifying where the issue is.
#Controller
public class InvoiceController
{
#RequestMapping(value = "/index", method = RequestMethod.GET)
public ModelAndView adminPage() {
String username;
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
username = auth.getName(); //get logged in username
username.toUpperCase();
// Logic to build menue based on the Role of the user.
HashMap hm = new HashMap();
OrderItems od = new OrderItems();
ModelAndView model = new ModelAndView();
model.addObject("usr", username);
//Set the object for Menue Links on the Page
model.addObject("mnue", hm);
model.setViewName("index");
model.addObject("odi",od);
return model;
}
#RequestMapping(method = RequestMethod.POST)
public String save(HttpServletRequest request,
HttpServletResponse response,
Model model)
{
System.out.println("Im here in Genaric Post Method");
return null;
}
}
Please also note that Im using Spring Security configurations. Is there anything to do with Security? Or there is some issue with Controller Class configuration.
Thanks in advance for your anticipation.
Regards,
D Kamran
Add endpoint url value to request mapping
#RequestMapping(value="/index", method = RequestMethod.POST)
This happens because Post method declared mapped to all paths as both Method and Controller class don't have that value

JerseyTest framework path encoding replaces ? with %3F

I have a failing test, which should be passing. The service works fine, but the JerseyTest JUnit test is failing with status 400.
Using Postman or a browser, when I try this URL against the deployed service:
http://localhost:8080/myService/123?appId=local&userId=jcn
I get correct result, status 200 and see the following in the log:
INFO: 4 * Server has received a request on thread http-nio-8080-exec-5
4 > GET http://localhost:8080/myService/123?appId=local&userId=jcn
Note the ? in the URL, which is correct.
But when I try this unit test in my JeryseyTest-extended Junit class:
#Test
public void getWithCorrectUrlExecutesWithoutError()
{
String x = target("myService/123?appId=local&userId=jcn").request().get(String.class);
}
it fails with a status 400, and I see this in the log:
INFO: 1 * Server has received a request on thread grizzly-http-server-0
1 > GET http://localhost:9998/myService/123%3FappId=local&userId=jcn
Note that the ? has been replaced with %3F.
I don't understand what is happening. If I try the "%3F" URL in the browser, I see the same 400 error from the unit test. So I feel somewhat certain that the encoding of the url is the problem.
Here is my Jersey resource, partial listing because it's kind of long, but I am pretty sure this is the relevant part:
#Component
#Path("/myService")
public class MyResource
{
#Autowired
SomeDao someDao;
#NotBlank
#QueryParam("appId")
private String appId;
#NotBlank
#QueryParam("userId")
private String userId;
#GET
#Path("/{id}")
#Produces(MediaType.APPLICATION_JSON)
public Status getStatus(#NotBlank #PathParam("id") String id)
{
errors = new ArrayList<>();
Status retVal;
if(validateId(id))
{
retVal = someDao.getStatus(id);
}
else
{
throw new BadParameterException(String.join(" | ", errors));
}
return retVal;
}
}
You can use the queryParam method on your WebTarget instance:
String x = target("myService/123")
.queryParam("appId", "local")
.queryParam("userId", "jcn")
.request()
.get(String.class);

How to reflect the incoming GET request in text?

I'm using Spring MVC and Springboot (assume latest version) to put up a simple web service that returns some text.
I was able to figure out how to use #RequestMapping and #PathVariable annotations to show one of the URL path variables as a response from the server (e.g. if the user goes to .../my_user_id/ in the browser, they can then see some text in the browser that includes that user_id... since the service returned it as a response).
I need help with figuring out how to capture the GET HTTP request the user's browser makes and then display it in text form as a response in the browser (I want to display the headers and the request body as plain text).
I've done some research, but none of the solutions available work properly. Is anyone aware of the right approach / feasibility here?
An approach I tried:
http://www.mkyong.com/java/how-to-get-http-request-header-in-java/
Some threads on the error I get back when I tried the above approach:
Spring RestTemplate - how to enable full debugging/logging of requests/responses?
http://forum.spring.io/forum/spring-projects/roo/84244-circular-view-path-resourcenotfound
Circular view path
How to avoid the "Circular view path" exception with Spring MVC test
http://myshittycode.com/2014/01/17/mockmvc-circular-view-path-view-would-dispatch-back-to-the-current-handler-url-view-again/
More on Spring MVC, which I'm heavily using:
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html
Anyhow. When using the below #Controller, I get an error:
#RestController
public class HelloController {
#RequestMapping("/")
public String index() {
return "Welcome to your home directory";
}
#RequestMapping(value="/mydata/{userId}", method=RequestMethod.GET)
public String printTheUser(#PathVariable String userId) {
return "The data for " + userId + " would live here";
}
#RequestMapping("/summary_data/")
public String index3() {
return "All summary data would appear here";
}
private String server = "localhost";
private int port = 8080;
#RequestMapping("/request_mirror/**")
public #ResponseBody String mirrorRest(#RequestBody String body, HttpMethod method, HttpServletRequest request,
HttpServletResponse response) throws URISyntaxException {
URI uri = new URI("http", null, server, port, request.getRequestURI(), request.getQueryString(), null);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> responseEntity =
restTemplate.exchange(uri, method, new HttpEntity<String>(body), String.class);
return responseEntity.getBody();
}
}
When running this code and navigating to localhost:8080/request_mirror/stuff3/, I get the following error:
Whitelabel Error Page. This application has no explicit mapping for /error, so you are seeing this as a fallback.
Mon Feb 08 15:41:13 EST 2016
There was an unexpected error (type=Bad Request, status=400).
Required request body content is missing: org.springframework.web.method.HandlerMethod$HandlerMethodParameter#a35a9b3f
Now, when I try a different approach (another #Controller) - the code looks like:
#Controller
#RequestMapping("/site")
public class SecondController{
#Autowired
private HttpServletRequest request;
#RequestMapping(value = "/{input:.+}", method = RequestMethod.GET)
public ModelAndView getDomain(#PathVariable("input") String input) {
ModelAndView modelandView = new ModelAndView("result");
modelandView.addObject("user-agent", getUserAgent());
modelandView.addObject("headers", getHeadersInfo());
return modelandView;
}
//get user agent
private String getUserAgent() {
return request.getHeader("user-agent");
}
//get request headers
private Map<String, String> getHeadersInfo() {
Map<String, String> map = new HashMap<String, String>();
Enumeration headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String key = (String) headerNames.nextElement();
String value = request.getHeader(key);
map.put(key, value);
}
return map;
}
}
For the above code (SecondController), (sourced from http://www.mkyong.com/java/how-to-get-http-request-header-in-java/), I get the following error, when I try to navigate to localhost:8080/site/stuff123456789... (but I can see the header keys and values from the request in the Map upon inspection... just not sure how to display them as text in the browser as the response).
This application has no explicit mapping for /error, so you are seeing this as a fallback.
Mon Feb 08 16:10:47 EST 2016
There was an unexpected error (type=Internal Server Error, status=500).
Circular view path [stuff123456789]: would dispatch back to the current handler URL [/site/stuff123456789] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)
EDIT: Use the HttpEntity to get the body in case it's empty.
I'm not sure exactly what you're trying to achieve, but think this might be close:
#RequestMapping(value="/echoRequest")
public #ResponseBody String echoRequest(HttpEntity<String> httpEntity, HttpServletRequest req) {
String out = "";
List<String> names = req.getHeaderNames();
for (String name : names) {
out += (name + ": " + req.getHeader(name) + "\n");
}
if (httpEntity.hasBody()) {
out += httpEntity.getBody();
}
return out;
}

post service is not calling throwing 400 (Bad Request)

Hi friends I am using Angularjs and rest-servies but when I am calling rest services from service.js file something is goning wrong and it is throwing 400(bad request )
main.js
garantiesService.getTarifs($scope.recap.ageDirigeant,$scope.selectedCompany.zipcode)
.success(function(){
console.log('in success');
})
service.js
healthApp.factory('garantiesService', ['$http', function($http) {
var service = {
getTarifs: function(age,zipcode)
{
console.log("age : "+age);
console.log("zipcode : "+zipcode);
var directorHealthInsuranceInfo = {};
directorHealthInsuranceInfo.age=age;
directorHealthInsuranceInfo.department=zipcode;
return $http.post('rest-service/quotes/health /director',directorHealthInsuranceInfo);
}
};
return service;
HealthInsuranceController.java
#Controller
public class HealthInsuranceQuoteResource {
#RequestMapping("quotes/health/director")
#ResponseBody
public String quoteDirector(#RequestBody DirectorHealthInsuranceInfo info) {
System.out.println("------HealthInsuranceQuoteResult------");
return "hi";
}
DirectorHealthInsuranceInfo.java
#Value
public class DirectorHealthInsuranceInfo {
private String department;
private int age;
}
when I am sending the request it is throwing Bad Request 400 error.
I see that there is a space in the url you supplied to the http.post method.
"rest-service/quotes/health /director"
I don't know if that is causing it.
But I also see that you POST your request to the service. Are you sure that your endpoint has been set up for POST requests?
I would recommend creating a basic endpoint that you call with a GET request, and no parameters. Just to root out the problem.

Categories

Resources