Spring Java how to use controller - spring

I'm completely new to Spring framework. and I have a task to make phone book application on spring. I need to make registration and authorization and also my phone book. I have 2 controllers for that, first UserController that controls authorization and registration
#Controller
public class UserController {
#Autowired
private UserService userService;
#Autowired
private SecurityService securityService;
#Autowired
private UserValidator userValidator;
#RequestMapping(value = "/registration", method = RequestMethod.GET)
public String registration(Model model) {
model.addAttribute("userForm", new User());
return "registration";
}
#RequestMapping(value = "/registration", method = RequestMethod.POST)
public String registration(#ModelAttribute("userForm")
User userForm, BindingResult bindingResult, Model model) {
userValidator.validate(userForm, bindingResult);
if (bindingResult.hasErrors()) {
return "registration";
}
userService.save(userForm);
securityService.autoLogin(userForm.getUsername(), userForm.getConfirmPassword());
return "redirect:/welcome";
}
#RequestMapping(value = "/login", method = RequestMethod.GET)
public String login(Model model, String error, String logout) {
if(error!=null) {
model.addAttribute("error", "Username or password is incorrect.");
}
if (logout!=null) {
model.addAttribute("message", "logged out successfully");
}
return "login";
}
#RequestMapping(value = {"/", "/welcome"}, method = RequestMethod.GET)
public String welcome(Model model) {
return "welcome";
}
#RequestMapping(value = "/admin", method = RequestMethod.GET)
public String admin(Model model) {
return "admin";
}
}
and ContactController that controls my fuctionality(adding, removing, editing and shows contacts)
#Controller
public class ContactController {
private ContactService contactService;
#Autowired(required = true)
#Qualifier(value = "contactService")
public void setContactService(ContactService contactService) {
this.contactService = contactService;
}
#RequestMapping(value = {"admin", "welcome"}, method = RequestMethod.GET)
public String listContactsForAdmin(Model model) {
model.addAttribute("contact", new Contact());
model.addAttribute("listContacts", this.contactService.listContacts());
return "admin";
}
#RequestMapping(value = "admin/add", method = RequestMethod.POST)
public String addContact(#ModelAttribute("contact") Contact contact) {
if (contact.getId() == 0) {
this.contactService.addContact(contact);
} else {
this.contactService.updateContact(contact);
}
return "redirect:/admin";
}
#RequestMapping("/remove/{id}")
public String removeContact(#PathVariable("id") int id) {
this.contactService.removeContact(id);
return "redirect:/admin";
}
#RequestMapping("/edit/{id}")
public String editBook(#PathVariable("id") int id, Model model) {
model.addAttribute("contact", this.contactService.getContactById(id));
model.addAttribute("listContacts", this.contactService.listContacts());
return "admin";
}
#RequestMapping("contactData/{id}")
public String contactData(#PathVariable("id") int id, Model model) {
model.addAttribute("contact", this.contactService.getContactById(id));
return "contactData";
}
}
when i try to authenticate or registr. new user I have such error:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: Ambiguous handler methods mapped for HTTP path 'http://localhost:8087/admin': {public java.lang.String kz.adilka.springsecurity.app.controller.UserController.admin(org.springframework.ui.Model), public java.lang.String kz.adilka.springsecurity.app.controller.ContactController.listContactsForAdmin(org.springframework.ui.Model)}
it says that I have problem with mapping admin page. but for me it seems to be ok, or maybe I missed smth

The reason is that you do not set the controller value for your controllers and they have the same RequestMapping method
#Controller // do not have identifier here
public class UserController {
#Autowired
private UserService userService;
#Autowired
private SecurityService securityService;
#Autowired
private UserValidator userValidator;
#RequestMapping(value = "/admin", method = RequestMethod.GET)
public String admin(Model model) {
return "admin";
}
}
#Controller // do not have identifier here
public class ContactController {
private ContactService contactService;
#RequestMapping(value = {"admin", "welcome"},
method = RequestMethod.GET)
public String listContactsForAdmin(Model model) {
model.addAttribute("contact", new Contact());
model.addAttribute("listContacts",
this.contactService.listContacts());
return "admin";
}
}
One possible solution is the set RequestMapping for each Controller method:
#Controller(value = "user")
public class UserController {
#Autowired
private UserService userService;
#Autowired
private SecurityService securityService;
#Autowired
private UserValidator userValidator;
#RequestMapping(value = "/admin", method = RequestMethod.GET)
public String admin(Model model) {
return "admin";
}
}
#Controller(value = "contact")
public class ContactController {
private ContactService contactService;
#RequestMapping(value = {"admin", "welcome"}, method = RequestMethod.GET)
public String listContactsForAdmin(Model model) {
model.addAttribute("contact", new Contact());
model.addAttribute("listContacts", this.contactService.listContacts());
return "admin";
}
}

