JSON + Spring 3.1 - json

Hi I am trying to write small app with REST Json. I have some method that returns ArrayList of entity objects. And I am doing that:
#RequestMapping(value="/workers/", method = RequestMethod.GET)
public #ResponseBody ArrayList<Workers> showAllEmployes() throws Exception
{
ArrayList<Workers> workers = new ArrayList<Workers>();
workers = (ArrayList<Workers>) spiroService.getAllWorkers();
return workers;
}
And after this I got:
HTTP Status 500. The server encountered an internal error that prevented it from fulfilling this request.
When I try to return primitive data type then all is ok. I have nothing in server logs. And I have necessary imports. Please some tip.

Seems you have issue in produce json format, try this.
#RequestMapping(value = "/workers/", method = RequestMethod.GET,
produces={MediaType.APPLICATION_JSON_VALUE})

Related

Method has too many Body parameters

I have the following requestMethod in a RestController class and it´s working fine:
#RequestMapping(path = "/api/v1/rest/websearcher/search/results", method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public ResponseEntity<WebResultResponse> getSavedAvailability(#RequestBody final WebResultRequest navigationRequest,
#CookieValue(value = "forceSupplier", defaultValue = "") final String forceSupplier)
I´ve also a feign client working fine as well. I added a new parameter called forceSupplier in both methods, but after adding it, I´m having the issue Method has too many Body parameters but I don´t really understand why I´m receiving this message because the param is the same.
This is the method in Feign:
#RequestMapping(path = "/api/v1/rest/websearcher/search/results", method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE + ";charset=UTF-8")
ResponseEntity<WebResultResponse> getAndSavedAvailability(#RequestBody WebResultRequest webSearcherResultRequest, #CookieValue(value = "forceSupplier", defaultValue = "") String forceSupplier);
What am I doing wrong? Thanks
The annotation #CookieValue is not supported when using Spring Cloud OpenFeign. As a result, Feign sees your #RequestBody and #CookieValue parameters as the request entities, and since you only have one request entity, Feign throws the exception you are seeing.
There is currently no support for Cookies in Feign.

ResponseEntity : HTTP Status 400 – Bad Request

I have a web service that returns JSON. I am trying to print the screen using this web service spring mvc. The code I wrote is getting 400 errors. How can I resolve it?
I use json object:
{"currencyRates":[{"currencyPair":"BGN/IRR","date":1519922870105,"askPrice":4.376,"bidPrice":2.162},{"currencyPair":"ROL/LKR","date":1519922870105,"askPrice":4.056,"bidPrice":2.132},{"currencyPair":"KES/MGF","date":1519922870105,"askPrice":4.067,"bidPrice":3.005}]}
Controller:
#RequestMapping(value = "/list", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
public String userList(ModelMap model) {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<List<CurrencyRate>> rateResponse = restTemplate.exchange(
"http://localhost:8080/denemeDenemeDeneme/rates", HttpMethod.GET, null,
new ParameterizedTypeReference<List<CurrencyRate>>() {
});
List<CurrencyRate> rates = rateResponse.getBody();
model.addAttribute("list", rates);
return "list";
}
Thanks...
The problem is that the target class which cannot be a non-static inner class. It doesn't work embedded in the Controller class which I think is the problem.
The details are in here but it boils down to the way Java added inner classes means they don't have the default constructor that Jackson requires.
or Check if your class CurrencyRates does have constructor without any parameter.

No Suitable MessageConverter

I have a spring boot application and am testing integration test. My REST service produces JSON and I can confirm it when testing it in postman.
But when I make a getForObject call by restTemplate:
#Test
public void testGetObject() {
Pet pet = restTemplate.getForObject("http://localhost:9000/pets/10000", User.class, Collections.emptyMap());
assertThat(pet.getName(), is("Bobby"));
}
It fails with following error:
Could not extract response: no suitable HttpMessageConverter found for response type [class petstore.entity.User] and content type [text/html;charset=utf-8]
I read lots of posts in stackoverflow, and having that restTempalte itself has MappingJackson2HttpMessageConverter as one of default converters which has JSON as default media type then I should not get this error.
Is there anything I am missing here?
Well, the message is pretty indicative - you're getting text/html as a response type, make your endpoint return application/json. If you're using Spring MVC then you can do it by adding the produces parameter to the annotation:
#RequestMapping(value = "/pets/{id}", method = RequestMethod.GET, produces = "application/json")
Or, if you're using Jersey, add this annotation to your method:
#Produces("application/json")

Spring RESTful web-service returns 404 AFTER url is successfully called

I have a Spring MVC 4 app with Spring Security 4 and is deployed on Tomcat 8 running under jdk 1.8. The web-service has the controller defined as such:
#RequestMapping(value = "/build", method = RequestMethod.POST, produces = "application/json", headers =
{ "Accept=*/*", "Content-Type=*/*" })
public SubjectEntity build(#RequestBody SubjectImportDTO subjectImportDTO)
{
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
User user = null;
if (principal instanceof User)
{
user = ((User) principal);
}
SubjectEntity entity = service.build(subjectImportDTO);
System.out.println("FINISH: build");
return entity;
}
I am getting a csrf token, I have that setup correctly. I know the url is getting called correctly because I can see that in the logs when I get there. The service on the back-end is running, data is correctly entered into the database, I correctly get the write object, and using the Jackson Mapper, the object 'SubjectEntity' should be translated into JSON and sent back to the requesting client. This web-service has been unit tested under the Spring Web Test framework, and it works great!
So, I am familiar with an HTTP 404 error in not finding a URL when the wrong parameters are passed in, or you're trying to do a POST when it's a GET, etc. So many reasons why we can get a 404 error ...
BUT ... IN THIS CASE ... We've already gotten to the URL, executed the code, and then it has the data it needs. Since the Controller says we have content-type / and it produces application/json, I don't know what else could be wrong?
Any ideas?
You should add #ResponseBodyto your method. without this, Spring mvc tries to find another handler method which can send a response.
NB: #RestController automatically add #ResponseBody on each method in a controller.

NO JSON Result from Spring3 MVC DispatcherServlet due to AOP Configuration

When we configure Spring AOP the JSON Results disappear for : AOPExression1
<aop:pointcut id="dmhMethodExecution"
expression="within(com.aditya.dmh..*)" />
So I added an exclusion for : AOPExpression1 as AOpExpression2
<aop:pointcut id="dmhMethodExecution"
expression="within(com.aditya.dmh..*)
and !within(com.aditya.dmh.controller..*)" />
in the ASPECTJ Expression
Still I donot see my JSON results from the controller which is a restful implementation.
package com.aditya.dmh.controller;
#Controller
public class EmployeeController {
private EmployeeServiceInterface employeeService;
#Autowired
public void setEmployeeService(EmployeeServiceInterface employeeService) {
this.employeeService = employeeService;
}
#RequestMapping("/employeeservices/1/allemployees.view")
public #ResponseBody Result<EmployeeModel> getEmployees(){
return employeeService.getEmployees(0, 10);
}
}
When I use log4j for the DEBUG messages I see the following:
15:37:04.214 [http-8090-1] DEBUG o.s.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'dmhServiceDispatcher': assuming HandlerAdapter completed request handling
15:37:04.214 [http-8090-1] DEBUG o.s.web.servlet.DispatcherServlet - Successfully completed request
When I remove the AOP the JSON results start to appear and I see that the additional Debug Message.
17:11:36.270 [http-8090-2] DEBUG o.s.w.s.m.m.a.RequestResponseBodyMethodProcessor - Written [com.aditya.Result#8a85268] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#62ba2e48]
Looking at the Spring forums I understand that the Convertor is automatically configured when the
<mvc:annotation-driven/>
is used.
Is my problem of configuring AOP have anything to do with the RequestResponseBodymethodProcessor not being called.
Does this have anything to do with the proxies created around my controller when I use AOPExpression1. Why would an exclusion as in AOPExpression2 still have the problem.
Anyhelp would be appreciated
I belive that to intercept a request to a controller you should do it with MVC interceptors and not with aspects. What I did is to put into the applicationContext.xml this:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/employeeservices/1/allemployees.view"/>
<bean class="com.aditya.dmh.interceptor.ResultInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
Now, the class ResultInterceptor is where you put the code you want to be done, for instance:
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("--- preHandle --- ");
return true;
}
At least this is the way I did it.
Hope it helps.
This is a bit of a speculation:
I think what is happening is a CGLIB based dynamic proxy is getting created for your controller (although you have excluded it explicitly in your new pointcut expression), if this happens then #RequestMapping annotations are not correctly detected(by `) and so the controller is not there to handle your REST request.
Can you try a few things:
Have an interface for the controller with the exact same methods that the controller handles, and put the #RequestMapping annotations there, this will handle cases where the dynamic proxy is created and should work as expected even if the dynamic proxy gets created..
Play around a little more with your pointcut expression to see why a proxy for you controller may be getting created.
THE SOLUTION FOR OUR PROBLEM IN THIS CONTEXT
We found out that the whole thing was with the Around Advice in AOP Configuration that we have had.
Before Fix
public void logAround(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
joinPoint.proceed();
long totalTime = System.currentTimeMillis() - startTime;
log.debug(buildLogMessage(new StringBuilder().append(METHOD_AROUND_ID)
.append("[").append(totalTime).append("] ").toString(),
joinPoint));
return returnValue;
}
After Fix
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
long startTime = System.currentTimeMillis();
Object returnValue = joinPoint.proceed();
long totalTime = System.currentTimeMillis() - startTime;
log.debug(buildLogMessage(new StringBuilder().append(METHOD_AROUND_ID)
.append("[").append(totalTime).append("] ").toString(),
joinPoint));
return returnValue;
}
the void effectively made sure that the Response Object sent by the logAround was not passed on back to the RequestResponseBodyMethodProcessor
Once we had it captured & returned the cglib proxies sent the response back to the processor & had the response sent back to the client.