I am building an application which has same functionalities both from AWS and Google Cloud. For example Creating an instance , Launching instance from Machine ID, Creating snapshot, Liting all Instances,etc. Which I called using REST calls.
For example:
<form method="post" action="rest/create/new" class="form-inline">
<label for="user">User Name</label> <input type="text" id="user"
name="user" class="form-control" size="50"
placeholder="Enter Username">
<button type="submit" class="btn btn-info">Start New Machine</button>
</form>
<form method="post" action="rest/launch/start" class="form-inline">
<label for="AMId">Launch Existing Machine</label><br> <input
type="text" id="AMId" name="AMId" class="form-control" size="50"
placeholder="Enter Instance ID">
<button type="submit" class="btn btn-info">Launch</button>
<br>
</form>
<br> <br>
<form method="get" action="rest/create/listAll" class="form-inline">
<label>Show All EC2 Instances</label><br>
<button type="submit" class="btn btn-info btn-lg">Show All</button>
</form>
<br> <br>
<form method="post" **action="rest/create/listRunning"**>
<label>Show All Running EC2 Instances</label><br>
<button type="submit" class="btn btn-info">Show All Running</button>
</form>
<br> <br>
<form method="post" action="rest/create/terminate" class="form-inline">
<label for="terminateID">Enter Instance ID</label><br> <input
type="text" id="terminateID" name="terminateID" class="form-control"
size="50" placeholder="Enter Machine ID">
<button type="submit" class="btn btn-info">Terminate</button>
</form>
<br> <br>
And I am catching these rest calls in classes.
For example,
#GET
#Path("/listAll")
public Response getAllAvailableImages(#Context ServletContext context)
Now what I want is how can I use both AWS and google cloud features, using these same calls or some other method,depending on requirement or choice?
How about:
GET /{provider}/images
POST /{provider}/images/{imageID}/start
where the variables in braces are placeholders for path parameters:
{provider} may resolve to AWS, Google or another provider
{imageID} references a unique image ID
Examples:
GET /AWS/images (gets all AWS images)
POST /GoogleCloud/images (creates new Google Cloud image)
POST /OpenStack/images/gfhdh45ff4/terminate (terminates a specific image)
If you are using Spring MVC for REST, the controller could look like:
#RestController
public class ImageController {
#Autowired
private ImageService imageService;
#RequestMapping(value = "/{provider}", method = RequestMethod.GET)
#ResponseStatus(HttpStatus.OK)
public List<Image> getImages(#PathVariable String provider) {
return imageService.getImagesByProvider(provider);
}
#RequestMapping(value = "/{provider}", method = RequestMethod.POST)
#ResponseStatus(HttpStatus.CREATED)
public Image createNewImage(#PathVariable String provider, #RequestBody Image image) {
return imageService.createImageForProvider(provider, image);
}
#RequestMapping(value = "/{provider}/images/{imageId}/start", method = RequestMethod.PUT)
#ResponseStatus(HttpStatus.NO_CONTENT)
public void startImageAtProvider(#PathVariable String provider, #PathVariable String imageId) {
return imageService.startImageAtProvider(provider, imageId);
}
}
The HTTP method for starting the image could be POST - and should be if starting an image is not idempotent. But I am assuming hat attempting to start an image which is already running will just be ignored.
Extra edit:
If the image IDs are unique across ALL providers, you could shorten the REST URLs regarding images:
POST /images/gfhdh45ff4/terminate (terminates a specific image)
Related
I want to create my own registration page with spring boot, instead of sending a JSON POST request from Postman.
I currently have an HTML page with a form which submits the registration data, a registration controller, and registration service. However, it is not working properly.
My code:
RegistrationRequest
#Getter
#AllArgsConstructor
#EqualsAndHashCode
#ToString
public class RegistrationRequest {
private final String firstName;
private final String lastName;
private final String email;
private final String password;
}
Registration Controller
#RestController
#RequestMapping(path = "api/v1/registration")
#AllArgsConstructor
public class RegistrationController {
private final RegistrationService registrationService;
#PostMapping
public String register(#RequestBody RegistrationRequest request) {
return registrationService.register(request);
}
#GetMapping(path = "confirm")
public String confirm(#RequestParam("token") String token) {
return registrationService.confirmToken(token);
}
HTML form
<form class="form-signin" method="post" action="api/v1/registration">
<h2 class="form-signin-heading">Please Log in to tour agency account</h2>
<p>
<label for="firstName" class="sr-only">First name</label>
<input type="text" id="firstName" name="firstName" class="form-control" placeholder="First name" required="" autofocus="">
</p>
<p>
<label for="lastName" class="sr-only">Last name</label>
<input type="text" id="lastName" name="lastName" class="form-control" placeholder="Last name" required="" autofocus="">
</p>
<p>
<label for="email" class="sr-only">Email</label>
<input type="text" id="email" name="email" class="form-control" placeholder="Email" required="" autofocus="">
</p>
<p>
<label for="password" class="sr-only">Password</label>
<input type="password" id="password" name="password" class="form-control" placeholder="Password" required="">
</p>
<button class="btn btn-lg btn-primary btn-block" type="submit">Register</button>
</form>
Template controller
#Controller
#RequestMapping("/")
public class TemplateController {#PostMapping("register") // I know that "register is not linked with path = api/v1/registeration
public String postRegister() {
return "register";
}
}
You need either need a template engine, or you could use Javascript and submit an AJAX request for that. If you want to use a template engine, I recommend using Thymeleaf, however there are many template engines that are available for use.
Using Thymeleaf, you'd have to modify your template to include th:action, which describes your endpoint, and th:object, which is your model. Then we name it as register.html:
<form action="#" th:action="#{/api/v1/registration}" th:object="${registrationRequest}" method="post">
<!-- Form inputs... -->
<button type="submit">Register</button>
</form>
Then in the controller, we need to tell Spring about our HTML page and the model:
#GetMapping("/register")
public String registerationForm(Model model) {
model.addAttribute("registrationRequest", new RegistrationRequest());
return "register";
}
So now when we open /register, our HTML page is loaded.
Finally, modify your POST endpoint to get our form's submitted model:
#PostMapping
public String register(#ModelAttribute RegistrationRequest registrationRequest) {
return registrationService.register(request);
}
This returns the result from registration service, you could also return a string which represents a page name, e.g. return "result", here result is an HTML page result.html.
I'm trying to develop an application in spring boot + thymeleaf, and I'm able to retrieve the logged in user details in the profile tab from the MySQL database, but when I try to change one or two field details (update) and hit the update button it is showing me an error message - Fri Sep 04 20:39:47 IST 2020
There was an unexpected error (type=Method Not Allowed, status=405).
Request method 'POST' not supported
see my controller code (I'm using #RestController annotated on top of the class)-
#RequestMapping(value = "/profile", method = RequestMethod.PUT)
public ModelAndView updateProfile(#ModelAttribute Customer customer, HttpSession session) {
ModelAndView model = new ModelAndView();
Customer exist = cRepo.findByCustEmail(customer.getCustEmail());
if(exist != null) {
if(exist.getCustEmail().equals(session.getAttribute("emailsession"))) {
cRepo.save(customer);
model.addObject("msg", "User Details has been successfully updated!!");
model.setViewName("profile");
}
}else {
model.addObject("exist", "Please enter correct email address!");
String email = (String) session.getAttribute("emailsession");
Customer cust = cRepo.findByCustEmail(email);
model.addObject("customer", cust);
model.setViewName("profile");
}
return model;
}
Thymleaf code (html) -
<div align="center" class="alert alert-success" th:if="${msg}" th:utext="${msg}"></div>
<div align="center" class="alert alert-danger" th:if="${exist}" th:utext="${exist}"></div>
<!-- Modal HTML -->
<div id="myModal">
<div class="modal-dialog modal-login">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Profile Details</h4>
</div>
<div class="modal-body">
<form name="myForm" th:action="#{/profile}" th:object="${customer}" method="post">
<div class="form-group">
<i class="fa fa-id-card"></i>
<input name="id" type="text" class="form-control" placeholder="Enter Id" th:field="${customer.custId}" disabled="true" required="required" />
</div>
<div class="form-group">
<i class="fa fa-user"></i>
<input name="name" type="text" class="form-control" placeholder="Enter Name" th:field="${customer.custName}" required="required" />
</div>
<div class="form-group">
<i class="fa fa-envelope"></i>
<input name="email" type="email" class="form-control" placeholder="Enter Email" th:field="${customer.custEmail}" required="required" />
</div>
<div class="form-group">
<i class="fa fa-lock"></i>
<input name="password" type="text" class="form-control" placeholder="Enter Password" th:field="${customer.custPassword}" required="required" />
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary btn-block btn-lg" value="Update" />
</div>
</form>
</div>
</div>
</div>
</div>
I want when user login and visit he/she should be able to check his/her profile(which I'm able to do working code) and when the user wants to update few fields(1-2 based on choice) and hit update he/she should be able to update the details (not create new user or record) because when I use #Controller on top of class then this code work and create new user instead update.
Your controller is annotated with #RequestMapping(value = "/profile", method = RequestMethod.PUT) which makes it a PUT endpoint. However, your request is clearly a POST. If we look at your html form it contains method="post". HTML forms only support GET and POST as valid methods so you need to update your endpoint to be a POST endpoint.
tldr;
RequestMapping(value = "/profile", method = RequestMethod.PUT)
to
RequestMapping(value = "/profile", method = RequestMethod.POST)
You request mapping in is POST but Controller has set to accept request as PUT.
<form name="myForm" th:action="#{/profile}" th:object="${customer}" **method="post"**>
#RequestMapping(value = "/profile", method = **RequestMethod.PUT**)
Just keep these in similar way both should be same.
Please check what I find and resolve this.
#RequestMapping(value = "/profile" ,method = RequestMethod.POST)
public ModelAndView updateProfile(#ModelAttribute Customer customer, HttpSession session) {
ModelAndView model = new ModelAndView();
Customer exist = cRepo.findByCustEmail(customer.getCustEmail());
if(exist != null) {
if(exist.getCustEmail().equals(session.getAttribute("emailsession"))) {
**exist.setCustId(exist.getCustId());
exist.setCustName(customer.getCustName());
exist.setCustEmail(customer.getCustEmail());
exist.setCustPassword(customer.getCustPassword());**
cRepo.save(exist);
model.addObject("msg", "User Details has been successfully updated!!");
model.addObject("customer", exist);
model.setViewName("profile");
}
}else {
model.addObject("exist", "Please enter correct email address!");
String email = (String) session.getAttribute("emailsession");
Customer cust = cRepo.findByCustEmail(email);
model.addObject("customer", cust);
model.setViewName("profile");
}
return model;
}
Cuba has its own backend system to add users.
Now I need to write a user registration in the front-end.
The Cuba version I am using is 6.9
I know that this version of encryption is SHA1 : https://doc.cuba-platform.com/manual-6.9/login.html
Now my question is : I don't know how to set the encrypted password to the database.
I create an entity through the Metadata
User user = metadata.create(User.class);
user.setPassword(passWord);
I'm not sure that's the best option but I used the following code:
#Inject
protected PasswordEncryption passwordEncryption;
...
user.setPassword(passwordEncryption.getPasswordHash(user.getId(), password));
I think you just need to create html file with this code:
<div class="span6">
<h3>Login</h3>
<div th:if="${(param.error != null)}">
<p>Invalid username / password</p>
</div>
<form id="f" name="f" method="POST" action="login">
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
<div>
<div>
<label style="width: 80px" for="login">Login</label>
<input type="text" id="login" name="login" value=""/>
</div>
<div>
<label style="width: 80px" for="password">Password</label>
<input type="password" id="password" name="password" value=""/>
</div>
</div>
<button type="submit">Login</button>
</form>
</div>
and then Request it from Controller:
#RequestMapping(value = "/", method = RequestMethod.GET)
public String index(Model model) {
if (PortalSessionProvider.getUserSession().isAuthenticated()) {
LoadContext l = new LoadContext(User.class);
l.setQueryString("select u from sec$User u");
model.addAttribute("users", dataService.loadList(l));
}
return "index";
}
Hi I'm new with Spring and I'm having problems in passing data between two pages using two different controllers.
I would like to know how I can handle this situations.
In my index.html I have a button that should redirect me to a new page passing some data. When i click the button it redirects me to the step2 page but I don't have to objects. How can I solve this? Is the GET method correct? Do I have to use the form just for passing some data between pages and controllers?
Below is what I have.
Index.html
<form th:action="#{/step2}" method="GET">
<input type="hidden" th:value="${mapSelectedServices}" name="mapSelectedServices"/>
<input type="hidden" th:value="${user}" name="loggedUser"/>
<div class="form-group d-flex align-items-center justify-content-between">
<button type="submit" class="btn btn-danger btn-rounded ml-auto" >SEE PRICES
<i class="fas fa-long-arrow-alt-right ml-2"></i>
</button>
</div>
</form>
Step2Controller
#RequestMapping(value="step2", method = RequestMethod.GET)
public ModelAndView step2(ModelAndView modelAndView, #ModelAttribute("user") User user,
#ModelAttribute("mapSelectedServices") HashMap<String,List<ServiceOffered>> mapSelectedServices,
BindingResult bindingResult){
modelAndView.addObject("user", user);
modelAndView.addObject("mapSelectedServices", mapSelectedServices);
modelAndView.setViewName("step2");
return modelAndView;
}
Sorry for all the questions, but I'm new to spring development.
HTML page:
<form th:action="#{/step2}" method="POST">
<input type="hidden" th:value="${mapSelectedServices}" name="mapSelectedServices"/>
<input type="hidden" th:value="${user}" name="loggedUser"/>
<div class="form-group d-flex align-items-center justify-content-between">
<button type="submit" class="btn btn-danger btn-rounded ml-auto" >SEE PRICES
<i class="fas fa-long-arrow-alt-right ml-2"></i>
</button>
</div>
</form>
Controller method:
public ModelAndView goToPgae2(#ModelAttribute ModelClass aClass)
{
ModelAndView mv=new ModelAndView("SecondHtlmPageName");//setting view name here
mv.addAttribute("aClass",aClass);
return mv;
}
Model Class with the specific variables passed from one page to another:
class ModelClass {
public Stirng mapSelectedServices; //use appropriate data type.
public String loggedUser;
//create getters and setters
}
Second page
<div>${aClass.loggedUser}</div>
DONE.
This way you can go to second page . And if you want to redirect to second page and the model attributes should be available there then you need to use flashattribute.
I started working with thymeleaf.
I am following this page: Spring MVC view layer: Thymeleaf vs. JSP
I have got a class:
public class MyMainObject {
private String a;
private String b;
private String c;
private String d;
private String e;
// getters and setters
}
I also have got a controller:
#Controller
public class MyMainObjectController extends AbstractController
#RequestMapping({"/subscribeth"})
public String getObj(final MyMainObject subscription) {
return "subscribeth";
}
}
Here is my html code:
<form action="#" th:object="${subscription}" th:action="#{/subscribeth}">
<fieldset>
<div>
<label for="a" th:text="#{subscription.a}">a:
</label> <input type="text" th:field="*{a}" />
</div>
<div>
<label for="b" th:text="#{subscription.b}">b:
</label> <input type="text" th:field="*{b}" />
</div>
<div>
<label for="c" th:text="#{subscription.c}">c: </label>
<input type="text" th:field="*{c}" />
</div>
<div>
<label for="d" th:text="#{subscription.d}">d:
</label> <input type="text" th:field="*{d}" />
</div>
<div>
<label for="e" th:text="#{subscription.e}">e:
</label> <input type="text" th:field="*{e}" />
</div>
<div class="submit">
<button type="submit" name="save" th:text="#{subscription.submit}">Subscribe me!</button>
</div>
</fieldset>
</form>
When I run mu application I have an error:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring3.processor.attr.SpringInputGeneralFieldAttrProcessor'
org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring3.processor.attr.SpringInputGeneralFieldAttrProcessor'
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'subscription' available as request attribute
It looks like, I have to create bean subscription.
And here is my question, how I can do that? I downloaded source code from the tutorial I mentioned before and I cannot find it.
Thank you in advance
Annotate your controller handler method's parameter with #ModelAttribute("subscription"). By default, without the value given, Spring will generate an attribute name based on the type of the parameter. Thus MyMainObject will become myMainObject.
I am a beginner, when I had this problem, It was solved by adding model.addAttribute("modelname", new modelObj()); before returning the view-name, eg:
#RequestMapping(value="/login", method=RequestMethod.GET)
public String showLogin(Model model, HttpSession session)
{
model.addAttribute("userForm", new UserForm());
return "users";
}