Related

Issue with Spring boot Controller with Mockito test case

I am completely new to Mockito and I have to write a test case for my REST Controller, but I am not sure where should I start. Any help would be really appreciated.I've updated my controller based on given suggestion.
Here's my controller:
#RestController
#RequestMapping("/api")
public class TestController {
#Autowired
TestService _testService;
#RequestMapping(value = "/getsearchDetailCourse", method = RequestMethod.GET)
public List<TestDto> getsearchDetailCourse(#RequestParam("courseName") String courseName,
#RequestParam("courseId") Long courseId) throws Exception {
return (List<TestDto>) _testService.searchDetailCourse(courseName, courseId);
}
}
My TestDto:
public class TestDto {
private String numberOfCourse;
private Long courseId;
public TestDto(){}
public TestDto(String numberOfCourse,Long courseId ){
super();
this.numberOfCourse = numberOfCourse;
this.courseId = courseId;
}
public String getNumberOfCourse() {
return numberOfCourse;
}
public void setNumberOfCourse(String numberOfCourse) {
this.numberOfCourse = numberOfCourse;
}
public Long getCourseId() {
return courseId;
}
public void setCourseId(Long courseId) {
this.courseId = courseId;
}
}
Here's my test:
#RunWith(SpringRunner.class)
#WebMvcTest(value = TestController.class, secure = false)
public class TestMethod {
#Autowired
private MockMvc mockMvc;
#MockBean
private TestService testService;
TestDto testDto = new testDto("Test",2744L);
#Test
public void retrieveDetailsForCourse() throws Exception {
Mockito.when(
testService.searchDetailCourse(Mockito.anyString(),
,Mockito.anyLong())).thenReturn(testDto);
RequestBuilder requestBuilder = MockMvcRequestBuilders.get(
"/api/getsearchDetailCourse").accept(
MediaType.APPLICATION_JSON);
MvcResult result = mockMvc.perform(requestBuilder).andReturn();
System.out.println(result.getResponse());
String expected = "[{\"numberOfCourse\":\"Testing1\",\"courseId\":2744},{\"numberOfCourse\":\"Testing2\",\"courseId\":2744}]";
JSONAssert.assertEquals(expected, result.getResponse()
.getContentAsString(), false);
}
}
I want to test the controller, please help me correct the test case above.

Post json data and file using ResponseEntity<>

