I'm writing web application using SpringMVC. I would like to keep some data in session until user logout. Earlier I did it by #SessionAttributes("someData"), but then I had to put #ModelAttribute("someData") someDataType someData as argument for every request mapping method. So this is what I did :
My AccessData class :
#Component
#Scope(value = "session")
public class AccessData {
private long userID;
private String userKey;
public AccessData(long ID, String key) {
this.userID = ID;
this.userKey = key;
}
public long getUserID() {
return userID;
}
public void setUserID(long userID) {
this.userID = userID;
}
public String getUserKey() {
return userKey;
}
public void setUserKey(String userKey) {
this.userKey = userKey;
}
}
First controller(here I'm getting and validating user input from form) :
#Controller
#Scope(value = "session")
public class LoginController {
#ModelAttribute("accessData")
public AccessData getAccessData() {
return this.accessData;
}
private Utils utilsService;
private LoginService loginService;
#Autowired
private AccessData accessData;
#Autowired
public LoginController(LoginService loginService, Utils utils) {
this.loginService = loginService;
this.utilsService = utils;
}
#RequestMapping(value = ControllerPaths.LOGIN, method = RequestMethod.POST)
public ModelAndView showLoginStatus(
#ModelAttribute(LOGINDATA) LoginData loginData) {
try {
accessData = loginService.validateLoginData(loginData);
} catch (IncorrectLoginDataException e) {
logger.trace("Showing fail login screen...");
return utilsService.getShowView(ViewPaths.LOGIN_FAIL);
} catch (HTTPException e) {
return utilsService.getShowViewWithStringAttribute(
ViewPaths.INFO_VIEW, MESSAGE, CONNECTION_ERROR);
}
return utilsService.getShowView(ViewPaths.LOGIN_SUCCESS);
}
}
Second controller :
#Controller
#Scope(value = "session")
public class SecondController {
#ModelAttribute("accessData")
public AccessData getAccessData() {
return this.accessData;
}
private Utils utilsService;
private LoginService loginService;
#Autowired
private AccessData accessData;
#Autowired
public SecondController(LoginService loginService, Utils utils) {
this.loginService = loginService;
this.utilsService = utils;
}
#RequestMapping(value = ControllerPaths.SHOW_ACCESS_DATA, method = RequestMethod.GET)
public ModelAndView showAccessData(
System.out.println(accessData.getUserKey());
return utilsService.getShowView(ViewPaths.INDEX);
}
}
The problem is that when I'm printing userKey value in second controller, the value is null. I checked if I'm getting correct data from server in LoginController and it's ok. So what am I doing wrong? Thanks in advance for help
The problem is that you are assigning a new object to the accessData variable. Instead you should update the field of the object that it is already referring to.
accessData = loginService.validateLoginData(loginData);
// Replace above line with something like this. Implement the copyProperties
// method to copy the attributes you need
AccessData newAccessData = loginService.validateLoginData(loginData);
copyPropteries(accessData,newAccessData);
Also it is not required to make the Controllers session scoped, add proxyMode=TARGET_CLASS to the scope annotation of the AccessData class.
Related
findAll() of mongoRepository returns empty list. what is wrong with the below code?
API used for counting the number of documents in the collection works fine.
Controller
#RestController
#RequestMapping("/api/api-management/scopes")
public class AuthScopesController {
private final ScopesService scopesService;
#Autowired
AuthScopesController(ScopesService scopesService) {
this.scopesService = scopesService;
}
#PostMapping("/")
public AuthScope createScope(#RequestBody AuthScope authScope) {
return scopesService.createAuthScope(authScope);
}
#GetMapping("/")
public List<AuthScope> getAllScopes() {
return scopesService.getAuthScopes();
}
}
service
#Service
public class ScopesService {
private final AuthScopeRepository authScopeRepository;
public ScopesService(AuthScopeRepository authScopeRepository) {
this.authScopeRepository = authScopeRepository;
}
public AuthScope createAuthScope(AuthScope authScope) {
return authScopeRepository.save(authScope);
}
//TODO: recheck
public List<AuthScope> getAuthScopes() {
return authScopeRepository.findAll();
}
}
repository
#Repository
public interface AuthScopeRepository extends MongoRepository<AuthScope, String> {
Optional<AuthScope> findByScope(String id);
}
model is as follows
#Data
#Document("auth-scopes")
public class AuthScope {
#Id
private String scope;
private String belongsToApi;
private String belongsToApiTitle;
private String description;
}
found the issue. in order to findAll() to work, the model has to have deleted status.
I've updated the model as follows
#Data
#Document("auth-scopes")
public class AuthScope {
#Id
private String scope;
private String belongsToApi;
private String belongsToApiTitle;
private String description;
private boolean deleted;
}
i am creating a simple spring boot project when i run the project ran into the problem with Spring Boot Ambiguous mapping. Cannot map method. i have create two various controller those are student and course controller.i completly attached the error below.
i attached the full
**gub link here** https://github.com/raguram1986/SpringSecuritys
Full Error i attached below
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'studentController' method
com.example.studentmanagement.Controller.StudentController#saveStudent(Student)
to {POST [/save]}: There is already 'courseController' bean method
com.example.studentmanagement.Controller.CourseController#saveCourse(Course) mapped.
Controller
#Controller
public class StudentController {
#Autowired
private StudentService service;
#GetMapping("/Student")
public String viewHomePage(Model model) {
List<Student> liststudent = service.listAll();
// model.addAttribute("liststudent", liststudent);
System.out.print("Get / ");
return "Student";
}
#GetMapping("/addStudent")
public String add(Model model) {
List<Student> liststudent = service.listAll();
model.addAttribute("liststudent", liststudent);
model.addAttribute("student", new Student());
return "addstudent";
}
#RequestMapping(value = "/save", method = RequestMethod.POST)
public String saveStudent(#ModelAttribute("student") Student std) {
service.save(std);
return "Student";
}
#RequestMapping("/edit/{id}")
public ModelAndView showEditStudentPage(#PathVariable(name = "id") int id) {
ModelAndView mav = new ModelAndView("addstudent");
Student std = service.get(id);
mav.addObject("student", std);
return mav;
}
#RequestMapping("/delete/{id}")
public String deleteStudentPage(#PathVariable(name = "id") int id) {
service.delete(id);
return "Student";
}
Student
#Entity
public class Student {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
private String stname;
private String course;
private int fee;
public Student() {
}
public Student(Long id, String stname, String course, int fee) {
this.id = id;
this.stname = stname;
this.course = course;
this.fee = fee;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getStname() {
return stname;
}
public void setStname(String stname) {
this.stname = stname;
}
public String getCourse() {
return course;
}
public void setCourse(String course) {
this.course = course;
}
public int getFee() {
return fee;
}
public void setFee(int fee) {
this.fee = fee;
}
StudentRepository
#Repository
public interface StudentRepository extends JpaRepository<Student, Long>{
}
Service
#Service
public class StudentService
{
#Autowired
private StudentRepository repo;
public List<Student> listAll() {
return repo.findAll();
}
public void save(Student std) {
repo.save(std);
}
public Student get(long id) {
return repo.findById(id).get();
}
public void delete(long id) {
repo.deleteById(id);
}
}
In your StudentController you have the endpoint /save
#RequestMapping(value = "/save", method = RequestMethod.POST)
public String saveStudent(#ModelAttribute("student") Student std) {
service.save(std);
return "Student";
}
But you haven't included the CourseController class in your question, which is mentioned in the error.
If you have defined an endpoint /save in that CourseController, then you have to rename it. Otherwise, when you invoke /save which controller needs to be invoked cannot be determined.
Add #RequestMapping above StudentController as below
#Controller
#RequestMapping("/students")
public class StudentController {
...
}
You are getting exception because there is already a mapping defined for path
/save
without being any controller mapping, so the first with root mapping is considered, but the next time it encounters same mapping it is already registered hence it is complaining. For clarity i'd suggest to add #RequestMapping to CourseController as well.
So now your course controller also becomes:
#Controller
#RequestMapping("/courses")
public class CourseController {
...
}
The best practice is to always add a request mapping at class level as well, like in your case, add a mapping like "/students" for SutdentController and "/course" for CourseController itself and then all other methods will be under that i.e. "/student/save" and then you will not face this issue anymore.
Ok so I am new to spring and don't really know how this works. I have been trying a few things and think its close to doing it but not getting any data from the server and giving me this error
Unsatisfied dependency expressed through constructor argument with index 4 of type [jp.co.fusionsystems.dimare.crm.service.impl.MyDataDefaultService]: : Error creating bean with name 'MyDataDefaultService' defined in file
My end point
//mobile data endpoint
#RequestMapping(
value = API_PREFIX + ENDPOINT_MyData + "/getMyData",
method = RequestMethod.GET)
public MyData getMyData() {
return MyDataDefaultService.getData();
}
My Object
public class MyData {
public MyData(final Builder builder) {
videoLink = builder.videoLink;
}
private String videoLink;
public String getVideoLink()
{
return videoLink;
}
public static class Builder
{
private String videoLink = "";
public Builder setVideo(String videoLink)
{
this.videoLink = videoLink;
return this;
}
public MyData build()
{
return new MyData(this);
}
}
#Override
public boolean equals(final Object other) {
return ObjectUtils.equals(this, other);
}
#Override
public int hashCode() {
return ObjectUtils.hashCode(this);
}
#Override
public String toString() {
return ObjectUtils.toString(this);
}
}
The Repository
public classMyServerMyDataRepository implements MyDataRepository{
private finalMyServerMyDataJpaRepository jpaRepository;
private final MyDataConverter MyDataConverter = new MyDataConverter();
#Autowired
publicMyServerMyDataRepository(finalMyServerMyDataJpaRepository jpaRepository) {
this.jpaRepository = Validate.notNull(jpaRepository);
}
#Override
public MyData getData() {
MyDataEntity entity = jpaRepository.findOne((long) 0);
MyData.Builder builder = new MyData.Builder()
.setVideo(entity.getVideoLink());
return builder.build();
}
The DefaultService that gets called by the endpoint
public class MyDataDefaultService {
private static final Logger logger = LoggerFactory.getLogger(NotificationDefaultService.class);
private finalMyServerMyDataRepository repository;
#Autowired
public MyDataDefaultService(MyServerMyDataRepository repository) {
this.repository = Validate.notNull(repository);
}
//Get the data from the server
public MobileData getData()
{
logger.info("Get Mobile Data from the server");
//Get the data from the repository
MobileData mobileData = repository.getData();
return mobileData;
}
}
The Converter
public class MyDataConverter extends AbstractConverter<MyDataEntity, MyData>
{
#Override
public MyData convert(MyDataEntity entity) {
MyData.Builder builder = new MyData.Builder()
.setVideo(entity.getVideoLink());
return builder.build();
}
}
My Entity
#Entity
#Table(name = “myServer”)
public class MyDataEntity extends AbstractEntity{
#Column(name = "video_link", nullable = true)
private String videoLink;
public String getVideoLink() {
return videoLink;
}
public void setVideoLink(final String videoLink) {
this.videoLink = videoLink;
}
}
Thank you for any help with this
Hibernate entity should have default constructor defined and implement Serializable interface as well, assume AbstractEntity matches the requirement. Hibernate won't accept an entity without a primary key so you have to define the one too:
#Entity
#Table(name = “myServer”)
public class MyDataEntity implements Serializable {
#Id
#GeneratedValue
private Long id;
#Column(name = "video_link", nullable = true)
private String videoLink;
public MyDataEntity() {
}
...setters&getters
}
MyData object represents the JSON server response, you can use Jackson annotations to control the result JSON properties:
public class MyDataResponse {
#JsonProperty("video_link")
private String videoLink;
public MyDataResponse() {
}
public MyDataResponse(String videoLink) {
this.videoLink = videoLink;
}
...setters&getters
}
Spring has an awesome project so called Spring Data that provides the JPA repositories, so there's no even the #Repository annotation ever needed:
public class MyDataRepository extends CrudRepository<MyDataEntity, Long> {
}
The Builder class represents the Service layer:
#Service
public class MyDataService {
#Autowired
private MyDataRepository myDataRepository;
public MyDataResponse getMyData(Long id) {
MyDataEntity entity = myDataRepository.findOne(id);
...rest logic, copy necessary data to MyDataResponse
}
}
Then a controller is:
#RestController // #ResponseBody not needed when using like this
public MyDataController {
#Autowired
private MyDataService myDataService;
#RequestMapping("/getMyData") // no need to specify method for GET
public MyDataResponse getMyData(#RequestParam("ID") Long myDataId) {
... validation logic
return myDataService.getMyData(myDataId); // return response
}
}
Now it should work, don't forget to add required dependencies to your classpath.
I wrote this Webservice using Spring Data MVC:
Rest Controller
#RestController
#RequestMapping("/textmessages")
public class TextMessageRestController {
#Autowired
private TextMessageService textMessageService;
#RequestMapping(value = "/send", method = RequestMethod.PUT)
#ResponseStatus(HttpStatus.CREATED)
public void insertTextMessage(#RequestBody TextMessage.TextMessageDTO textMessageDTO) {
textMessageService.save(textMessageDTO);
}
}
Spring Service
#Service
#Transactional
public class TextMessageService {
#Autowired
private TextMessageRepository textMessageRepository;
#Autowired
private UserService userService;
public void save(TextMessage message) {
textMessageRepository.save(message);
}
public void save(TextMessage.TextMessageDTO textMessageDTO) {
save(from(textMessageDTO));
}
public TextMessage from(TextMessage.TextMessageDTO textMessageDTO) {
User sender = userService.from(textMessageDTO.getSender());
User receiver = userService.from(textMessageDTO.getReceiver());
return new TextMessage(receiver, sender, textMessageDTO.getSymmetricKeyEncrypted(), textMessageDTO.getText());
}
}
DTO - a static inner class
//This annotations are from Lombok
#Getter
#Setter
#AllArgsConstructor(access = AccessLevel.PRIVATE)
public static class SenderReceiverDTO {
private String username;
private String pk;
public static SenderReceiverDTO from(User user) {
SenderReceiverDTO dto = new SenderReceiverDTO(user.username, user.pk);
return dto;
}
}
When I try to consume that REST Service, I get following Exception:
Consuming the rest service
public class RestService {
private static final String REST_STRING = "http://localhost:8080/cchat/";
private static final String TXT_MSG_STRING = REST_STRING + "textmessages/";
private static final String SEND_TXT_MSG = TXT_MSG_STRING + "send/";
private final RestTemplate restTemplate;
public RestService() {
this.restTemplate = new RestTemplate();
}
#SuppressWarnings("unchecked")
public List<TextMessage.TextMessageDTO> loadTextMessages(User.UserIdentifyingDTO userIdentifyingDTO) {
return restTemplate.postForObject(RECEIVE_TXT_MSG, userIdentifyingDTO, List.class);
}
}
i get the excpetion
org.springframework.web.client.HttpClientErrorException: 400 Bad Request
at foo.RestService.sendTextMessage(RestService.java:33)
Tests prove that the server-side is working properly!
Any ideas what may cause the problem?
i have small web application in spring mvc and hibernate.
in this web service via push notification to database into data is automatically push into android device.
how to do push notification?
restful controller
#Controller
#RequestMapping("/json")
public class JsonData
{
#Autowired
private AdminService adminService;
#GET
#RequestMapping(value="/jsonEnglishWord")
#Produces(MediaType.APPLICATION_JSON)
public #ResponseBody List<English_Word> getAllWord() {
return new ArrayList<English_Word>(adminService.getAllWord());
}
#GET
#RequestMapping(value="/jsonGujaratiWord")
#Produces(MediaType.APPLICATION_JSON)
public #ResponseBody List<Gujarati_Word> getallGujarati_Words(){
return new ArrayList<Gujarati_Word>(adminService.getAllGujaratiword());
}
database model
#Entity
#Table(name="English_Word")
public class English_Word {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int word_id;
private String word_name;
#Lob
private String word_explain;
#Temporal(TemporalType.DATE)
private Date word_date;
public int getWord_id() {
return word_id;
}
public void setWord_id(int word_id) {
this.word_id = word_id;
}
public String getWord_name() {
return word_name;
}
public void setWord_name(String word_name) {
this.word_name = word_name;
}
public String getWord_explain() {
return word_explain;
}
public void setWord_explain(String word_explain) {
this.word_explain = word_explain;
}
public Date getWord_date() {
return word_date;
}
public void setWord_date(Date word_date) {
this.word_date = word_date;
}
}
Please refer following link. It helps me. check for java code. first create app on google
http://javapapers.com/android/google-cloud-messaging-gcm-for-android-and-push-notifications/