2

I have this code in my view to display a input box and a submit button. (UPDATED)

  <form action="/hms/accommodations" method="GET">
       <input type="text" name="searchKeyword"/>
       <input type="submit" value="Submit"/>
  </form>

As I click the submit button, I need to pass whatever the user's typed into the input box to be passed on to a method in my Controller.

This is the method I have in my Controller. (UPDATED)

@RequestMapping(value = "/hms/accommodations", method = RequestMethod.GET)
public List<Accommodation> listofAccomo(@RequestParam String searchKeyword){
    List<Accommodation> searchResult = accommodationService.findAllAccommodationBySearchBox(searchKeyword);
    return searchResult;
}

I have this in my AccommodationService class:

 public abstract List<Accommodation> findAllAccommodationBySearchBox(String searchKeyword);

And this on another class:

public List<Accommodation> findAllAccommodationBySearchBox(String searchKeyword){
    TypedQuery<Accommodation> searchResult = em.createNamedQuery("findAllAccommodationBySearch", Accommodation.class);
    searchResult.setParameter("searchKeyword",'%'+searchKeyword+'%');
    List<Accommodation> result=searchResult.getResultList();
    return result;
 }

I have this NamedQuery in my domain.:

@NamedQueries(
{
 @NamedQuery(
   name = "findAllAccommodationBySearch",
   query = "SELECT a FROM Accommodation a WHERE a.person.firstName LIKE :searchKeyword OR a.person.middleName LIKE :searchKeyword OR a.person.lastName LIKE :searchKeyword OR a.room.roomNumber LIKE :searchKeyword OR a.person.pvId LIKE :searchKeyword OR a.startDate LIKE :searchKeyword OR a.endDate LIKE :searchKeyword"
   )
})

What happens is that when I click my submit button after typing, it redirects to the same page but with a different URL but it does not seem to access my Controller method because it doesn't return the value it was supposed to return. What am I missing out here? Hope someone can help. Thanks!

EDIT: This is my Controller class code.

import java.io.UnsupportedEncodingException;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
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.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.util.UriComponentsBuilder;
import org.springframework.web.util.UriUtils;
import org.springframework.web.util.WebUtils;

import ph.com.smesoft.hms.domain.Accommodation;
import ph.com.smesoft.hms.service.AccommodationService;
import ph.com.smesoft.hms.service.PersonService;
import ph.com.smesoft.hms.service.RoomService;

@Controller
@RequestMapping("/accommodations")
public class AccommodationController {