I am trying to upload json data and image to a database of a form using spring rest and hibernate. I tried to test it using POSTMAN by setting form-data in body and content-type as application/json in header, but i am getting http error 400. I also tried using #RequestPart but didnt not work. I searched but could not find an example using ResponseEnity<>. I think i am doing something wrong in controller class. Please someone help me.
Without the file part i am able to add json data to db using this.
#RequestMapping(value = "/users", method = RequestMethod.POST, produces ="application/json")
public ResponseEntity<User> createAparts( #RequestBody User user) {
if (user == null) {
return new ResponseEntity<User>(HttpStatus.BAD_REQUEST);
}
userService.addAparts(user);
return new ResponseEntity<User>(user, HttpStatus.CREATED);
}
Below are the related code to issue.
model
#Entity
#Table(name = "User")
#JsonIgnoreProperties({"hibernateLazyInitializer", "handler", "ignoreUnknown = true"})
public class User{
#Id
#Column(name = "id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private int id;
#Column(name = "Name")
private String Name;
#Column(name = "file_data")
private byte[] file_data;
#Column(name = "filename")
private String filename;
#JsonCreator
public ApartsData(#JsonProperty("id") int id,
#JsonProperty("Name") String Name,
#JsonProperty("filename") String filename,
#JsonProperty("file_data") byte[] file_data){
this.ad_id = ad_id;
this.Name = Name;
this.filename= filename;
this.file_data = file_data;
}
public User(){
}
DAO
#Repository
public class UserDaoImpl implements UserDao{
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory){
this.sessionFactory = sessionFactory;
}
#Override
public void addUser(User user) {
Session session = this.sessionFactory.getCurrentSession();
session.persist(user);
}
}
Service
#Service
public class UserServiceImpl implements UserService {
private UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
#Override
#Transactional
public void addUser(User user) {
this.userDao.addUser(user);
}
}
controller
#RestController
public class UserController {
private UserService userService;
#Autowired(required=true)
#Qualifier(value="userService")
public void setUserService(UserService userService){
this.userService = userService;
}
#RequestMapping(value = "/users", method = RequestMethod.POST,
produces ="application/json")
public ResponseEntity<User> createApartsData(#RequestBody User user,
#RequestParam("file") MultipartFile file) {
HttpHeaders headers = new HttpHeaders();
if (user == null) {
return new ResponseEntity<User>(HttpStatus.BAD_REQUEST);
}
if (!file.isEmpty()) {
try {
user.setFilename(file.getOriginalFilename());
user.setFile_data(file.getBytes());
} catch (Exception e){
e.printStackTrace();
}
}
userService.addUser(user);
headers.add("User Created - ", String.valueOf(user.getid()));
return new ResponseEntity<User>(user, headers, HttpStatus.CREATED);
}
}
UPDATE:
I am able to make it work with #RequestParam. Please some help me to make it work with #RequestBody

Spring social returning wrong user profile

I'm using Spring Social LinkedIn to retrieve user profiles with a custom ConnectController since I want to the user to login and retrieve the profile in one step. The issue is that sometimes the first user in the system is returned instead of the currently logged in user.
Here is my CustomConnectController
#Controller
#RequestMapping("/connect")
public class CustomConnectController extends ConnectController {
#Inject
public CustomConnectController(ConnectionFactoryLocator connectionFactoryLocator,
ConnectionRepository connectionRepository) {
super(connectionFactoryLocator, connectionRepository);
}
#Override
protected String connectView(String providerId) {
return "redirect:/hey/" + providerId + "Connect";
}
#Override
protected String connectedView(String providerId) {
return "redirect:/hey/" + providerId + "Connected";
}
}
and my webcontroller
#Controller
public class WebController {
#Autowired
private LinkedIn linkedin;
#Autowired
private ConnectionRepository repository;
#RequestMapping(value = "/hey/linkedinConnected", method = RequestMethod.GET)
public String linkedinConnected(HttpServletRequest request, Model model, Locale locale) {
if (repository.findConnections("linkedin").isEmpty()
|| !linkedin.isAuthorized()) {
return "redirect:/connect/linkedin";
}
LinkedInProfile userProfile = linkedin.profileOperations().getUserProfile();
return "loggedinpage";
}
#RequestMapping(value = "/hey/linkedinConnect", method = RequestMethod.GET)
public String linkedinConnect(HttpServletRequest request, Model model, Locale locale) {
if (repository.findConnections("linkedin").isEmpty()
|| !linkedin.isAuthorized()) {
return "redirect:/connect/linkedin";
}
LinkedInProfile userProfile = linkedin.profileOperations().getUserProfile();
return "loggedinpage";
}
}
Any ideas of what I'm doing wrong?

localhost:8080/ returns status 404 - Spring

