This is my code:
package com.application.myGoogleAppEngine.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
#Controller
public class IndexController {
#RequestMapping("/index")
public String index(ModelMap map){
return "index";
}
}
Unfornately, #RequestMapping makes an error. I use Spring 2.5.6 and I've imported org.springframework and org.springframework with spring-webmvc in my pom.xml
Do you have any solutions ?
Thank you
Just add the import statement for that class
import org.springframework.web.bind.annotation.RequestMapping;
Related
Basically, I have created all of the pojo and layers(including the repository layer) necessary for Spring Boot to automatically implement MySql commands. When I trying to run the programme, I get the following command:
Description:
Parameter 0 of constructor in com.fsse2207.project_backend.api.ProductApi required a bean of type 'com.fsse2207.project_backend.service.ProductService' that could not be found.
Action:
Consider defining a bean of type 'com.fsse2207.project_backend.service.ProductService' in your configuration.
It turns out there's sth wrong about the bean in my ProductApi. It says "
Could not autowire. No beans of 'ProductService' type found." How do I fix it?
The following is the interface under the service layer:
package com.fsse2207.project_backend.service;
import com.fsse2207.project_backend.data.ProductCreateData;
import com.fsse2207.project_backend.data.ProductDetailData;
import com.fsse2207.project_backend.exception.ProductFoundByIdException;
import org.springframework.stereotype.Service;
public interface ProductService {
ProductDetailData createProductData (ProductCreateData productCreateData) throws ProductFoundByIdException;
}
The following is the service class:
package com.fsse2207.project_backend.service.impl;
import com.fsse2207.project_backend.data.ProductCreateData;
import com.fsse2207.project_backend.data.ProductDetailData;
import com.fsse2207.project_backend.data.entity.ProductEntity;
import com.fsse2207.project_backend.exception.ProductFoundByIdException;
import com.fsse2207.project_backend.repository.ProductRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service
public class ProductServiceImpl {
private ProductRepository productRepository;
#Autowired
public ProductServiceImpl(ProductRepository productRepository){
this.productRepository=productRepository;
}
public ProductDetailData createProductData (ProductCreateData productCreateData) throws ProductFoundByIdException {
ProductEntity productEntity=new ProductEntity(productCreateData);
if(productRepository.existsById(productEntity.getpId())){
throw new ProductFoundByIdException();
}
return new ProductDetailData(productRepository.save(productEntity));
}
}
The following is the Api:
package com.fsse2207.project_backend.api;
import com.fsse2207.project_backend.data.ProductCreateData;
import com.fsse2207.project_backend.data.ProductDetailData;
import com.fsse2207.project_backend.data.dto.CreateRequestDto;
import com.fsse2207.project_backend.data.dto.CreateResponseDto;
import com.fsse2207.project_backend.exception.ProductFoundByIdException;
import com.fsse2207.project_backend.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class ProductApi {
private ProductService productService;
#Autowired
public ProductApi(ProductService productService){
this.productService=productService;
}
#PostMapping
public CreateResponseDto createResponseDto(#RequestBody CreateRequestDto createRequestDto) throws ProductFoundByIdException {
ProductCreateData productCreateData=new ProductCreateData(createRequestDto);
ProductDetailData productDetailData =productService.createProductData(productCreateData);
return new CreateResponseDto(productDetailData);
}
}
I found the problem:
I didn't add the implements keyword in the class definition of ProductServiceImpl so it was not connected to the bean, aka the interface, aka the service layer.
First of all you should not add annotation #Service for ProductService interface.
Moreover this can happen when you have your Class Application in "another package".
You can solve the problem using annotation #ComponentScan (basePackages = {"your.company.domain.package"})
I am trying to create a webapp but it's not working I am geeting 404 response.
The package structure is like:
com.example.demo
com.example.demo.jerseyConfig.java
com.example.demo.demo.java
com.example.demo.backend.service.userManagementService.java
My Application.java is
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import com.example.pentest.backend.service.userManagementService;
#SpringBootApplication
public class demo {
public static void main(String[] args) {
//new demo().configure(new SpringApplicationBuilder(demo.class)).run(args);
SpringApplication.run(demo.class, args);
}
}
My Jersey config is
package com.example.demo;
import javax.ws.rs.ApplicationPath;
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.context.annotation.Profile;
import com.example.pentest.backend.service.userManagementService;
import org.springframework.stereotype.Component;
#Component
#ApplicationPath("/")
public class jerseyConfig extends ResourceConfig {
public jerseyConfig() {
register(userManagementService.class);
}
}
My userManagementService.java is
package com.example.demo.backend.service;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import javax.ws.rs.POST;
import javax.ws.rs.GET;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.context.annotation.Profile;
#Component
#Path("/backend")
public class userManagementService {
#Path("/user/login")
#GET
#Consumes(MediaType.APPLICATION_FORM_URLENCODED_VALUE)
#Produces(MediaType.APPLICATION_JSON_VALUE)
public Response createUser() {
return Response.status(Response.Status.OK).build();
}
}
I am running it on tomcat server, I am seeing no errors. The url I am trying to access is http://localhost:8080/demo/backend/user/login
I have a servlet annotated with #WebServlet("*.html") and a controller with #GetMapping("/greeting.html"). Despite the controller mapping being more specific, the servlet takes precedence.
In my application I can't trivially change the mapping of the servlet (I'm in the middle of a complex migration from servlets to Spring-Boot).
I tried #Order annotation, and different matching rules. So far no progress.
You can reproduce it with just 3 classes:
application.java
package hello;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
#SpringBootApplication
#ServletComponentScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
GreetingController.java
package hello;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
#Controller
public class GreetingController {
#GetMapping("/greeting.html")
#Order(Ordered.HIGHEST_PRECEDENCE)
#ResponseBody
public String greeting() {
return "this is geeting.html";
}
}
SimpleServlet.java
package hello;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
#WebServlet("/*.html")
#Order(Ordered.LOWEST_PRECEDENCE)
public class SimpleServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().println("This is *.html servlet");
super.doGet(req, resp);
}
}
When accessing localhost:8080 I expect to see this is geeting.html, instead I get This is *.html servlet.
Trying to simply validate a field of my bean and instead of doing it manually wanted to check out Spring Validation, but didn't have much luck as of now.
In short:
Validation with #Valid annotation seems to never be called when I call a method of my #RestController
My code:
pom.xml (for the validation part)
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.1.0.Final</version>
</dependency>
Spring is version 4.1.1
Validator
package mypackage;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
public class UtenteValidator implements Validator{
public UtenteValidator() {
// TODO Auto-generated constructor stub
}
#Override
public boolean supports(Class<?> clazz) {
return UtenteLite.class.equals(clazz);
}
//validation test
#Override
public void validate(Object target, Errors errors) {
UtenteLite user = (UtenteLite) target;
if(user.getName != "foo") {
errors.rejectValue("name", "name not correct");
}
}
}
Controller
package myPackage;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping("/users")
public class UsersController {
public UsersController() {
}
//tried to put #InitBinder, but no luck
#InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setValidator(new UtenteValidator());
}
#ResponseBody
#RequestMapping(value="", method=RequestMethod.PUT)
public <T> ResponseEntity<T> aggiornaUtente(#RequestBody #Valid UtenteLite utente, BindingResult result)
{
ResponseEntity<T> responseEntity=null;
return responseEntity;
}
}
Te BindingResult result object shows always zero errors and the validate, supports or initBinder methods are never called.
Found this tutorial that reads:
When #InitBinder methods get called?
The #InitBinder annotated methods
will get called on each HTTP request if we don't specify the 'value'
element of this annotation.
WebDataBinder argument is specific to a model attribute. That means
each time a model attribute is created by Spring this method will get
called with a new instance of WebDataBinder.
So I tried to change my controller method to this adding a #ModelAttribute and NOW the validation code gets called BUT the requestBody object (the "utente" object) is empty, so validation always fails because the fields are all nulls:
#ResponseBody
#RequestMapping(value="", method=RequestMethod.PUT)
public <T> ResponseEntity<T> aggiornaUtente(#RequestBody #Valid #ModelAttribute("utente") UtenteLite utente, BindingResult result)
{
...
}
The utente method parameter is passed with a JSON as the body of the request.
Ok,
after several tries I succeded in producing a working solution just by adding the hibernate-validation artifact reference in my pom.xml.
I wrongly supposed the hibernate-validator was mandatory only if I was usig validation annotations on the beans properties (like #NotNull, #Pattern, etc..)
So only by adding this snippet I was able to solve my problem (hope this will spare a few hours of work to someone else):
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.1.3.Final</version>
</dependency>
The complete code now is:
Validator
package mypackage;
import org.springframework.validation.Errors;
import org.springframework.validation.Validator;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
public class UtenteValidator implements Validator{
public UtenteValidator() {
// TODO Auto-generated constructor stub
}
#Override
public boolean supports(Class<?> clazz) {
return UtenteLite.class.equals(clazz);
}
//validation test
#Override
public void validate(Object target, Errors errors) {
UtenteLite user = (UtenteLite) target;
if(user.getName != "foo") {
errors.rejectValue("name", "name not correct");
}
}
}
Controller
package myPackage;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
#RestController
#RequestMapping("/users")
public class UsersController {
public UsersController() {
}
//tried to put #InitBinder, but no luck
#InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setValidator(new UtenteValidator());
}
#ResponseBody
#RequestMapping(value="", method=RequestMethod.PUT)
public <T> ResponseEntity<T> aggiornaUtente(#RequestBody #Valid UtenteLite utente)
{
ResponseEntity<T> responseEntity=null;
return responseEntity;
}
}
I am working on Spring and hibernate project. For database communication we have conventional two layered implementation (i.e DAO layer and Service layer). I have following files:
DemoDao.java
package net.dao;
import java.util.List;
import net.domain.Demo;
public interface DemoDao
{
public List<Demo> get();
}
DemoDaoImpl.java
package net.dao;
import java.util.List;
import net.domain.Demo;
import org.hibernate.SessionFactory;
import org.hibernate.classic.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
#Repository
public class DemoDaoImpl implements DemoDao
{
#Autowired
SessionFactory sessionFactory;
public List<Demo> get()
{
Session session=sessionFactory.openSession();
List<Demo> list=session.createQuery("from Demo").list();
session.close();
return list;
}
}
That was DAO layer
Follwing is from service layer:
DemoManager.java
package net.service;
import java.util.List;
import net.domain.Demo;
public interface DemoManager
{
public List<Demo> get();
}
DemoManagerImpl.java
package net.service;
import java.util.List;
import net.dao.DemoDao;
import net.domain.Demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service
public class DemoManagerImpl implements DemoManager
{
#Autowired
DemoDao demoDao;
public List<Demo> get()
{
List<Demo> list=demoDao.get();
return list;
}
}
Follwing is my controller
FromDualLayerView.java
package net.spring;
import java.util.List;
import net.domain.Demo;
import net.service.DemoManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
#Controller
public class FromDualLayerView
{
#Autowired
DemoManager demoManager;
#RequestMapping("/dualLayer")
public ModelAndView toResult(ModelMap map)
{
List<Demo> list=demoManager.get();
map.addAttribute("listData", list);
return new ModelAndView("result");
}
}
My Question
Actually everything works fine, but my question over here is that i am not annotating the DemoDao and DemoManager interface, but i am autowiring them. According to the autowiring definition the entities which are annotated are injected.
The how come the dependency is injected by Spring container?
And how does it work like an Impl class?
Thanks in advance.
DemoManagerImpl is annotated as a service and is the only qualifying bean to be injected in the FromDualLayerView class, as it's the only component which is instance of DemoManager. I suppose you have the component scan turned on as well.
The #Repository annotation and the #Service annotation mean you are annotating them. It's actually a spring best practice to annotate the implementations and not the interfaces.
Your spring config file is scanning the classpath, thus those beans are detected. Turn spring logging up to TRACE and you'll probably see output along the lines of:
"scanning classpath, found target DemoDaoImpl"