 @RequestMapping(value = "/{id}", method = RequestMethod.GET, headers = "Accept=application/json")
    @ResponseBody
    public ResponseEntity<String> showJson(@PathVariable("id") Long id) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json; charset=utf-8");
        try {
            Accommodation accommodation = accommodationService.findAccommodation(id);
         if (accommodation == null) {
                return new ResponseEntity<String>(headers, HttpStatus.NOT_FOUND);
            }
            return new ResponseEntity<String>(accommodation.toJson(), headers, HttpStatus.OK);
        } catch (Exception e) {
            return new ResponseEntity<String>("{\"ERROR\":"+e.getMessage()+"\"}", headers, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
[1:49:35 AM] Kath Revilla:  @RequestMapping(headers = "Accept=application/json")
    @ResponseBody
    public ResponseEntity<String> listJson() {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json; charset=utf-8");
        try {
            List<Accommodation> result = accommodationService.findAllAccommodations();
            return new ResponseEntity<String>(Accommodation.toJsonArray(result), headers, HttpStatus.OK);
        } catch (Exception e) {
            return new ResponseEntity<String>("{\"ERROR\":"+e.getMessage()+"\"}", headers, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

 @RequestMapping(method = RequestMethod.POST, headers = "Accept=application/json")
    public ResponseEntity<String> createFromJson(@RequestBody String json, UriComponentsBuilder uriBuilder) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json");
        try {
            Accommodation accommodation = Accommodation.fromJsonToAccommodation(json);
            accommodationService.saveAccommodation(accommodation);
            RequestMapping a = (RequestMapping) getClass().getAnnotation(RequestMapping.class);
            headers.add("Location",uriBuilder.path(a.value()[0]+"/"+accommodation.getId().toString()).build().toUriString());
            return new ResponseEntity<String>(headers, HttpStatus.CREATED);
        } catch (Exception e) {
            return new ResponseEntity<String>("{\"ERROR\":"+e.getMessage()+"\"}", headers, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }


 @RequestMapping(value = "/jsonArray", method = RequestMethod.POST, headers = "Accept=application/json")
    public ResponseEntity<String> createFromJsonArray(@RequestBody String json) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json");
        try {
            for (Accommodation accommodation: Accommodation.fromJsonArrayToAccommodations(json)) {
                accommodationService.saveAccommodation(accommodation);
            }
            return new ResponseEntity<String>(headers, HttpStatus.CREATED);
        } catch (Exception e) {
            return new ResponseEntity<String>("{\"ERROR\":"+e.getMessage()+"\"}", headers, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

 @RequestMapping(value = "/{id}", method = RequestMethod.PUT, headers = "Accept=application/json")
    public ResponseEntity<String> updateFromJson(@RequestBody String json, @PathVariable("id") Long id) {
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json");
        try {
            Accommodation accommodation = Accommodation.fromJsonToAccommodation(json);
            accommodation.setId(id);
            if (accommodationService.updateAccommodation(accommodation) == null) {
                return new ResponseEntity<String>(headers, HttpStatus.NOT_FOUND);
            }
            return new ResponseEntity<String>(headers, HttpStatus.OK);
        } catch (Exception e) {
            return new ResponseEntity<String>("{\"ERROR\":"+e.getMessage()+"\"}", headers, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }

 @Autowired
    AccommodationService accommodationService;

 @Autowired
    PersonService personService;

 @Autowired
    RoomService roomService;


 @RequestMapping(produces = "text/html")
    public String list(@RequestParam(value = "page", required = false) Integer page, @RequestParam(value = "size", required = false) Integer size, @RequestParam(value = "sortFieldName", required = false) String sortFieldName, @RequestParam(value = "sortOrder", required = false) String sortOrder, Model uiModel) {
        if (page != null || size != null) {
            int sizeNo = size == null ? 10 : size.intValue();
            final int firstResult = page == null ? 0 : (page.intValue() - 1) * sizeNo;
            uiModel.addAttribute("accommodations", Accommodation.findAccommodationEntries(firstResult, sizeNo, sortFieldName, sortOrder));
            float nrOfPages = (float) accommodationService.countAllAccommodations() / sizeNo;
            uiModel.addAttribute("maxPages", (int) ((nrOfPages > (int) nrOfPages || nrOfPages == 0.0) ? nrOfPages + 1 : nrOfPages));
        } else {
            uiModel.addAttribute("accommodations", Accommodation.findAllAccommodations(sortFieldName, sortOrder));
        }
        addDateTimeFormatPatterns(uiModel);
        return "accommodations/list";
    }

 @RequestMapping(value = "/hms/accommodations", method = RequestMethod.GET)
 public List<Accommodation> listofAccomo(@RequestParam String searchKeyword){
     List<Accommodation> searchResult = accommodationService.findAllAccommodationBySearchBox(searchKeyword);
     return searchResult;
 }

 void addDateTimeFormatPatterns(Model uiModel) {
        uiModel.addAttribute("accommodation_startdate_date_format","yyyy-MM-dd");
        uiModel.addAttribute("accommodation_enddate_date_format","yyyy-MM-dd");
    }

 void populateEditForm(Model uiModel, Accommodation accommodation) {
        uiModel.addAttribute("accommodation", accommodation);
        addDateTimeFormatPatterns(uiModel);
        uiModel.addAttribute("people", personService.findAllPeople());
        uiModel.addAttribute("rooms", roomService.findAllRooms());
    }

 String encodeUrlPathSegment(String pathSegment, HttpServletRequest httpServletRequest) {
        String enc = httpServletRequest.getCharacterEncoding();
        if (enc == null) {
            enc = WebUtils.DEFAULT_CHARACTER_ENCODING;
        }
        try {
            pathSegment = UriUtils.encodePathSegment(pathSegment, enc);
        } catch (UnsupportedEncodingException uee) {}
        return pathSegment;
    }




}
Kendall H.
  • 461
  • 3
  • 9
  • 21

2 Answers2

2

The issue seems to be that in your controller method you expect a path parameter whereas in the form you are passing a query parameter. I would change the method to accept a query parameter like

@RequestMapping(value = "/hms/accommodations", method = RequestMethod.GET)
public List<Accommodation> listofAccomo(@RequestParam String searchKeyword){
    List<Accommodation> searchResult = accommodationService.findAllAccommodationBySearchBox(searchKeyword);
    return searchResult;
}

There are two changes:

  1. Changed the mapping to match the form action
  2. Made searchKeyword a request parameter rather than a path variable.

Also In the form you dont need the query parameter part in the action as it will be replaced by the browser during submit and the data will be appended as query parameter:

  <form action="/hms/accommodations" method="GET">
    <input type="text" name="searchKeyword"/>
    <input type="submit" value="Submit"/>
  </form>
Bijoy
  • 41
  • 5
  • I tried this but it still doesn't return anything. I tried printing strings in between the codes to see if it goes through each line but it didn't print out a single thing. Still confused as to why it can't seem to access the controller method. – Kendall H. Oct 27 '16 at 17:24
  • can you access the controller method from any other client? curl, browser? – Bijoy Oct 27 '16 at 17:32
  • Actually, when I click the Submit button, it goes to this url: http://localhost:8080/hms/accommodations?searchKeyword=keyword "keyword "is the word I typed in the input box. Does this mean I can access the controller method? – Kendall H. Oct 27 '16 at 17:39
  • Can you access "localhost:8080/hms/accommodations?searchKeyword=keyword" from a browser and see if it returns anything. If it doesnt check your Controller class has the @Controller annotation. Without it the methods will not register the mappings. – Bijoy Oct 27 '16 at 17:43
  • It can be accessed through a browser yes, but it just doesn't return anything at all. Only the same page just with a this "localhost:8080/hms/accommodations?searchKeyword=keyword" . And yes it does have a @Controller annotation. I'm pretty sure my Controller class itself is working because I have other methods in it as well and it seems to be doing just fine. Really at a lost right now. – Kendall H. Oct 27 '16 at 17:46
  • Since you can access the method but it doesnt return anything, this suggest something happening inside the method. Maybe it is not able to deserialize the return type. – Bijoy Oct 27 '16 at 17:55
  • try placing a @ResponseBody in the controller method. This will deserialize to json in the response. – Bijoy Oct 27 '16 at 17:56
  • So the problem maybe in the method itself? – Kendall H. Oct 27 '16 at 18:06
  • The odd thing for me is that it doesn't return anything at all. Not even an exception or error. – Kendall H. Oct 27 '16 at 18:07
  • I tried adding @ResponseBody by the way but it didn't do anything. – Kendall H. Oct 27 '16 at 18:11
0

The problem is with your current code, the final url becomes as below: /accommodations/hms/accommodations

In other words, total url = @RequestMapping at class level + @RequestMapping at method level (total url is what spring handler mapping sees & then maps/identifies to invoke the respective method)

Option (1) :

So, to make it working, you need to remove @RequestMapping("/accommodations") at the top (class level)

Controller class:

@Controller
public class AccommodationController {
    @RequestMapping(value = "/hms/accommodations", method = RequestMethod.GET)
     public List<Accommodation> listofAccomo(@RequestParam String searchKeyword){
         List<Accommodation> searchResult = accommodationService.findAllAccommodationBySearchBox(searchKeyword);
         return searchResult;
     }
    //add all other methods
 }

HTML:

<form action="/hms/accommodations" method="GET">
        <input type="text" name="searchKeyword"/>
        <input type="submit" value="Submit"/>
      </form>

Option (2): You can change your form as below with action as "/accommodations/hms/accommodations":

Controller class:

@Controller
@RequestMapping("/accommodations")
    public class AccommodationController {
        @RequestMapping(value = "/hms/accommodations", method = RequestMethod.GET)
         public List<Accommodation> listofAccomo(@RequestParam String searchKeyword){
             List<Accommodation> searchResult = accommodationService.findAllAccommodationBySearchBox(searchKeyword);
             return searchResult;
         }
        //add all other methods
     }

HTML:

<form action="/accommodations/hms/accommodations" method="GET">
    <input type="text" name="searchKeyword"/>
    <input type="submit" value="Submit"/>
  </form>
Vasu
  • 21,832
  • 11
  • 51
  • 67
  • With my current code, the url become **"localhost:8080/hms/accommodations?searchKeyword=keyword"** after clicking submit. – Kendall H. Oct 27 '16 at 18:05
  • thats what you would see in the browser, for which no controller url mapped – Vasu Oct 27 '16 at 18:07
  • Can you try my option(2) above ? – Vasu Oct 27 '16 at 18:07
  • I tried and it returned **localhost page not found** . – Kendall H. Oct 27 '16 at 18:10
  • Did you try my Option(1) removing the @RequestMapping at class level ? – Vasu Oct 27 '16 at 18:13
  • Yes and I got the HTTP 404 Error. – Kendall H. Oct 27 '16 at 18:16
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/126854/discussion-between-javaguy-and-kendall-h). – Vasu Oct 27 '16 at 18:21
  • Sorry for the late response Sir. I hope you can still help me. – Kendall H. Oct 28 '16 at 11:45
  • Hi Sir! I tried your sugggestions but it still didn't work. I think the problem lies within the method itself. I just couldn't quite point it out because when i run it, it doesn't really return anything at all. It doesn't even throw an exception message of some sort. I included all the other methods and the **namedquery** the method calls, you think you can see what is wrong there? – Kendall H. Oct 28 '16 at 12:14
  • Can you update the question with the latest code of RestController and Html page ? – Vasu Oct 28 '16 at 12:48
  • I have updated everything I have changed. That's just about it. – Kendall H. Oct 28 '16 at 13:01
  • Why are you having @RequestMapping("/accommodations") at the top of your class AccommodationController ? Just REMOVE IT – Vasu Oct 28 '16 at 14:07
  • Everythime I remove it, it gets **localhost page not found** . – Kendall H. Oct 28 '16 at 14:29