This is my code:
#Controller
#RequestMapping("/")
public class MerchantsController {
#Autowired
MerchantsService merchantsService;
#Autowired
ProductsService productsService;
#Autowired
OrdersService ordersService;
#RequestMapping(value = "/merchants", method = RequestMethod.GET)
public ModelAndView showMerchantsList() {
ModelAndView modelAndView = new ModelAndView("merchantsList");
List<Merchant> merchants = merchantsService.getMerchantsList();
for (Merchant merchant : merchants) {
if(merchant.getOrder_type() == OrderType.NO_ORDERING){
merchant.setOrderUntil(Time.valueOf("00:00:00"));
}
}
modelAndView.addObject("merchants", merchants);
return modelAndView;
}
As I understand when I send request to localhost:8080/ it should open localhost:8080/merchants, but it is not working. Anyone has any suggestions?
Your showMerchantsList method will be called when you send request to localhost:8080/merchants. And this method will you redirect again localhost:8080/merchants. But if you want send request as localhost:8080/ and direct you to localhost:8080/merchants, then you should create another method as this:
#RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView showMerchantsListWithoutRequestMapping() {
ModelAndView modelAndView = new ModelAndView("merchantsList");
List<Merchant> merchants = merchantsService.getMerchantsList();
for (Merchant merchant : merchants) {
if(merchant.getOrder_type() == OrderType.NO_ORDERING){
merchant.setOrderUntil(Time.valueOf("00:00:00"));
}
}
modelAndView.addObject("merchants", merchants);
return modelAndView;
}
This method will redirect you to localhost:8080/merchants, when you called localhost:8080/
Normal way you should use
#Controller
public class MerchantsController {
#Autowired
MerchantsService merchantsService;
#Autowired
ProductsService productsService;
#Autowired
OrdersService ordersService;
#RequestMapping(value = "/merchants", method = RequestMethod.GET)
public ModelAndView showMerchantsList() {
ModelAndView modelAndView = new ModelAndView("merchantsList");
List<Merchant> merchants = merchantsService.getMerchantsList();
for (Merchant merchant : merchants) {
if(merchant.getOrder_type() == OrderType.NO_ORDERING){
merchant.setOrderUntil(Time.valueOf("00:00:00"));
}
}
modelAndView.addObject("merchants", merchants);
return modelAndView;
}
As i understand your requirement silly way:
#Controller
public class MerchantsController {
#Autowired
MerchantsService merchantsService;
#Autowired
ProductsService productsService;
#Autowired
OrdersService ordersService;
#RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView showMerchantsList() {
ModelAndView model=new ModelAndView("redirect:/merchants");
return model;
}
#RequestMapping(value = "/merchants", method = RequestMethod.GET)
public ModelAndView showMerchantsList() {
ModelAndView modelAndView = new ModelAndView("merchantsList");
List<Merchant> merchants = merchantsService.getMerchantsList();
for (Merchant merchant : merchants) {
if(merchant.getOrder_type() == OrderType.NO_ORDERING){
merchant.setOrderUntil(Time.valueOf("00:00:00"));
}
}
modelAndView.addObject("merchants", merchants);
return modelAndView;
}
Note: Because / always denotes to root.

Spring MVC #pathvariable annotated does not pass the value from interface to implementation

Service Class
#Service
#RequestMapping(value = "employees")
public interface EmployeeService {
#RequestMapping(value = "{id}", method = RequestMethod.GET)
public #ResponseBody Employee getEmployee(#PathVariable("id") int employeeId) throws EmpException;
#RequestMapping(method = RequestMethod.GET)
public #ResponseBody List<Employee> getAllEmployees() throws EmpException;
#RequestMapping(method = RequestMethod.POST)
public #ResponseBody Employee createEmployee(#RequestBody Employee employee) throws EmpException;
#RequestMapping(value ="{id}", method = RequestMethod.DELETE)
public #ResponseBody UserInfo deleteEmployee(#PathVariable("id") int employeeId) throws EmpException;
#RequestMapping(value="{id}", method = RequestMethod.PUT)
public #ResponseBody Employee updateEmployee(#RequestBody Employee employee,#PathVariable("id") int employeeId) throws EmpException;
}
Implementation class
#Service("employeeService")
public class EmployeeServiceImpl implements EmployeeService {
#Autowired
private Employee employee;
private static final Logger logger = LoggerFactory.getLogger(EmployeeServiceImpl.class);
public Employee getEmployee(#PathVariable("id") int employeeId) throws EmpException {
logger.info("Start getEmployee. ID="+employeeId);
employee = employeeDao.getEmployee(employeeId);
if(employee != null) {
return employee;
} else {
throw new EmpException("ID: "+employeeId+" is not available");
}
}
}
in implementation class also i used #pathvariable annotation then only value for employeeId will be pass from interface to implementation otherwise null pointer expression will be occur.any other way to pass the value from interface to implementation without using #pathvariable .
Request mappings don't go on service class, they go on controller.
For which you'll need #Controller annotation.

Resources