org.springframework.web.HttpMediaTypeNotSupportedException - spring-boot

when i am trying to get values by id ..i got error like this in postman
{
"timestamp": 1547708533031,
"status": 500,
"error": "Internal Server Error",
"exception":"org.springframework.http.converter.HttpMessageNotWritableException",
"message": "Could not write JSON: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS); nested exception is com.fasterxml.jackson.databind.JsonMappingException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) (through reference chain: com.Cetegory.Entites.ArtistRegister[\"subcetgory\"]->com.Cetegory.Entites.SubCetegory_$$_jvst706_1[\"handler\"])",
"path": "/getartist/2"
}
this is contoller for get data by id
#RestController
public class RegisterController {
#Autowired
ArtistService artser;
#PostMapping(value="/addArtist",produces="application/json")
#ResponseBody public ArtistRegister addArtist(#RequestBody ArtistRegister artist) {
ArtistRegister artRegister = null;
try {
artRegister = artser.addArtist(artist);
} catch (Exception e) {
e.printStackTrace();
}
return artRegister;
}
#RequestMapping(value="/getartist/{artist_id}",method=RequestMethod.GET,produces="application/json")
#ResponseBody public ArtistRegister getArtistDetails(#PathVariable ("artist_id") int artist_id ,HttpServletRequest request,
HttpServletResponse response) throws Exception{
return artser.getArtistDetails(artist_id);
}
#RequestMapping(value="/delete/{artist_id}",method=RequestMethod.DELETE,produces="application/json")
public void deleteById(#PathVariable (value="artist_id") int artist_id,HttpServletRequest request,
HttpServletResponse response) throws Exception{
artser.deleteById(artist_id);
}
#RequestMapping(value = "/updateartist", method = RequestMethod.PUT, produces = "application/json")
public ArtistRegister updateArtist(#RequestBody ArtistRegister artreg, HttpServletRequest request, HttpServletResponse response)
throws Exception
{
return artser.updateArtist(artreg);
}
this is service
#Service
#Transactional
public class ArtistService {
#Autowired
private ArtistRepository artrep;
#Autowired
private RegisterDAO artdao;
public ArtistRegister addArtist(ArtistRegister artreg) {
ArtistRegister artReg = null;
try {
artReg = artrep.save(artreg);
} catch (Exception e) {
e.printStackTrace();
}
return artReg;
}
public ArtistRegister getArtistDetails(int artist_id) {
return artdao.getArtistDetails(artist_id);
}
public void deleteById(int artist_id) {
artdao.deleteById(artist_id);
}
public ArtistRegister updateArtist(ArtistRegister artreg) {
return artdao.updateArtist(artreg);
}
}
this is DAO
#Repository
#Transactional
public class RegisterDAO {
private static final Logger logger = LoggerFactory.getLogger(SubCetegoryDAO.class);
#Autowired
SessionFactory sessionFactory;
#Autowired
EntityManager entitymanager;
public ArtistRegister getArtistDetails(int artist_id) {
try
{
String hql = "FROM ArtistRegister a where a.artist_id=?";
return (ArtistRegister) entitymanager.createQuery(hql).setParameter(1, artist_id).getSingleResult();
}
catch (EmptyResultDataAccessException e)
{
return null;
}
catch (Exception e)
{
logger.error("Exception in getUser"+ e.getMessage());
return null;
}
}

Remove #JsonManagedReference annotation and update fetch type to LAZY, by following way:
#OneToOne(targetEntity = SubCetegory.class, cascade = CascadeType.MERGE,fetch=FetchType.LAZY)
#JoinColumn(name = "sub_cetegory_id")
What are fetch types Lazy and Eager?
The EAGER strategy is a requirement on the persistence provider runtime that data must be eagerly fetched. The LAZY strategy is a hint to the persistence provider runtime that data should be fetched lazily when it is first accessed.
REFERENCES
Official documentation fetch type

Related

Read custom header value from the response

When I send request from the Soap UI under raw response tab I see the following result(find attachment). Now in AOP controller I want to read this header value which is marked as red. How it is possible? Thanks in advance.
In my application to send soap requests I have WebServiceTemplate. I applied custom interceptor WebServiceInterceptor (which implements ClientInterceptor interface) on this web service template. In overridden afterCompletion method, which injects MessageContext, I was able to take this property from the SaajMessageHeader.
Here is what code looks like:
#Configuration
public class MyWebServiceConfig {
#Bean(name = "myWSClient")
public WebServiceTemplate myWSClient() throws Exception {
WebServiceTemplate template = new WebServiceTemplate();
...
WebServiceInterceptor[] interceptors = { new WebServiceInterceptor() };
template.setInterceptors(interceptors);
return template;
}
private static class WebServiceInterceptor implements ClientInterceptor {
#Override
public boolean handleRequest(MessageContext messageContext) throws WebServiceClientException {
...
return true;
}
#Override
public boolean handleResponse(MessageContext messageContext) throws WebServiceClientException {
return true;
}
#Override
public boolean handleFault(MessageContext messageContext) throws WebServiceClientException {
return true;
}
#Override
public void afterCompletion(MessageContext messageContext, Exception ex) throws WebServiceClientException {
try {
SaajSoapMessage message = (SaajSoapMessage) messageContext.getResponse();
String []traceId = message.getSaajMessage().getMimeHeaders().getHeader("ITRACING_TRACE_ID");
if(traceId != null && traceId.length > 0){
process.setTraceId(traceId[0]);
}
} catch (Exception e) {
}
}
}

Exception handing in Spring Boot Rest API ResponseStatusException

While running the program saying remove the catch clause.
#RestController #RequestMapping(value = "/api/")
public class EmployeeController {
private EmployeeService employeeService;
#Autowired
public EmployeeController(EmployeeService employeeService) {
this.employeeService = employeeService;
}
#GetMapping(value = "employee")
public List<Employee> getAllEmployee() {
try {
return employeeService.findAllEmployees();
} catch (MyResourceNotFoundException ex) {
throw new ResponseStatusException(
HttpStatus.NOT_FOUND, "Employee not Found", ex);
}
}
}
This is the exception Class
#ResponseStatus(code = HttpStatus.NOT_FOUND, reason = "Employee Not Found")
public class MyResourceNotFoundException extends Exception {
private static final long serialVersionUID = 1L;
public MyResourceNotFoundException(String errorMessage) {
super(errorMessage);
}
}
Kindly find below screenshot. This is the exception which is being thrown while running the application.
I think there is a logical error in getAllEmployee method. Because, if in employeeService.findAllEmployees() there will be no employee, then by the logic of code it should return list of Employee with size 0. So, I think your code should look like this:
#GetMapping(value = "employee")
public List<Employee> getAllEmployee() throws MyResourceNotFoundException {
List<Employee> employees = employeeService.findAllEmployees();
if (employees.size() > 0) return employees;
else throw new MyResourceNotFoundException("Employee not Found");
}

How to validated rest url in spring boot?

validate Rest URL in spring boot.
Requirement: If I hit the wrong URL then it should throw a custom exception.
ex. Correct URL is "/fulfillment/600747l/send_to_hub" If I hit "/api/600747l/send_to_hub_1" then it should return exception like
"404:- URL not Found.".
Right now it returning "500 : -
{
"timestamp": 1531995246549,
"status": 500,
"error": "Internal Server Error",
"message": "Invalid Request URL.",
"path": "/api/600747l/send_to_hub_1"
}"
you need to write NewClass with annotation #ControllerAdvice which will redirect all exceptions to this NewClass.
example
Your Custom Exception Class:
#Data
#AllArgsConstructor
#EqualsAndHashCode(callSuper = false)
public class IOApiException extends IOException {
private ErrorReason errorReason;
public IOApiException(String message, ErrorReason errorReason) {
super(message);
this.errorReason = errorReason;
}
}
Now the CustomExceptionHandler Class -
#ControllerAdvice
#RestController
public class GlobalExceptionHandler {
Logger logger = LoggerFactory.getLogger(this.getClass());
#ResponseStatus(HttpStatus.UNAUTHORIZED)
#ExceptionHandler(value = IOApiException.class)
public GlobalErrorResponse handleException(IOApiException e) {
logger.error("UNAUTHORIZED: ", e);
return new GlobalErrorResponse("URL Not Found", HttpStatus.UNAUTHORIZED.value(), e.getErrorReason());
}
//this to handle customErrorResponseClasses
public GlobalErrorResponse getErrorResponseFromGenericException(Exception ex) {
if (ex == null) {
return handleException(new Exception("INTERNAL_SERVER_ERROR"));
}
else if (ex instanceof IOApiException) {
return handleException((IOApiException) ex);
}
}
Now Your error response class:
public class GlobalErrorResponse {
private String message;
#JsonIgnore
private int statusCode;
private ErrorReason reason;
}
ErrorReason Class
public enum ErrorReason {
INTERNAL_SERVER_ERROR,
INVALID_REQUEST_PARAMETER,
INVALID_URL
}
add and register one filter who calls the GlobalExceptionHandler in exception case like this
public class ExceptionHandlerFilter implements Filter {
private final GlobalExceptionHandler globalExceptionHandler;
public ExceptionHandlerFilter(GlobalExceptionHandler globalExceptionHandler) {
this.globalExceptionHandler = globalExceptionHandler;
}
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
try {
chain.doFilter(request, response);
} catch (Exception exception) {
HttpServletResponse httpResponse = (HttpServletResponse) response;
GlobalErrorResponse errorResponse = globalExceptionHandler.getErrorResponseFromGenericException(exception);
httpResponse.setStatus(errorResponse.getStatusCode());
response.getWriter().write(new ObjectMapper().writeValueAsString(errorResponse));
}
}
#Override
public void destroy() {
}
}
Like this you can add as many exceptions you want.. and can handle it manually.
As per your question first of all you need to define a base url(e.g.-/api) so that any url must be handled through your controller.Now after base url as shown /api/600747l/send_to_hub_1 #PathVariable int id. This circumstance is important, because Spring documentation said that if method argument annotated with #PathVariable can’t be casted to specified type (in our case to int), it will be exposed as String. Hence it can cause a TypeMismatchException.
To handle this I will use #ExceptionHandler annotation on #Controller level. Such approach suits for this situation as no one else. I just need to make 2 changes in the Controller:
1.Add MessageSource field
2.Add exception handler method
#Autowired
private MessageSource messageSource;
...
#ExceptionHandler(TypeMismatchException.class)
#ResponseStatus(value=HttpStatus.NOT_FOUND)
#ResponseBody
public ErrorInfo handleTypeMismatchException(HttpServletRequest req, TypeMismatchException ex) {
Locale locale = LocaleContextHolder.getLocale();
String errorMessage = messageSource.getMessage("error.bad.smartphone.id", null, locale);
errorMessage += ex.getValue();
String errorURL = req.getRequestURL().toString();
return new ErrorInfo(errorURL, errorMessage);
}
...

Spring: Catch exception thrown from AccessDecisionManager - NOT from Controller

Using Spring (4.2.4) with MVC (4.2.4) and Security (4.0.3). I have implemented an AccessDecisionManager and from within my decide-method I am throwing an exception:
public void decide(
Authentication authentication,
Object object,
Collection<ConfigAttribute> configAttributes
) throws AccessDeniedException, InsufficientAuthenticationException {
FilterInvocation fi = (FilterInvocation) object;
String requestUrl = fi.getRequestUrl();
...
throw new SessionCompanyNotRoleTableCompanyException(1, 2);
...
throw new AccessDeniedException("Access denied!");
}
I'm not able to catch neither "SessionCompanyNotRoleTableCompanyException" nor AccessDeniedException. I've tried using a global exception handler:
#Component
#ControllerAdvice
public class GlobalExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
#ExceptionHandler(SessionCompanyNotRoleTableCompanyException.class)
public ModelAndView sessionCompanyNotRoleTableCompany() {
log.debug("SessionCompanyNotRoleTableCompanyException captured in GlobalExceptionHandler");
String reason = "Reason: SessionCompanyNotRoleTableCompanyException";
ModelAndView mav = new ModelAndView();
mav.addObject("reason", reason);
mav.setViewName("error.html");
return mav;
}
#ExceptionHandler(Exception.class)
public ModelAndView exception(ModelMap model) {
log.debug("Exception captured in GlobalExceptionHandler");
String reason = "General Exception";
ModelAndView mav = new ModelAndView();
mav.addObject("reason", reason);
mav.setViewName("error.html");
return mav;
}
}
I've even created ExceptionResolver-classes like:
#Component
public class SessionCompanyNotRoleTableCompanyExceptionResolver implements HandlerExceptionResolver, Ordered {
private static final Logger log = LoggerFactory.getLogger(SessionCompanyNotRoleTableCompanyExceptionResolver.class);
private int order;
#Override
public ModelAndView resolveException(
HttpServletRequest request,
HttpServletResponse response,
Object handler,
Exception ex
) {
if (ex instanceof SessionCompanyNotRoleTableCompanyException) {
log.debug("SessionCompanyNotRoleTableCompanyException captured in SessionCompanyNotRoleTableCompanyExceptionResolver");
String reason = "Reason: SessionCompanyNotRoleTableCompanyException";
ModelAndView mav = new ModelAndView();
mav.addObject("reason", reason);
mav.setViewName("error.html");
return mav;
}
return null;
}
#Override
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
}
... and have them initialized in my web-config-class like:
#Bean
public SessionCompanyNotRoleTableCompanyExceptionResolver createSessionCompanyNotRoleTableCompanyExceptionResolver() {
SessionCompanyNotRoleTableCompanyExceptionResolver resolver = new SessionCompanyNotRoleTableCompanyExceptionResolver();
resolver.setOrder(1);
return resolver;
}
These work, i.e. exceptions are captured ONLY IF they are thrown from the Controllers. But NOT from my decide-method in the AccessDecisionManager.
What and how am I supposed to implement something that can catch these outside (before) the controller?
EDIT (adding the SessionCompanyNotRoleTableCompanyException to show you its definition):
public class SessionCompanyNotRoleTableCompanyException extends RuntimeException {
private static final long serialVersionUID = 1L;
public SessionCompanyNotRoleTableCompanyException(Long contextCompanyId, Long tableId) {
super("Context companyId: " + contextCompanyId + ", tableId: " + tableId);
}
}

Logging requests and responses in Spring

I'm trying to implement logging system in a Spring boot application. There are requests coming into the system which have one or more responses.
Requests and responses must be logged into the database in a separate thread, not in the worker thread.
This is my idea.
tables in mysql - "request" with required columns, and "response" with request_id as foreign key
relation between resquest and response - one to many.
A separate thread in LogService is started in #PostContruct to save the data in the DB.
I'm sure there are better solutions to this problem. Please guide with some suggestions.
#Service
public class LogServiceImpl implements LogService {
private final BlockingQueue<Object> logQueue = new LinkedBlockingQueue<>();
private volatile boolean done;
// repositories
#Autowired
private RequestRepository requestRepository;
#Autowired
private ResponseRepository responseRepository;
#Async
#Override
public void log(Object obj) {
try {
logQueue.put(obj);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
#PostContruct
private saveToDb(){
new Thread(() -> {
while(!done){
String object = logQueue.poll(5, TimeUnit.SECONDS)
if(object != null){
if(object instanceof Request){
requestRepository.save((Request)object);
}
if(object instanceof Response){
responseRepository.save((Response)object);
}
}
}
}).start();
}
public void stop() {
done = true;
}
}
class Request{
.....
}
class Response{
......
}
#Service
public class SomeService1 {
#Autowired
private LogService logService;
public void someMeth1(Request request) {
....
logService.log(request);
}
}
#Service
public class SomeService2 {
#Autowired
private LogService logService;
public void someMeth2(Response response) {
....
logService.log(response);
}
}

Resources