Creating Quiz (Quastionare) using Spring MVC + JSP - java

i need your help. My brain will explode without your help! I am writting Quiz app on Spring MVC + JSP.
What i done for now:
1. I created HashMap + hardcode correct answer.
2. I created #RequestMapping(value = "/level_one", method = RequestMethod.POST)
public String levelOne() {
return "levelone";
}
How it shoul be:
pics
Then i just freezed and i don't know what to do and how to unite this code in #RequestMaping with HashMap and write code in jsp to make it visible and clickable???
In controller i wrote :
package ua.kiev.prog;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.util.HashMap;
import java.util.Map;
#Controller
#RequestMapping("/")
public class MyController {
final private String rightAnswerOne = "Dance";
#ModelAttribute("answerList")
public Map answerList() {
Map<String, String> answerList = new HashMap<String, String>();
answerList.put("one", "Sandbox");
answerList.put("two", "Pixel");
answerList.put("three", "Game");
answerList.put("four", "Picture");
return answerList;
}
#RequestMapping(value = "/level_one", method = RequestMethod.POST)
public String levelOne() {
return "levelone";
}
}

#modelAttribute is executed before the request mapping. That populate the Model model object (that you didn't pass as a parameter on the method annotated with #requestmapping.
You can access to that object using model.asMap().Get("yourkey").
#RequestMapping(value = "/level_one", method = RequestMethod.POST) public String levelOne(Model model) {
model.asMap().get("answerList");
...
return "levelone"; }
This is how modelattribute works but it is a long argument. You might search for some tutorial on spring MVC.
I recommend to Google mkyong spring mvc, he has a huge set of basic tutorials for spring mvc , easy to understand.
Check this link
http://www.mkyong.com/spring3/spring-3-mvc-hello-world-example/

Thank you.I will do it. But on this example, please answer on one more question. If i write code as you wrote before. How should i write jsp page, to unite answers from hash map in the controller and web view? So then if i click on the button on the web, it will be united with hash map on the server side page.
So then i will be able to write something like this:
public static int getCount(HashMap<String, String> answerList, String rightAnswerOne, String rightAnswerTwo, String message) {
int count = 0;
for (String tmp : answerList.values()) {
if (rightAnswerOne.equals(tmp) ) {
count++;
System.out.println("SUCCESS");
} else {
System.out.println("DENIED");
}
}
return count;
}
I just want to understand how to write such things.

Related

How to create Spring Boot REST service "type: POST"?

I'm a beginner in spring boot and I'm trying to create REST endpoint that's adding two numbers (type: POST) so can anyone help me with that and tell me where is the problems in my code??
package demo.controller;
import org.springframework.beans.factory.annotation.Autowired;
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.RestController;
import demo.service.ServiceAdding;
#RestController
public class DemoController {
#Autowired
private ServiceAdding ServiceAdding;
#RequestMapping(value="/getNumbers", method=RequestMethod.GET)
public ServiceAdding getNumbers() {
ServiceAdding.setNumber1(1);
ServiceAdding.setNumber2(3);
return ServiceAdding;
}
#RequestMapping(value="/postNumbers", method=RequestMethod.POST)
public int postNumbers (#RequestBody final ServiceAdding ServiceAdding ) {
int sum = ServiceAdding.getNumber1() + ServiceAdding.getNumber2();
return sum;
}
}
Try using #PostMapping instead of #RequestMapping
#PostMapping(value = "postNumbers")
public int postNumbers(...){
...
}
what errors are you getting?
Also try adding a value to the restController maybe?
#RestController(value="api/v1")
#RequestMapping(value = "/getNumbers, method = RequestMethod.GET, produces = "application/json")
You can also use #GetMapping, #PostMapping etc
Sounds like you're not performing a POST request. How do you load that URL?
You need to have either:
Webpage that has a FORM that does a POST
Use a tool like PostMan (or similar tool) to submit the post request.
The correct one should be like below :
#RestController
#RequestMapping("/api")
public class DemoController {
... other codes
#RequestMapping(value="/postNumbers", method=RequestMethod.POST)
public int postNumbers (#RequestBody SumNumbersRequest sumNumbersRequest)
{
int sum = sumNumbersRequest.getNumber1() + sumNumbersRequest.getNumber2();
return sum;
}
}
#Data // from Lombok for getter setter
class SumNumbersRequest {
private int number1;
private int number2;
}
And you should post json request to url localhost:8080/api/postNumber as below with Content-Type : application/json :
{
"number1":5,
"number2":15
}

Convert Spring MVC to Spring fullREST JSON application

I make application in Java Spring similar to:
Java Blog Aggregator
Author of this app use Spring MVC and common http request. Is it fast way to remodel of controllers to full rest application which use AJAX?
I do not know where to start.
I would like to send JSON. I don't have my own code now, cause I just getting started.
Example of controller:
package cz.jiripinkas.jba.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import cz.jiripinkas.jba.service.ItemService;
#Controller
public class IndexController {
#Autowired
private ItemService itemService;
#RequestMapping("/index")
public String index(Model model) {
model.addAttribute("items", itemService.getItems());
return "index";
}
}
Thanks for any help.
Yes, you can do that, follow these steps:-
Download a JSON API jar and include that library in your application. You can download one HERE
Convert your public String index(Model model) method to public void index(Model model, HttpServletResponse response).
Remove the line return "index"; as now your method is of void type.
Contruct a JSON with the library you just added. You will finally have an object of type JSONObject
Once you have this object, convert and store into a String. For example, if you have a variable named returnJSONObj of type JSONObject, you can write convert it into a String as String returnJSONStr = returnJSONObj.toString()
Finally, you have write the output at a JSON String:-
response.setContentType("application/json");
response.getWriter.println(returnJSONStr);
This will make your method return a JSON String, which you can use in your REST API.
EDIT
Added sample code for reference
package cz.jiripinkas.jba.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import cz.jiripinkas.jba.service.ItemService;
#Controller
public class IndexController {
#Autowired
private ItemService itemService;
#RequestMapping("/index")
public void index(Model model, HttpServletResponse response) {
List items = itemService.getItems();
String returnJSONStr = createJSONStr(items);
response.setContentType("application/json");
response.getWriter().println(returnJSONStr); //this method throws IOException
}
private String createJSONStr(List items) {
JSONObject json = new JSONObject();
for(Item item: items) { //For each item
json.put("property1", item.getProperty1()); //replace by your own properties
json.put("property2", item.getProperty2());
}
return json.toString();
}
}
You can make this a REST Webservice by :
1) Replacing #Controller with #RestController.
2) Changing #RequestMapping("/index") to :
#RequestMapping(value="/index",
method=RequestMethod.GET,
produces=MediaType.APPLICATION_JSON_VALUE)
3) And if you intent to on receiving some payload in this index web service then replace RequestMethod.GET with RequestMethod.POST and change parameters of index function to some DTO object which will map with json you want to receive and annotate it with #RequestBody(This is optional in case you are using #RestController).
EDIT :
4) If you want to return a JSON object , you just need to create a bean with attribute names same as your keys :
class User {
private String id;
private String name;
public void setName(String name){
this.name=name;
}
public void getName(){
return this.name;
}
public void getId(){
return this.id;
}
public void setId(String id){
this.id=id;
}
}
and return this object from the method as follows :
#RequestMapping(value="/index",
method=RequestMethod.GET,
produces=MediaType.APPLICATION_JSON_VALUE)
public User index() {
User user = new User();
user.setId("1");
user.setName("Test");
return user;
}

GET request for receiving the parameter from android in spring REST API?

I am trying to write the spring REST code to get the parameters send by the android users. For example android users fills out the form and click send button. Now I want to receive the values or parameters in REST API. I search google but could not figure out how to do it. Below is the code I tried but it didn't work
EmailController.java
package com.intern.training
import java.awt.PageAttributes.MediaType;
import java.util.Map;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.WebRequest;
#RestController
#RequestMapping("/email")
public class EmailController
{
#RequestMapping(method= RequestMethod.GET)
public void getAll(WebRequest webRequest)
{
Map<String,String[]>params=webRequest.getParameterMap();
System.out.println(params);
}
}
I strongly advice you to not send parameters with a GET request. Prefer a POST request. (See Cross-site request forgery)
Then, create a class which represents the parameters that you are to receive :
public class RequestParams {
private String name;
private String surname;
//Getters, Setters...
}
Then expect this object as a param of your method :
#RequestMapping(method= RequestMethod.POST)
/**
Pay attention to the above #RequestBody annotation
or you will get null instead of the parameters
**/
public void getAll(#RequestBody RequestParams request)
{
request.getName();
request.getSurname();
//...
System.out.println(request.getName() + " " + request.getSurname());
}

In Spring-MVC, how do I dynamically set constructor arguments of a session attribute?

We are building a webapp that communicates with a remote API. I would like to design the client for this remote API like this:
def RemoteApi
constructor (username, password)
getCurrentUser() //implementation will use username and password
getEmployees() //implementation will use username and password
...
The point being, I want to pass in the credentials to this client during construction, and have all the other methods use these credentials. My second requirement is I want this RemoteApi instance to be in the session.
I have found out how to pass dynamic constructor arguments here.
I have found out how to create a session attribute here.
But I can't figure out a way to combine these two techniques. From what I gather, you have to instantiate a session attribute in its own getter-like method. This getter-like method won't have access to the form's fields so I won't be able to pass in credentials at this point.
Here's where I'm stuck:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.SessionAttributes;
import java.util.Map;
#Controller
#SessionAttributes("remoteClient")
public class LoginController {
#Value("${company.name}")
private String companyName;
#Autowired
private RemoteClient remoteClient;
#ModelAttribute("remoteClient")
public RemoteClient addRemoteClientToSession() {
return remoteClient; //how do initialize this with credentials in here?
}
#RequestMapping("/")
public String showLogin(Model model) {
model.addAttribute("credentials", new Credentials());
return "login";
}
#RequestMapping("/login")
public String login(#ModelAttribute("credentials") Credentials credentials, Map<String, Object> model) {
if (remoteClient.auth(companyName, credentials.getUsername(), credentials.getPassword())) {
model.put("fullname", remoteClient.findCurrentUser().getName());
return "projectView";
} else {
return "login";
}
}
}
Update: Maybe the solution has to do with this technique. I didn't know about ModelAndView before this.
The article I linked to in the question did have the necessary technique in it. What I would do is create an #Autowired RemoteApiFactory that has a newInstance(Credentials) method and pass that into addObject. The implementation of newInstance would probably end up using the new keyword. If anyone knows how to avoid this detail, I'd love to hear it.
Here's its example tweaked for my needs:
#Controller
#SessionAttributes("remoteApi")
public class SingleFieldController {
#Autowired
private RemoteApiFactory remoteApiFactory;
#RequestMapping(value="/single-field")
public ModelAndView singleFieldPage() {
return new ModelAndView("single-field-page");
}
#RequestMapping(value="/remember")
public ModelAndView rememberThought(#MethodAttribute("credentials") Credentials credentials) {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("remoteApi", remoteApiFactory.newInstance(credentials));
modelAndView.setViewName("single-field-page");
return modelAndView;
}
}

How to show different JSP page depending on certain conditions in Spring MVC Controller?

I am working on Spring MVC controller project. I have a JSP page which contains certain forms and people will type certain entries in it and then press submit button.
Now below is my code base - As soon as I hit this url on the browser -
http://localhost:8080/testweb/testOperation
It automatically goes to below method if I put a breakpoint and then it shows me my testOperation jsp page on the browser and it works fine.
#RequestMapping(value = "testOperation", method = RequestMethod.GET)
public Map<String, String> testOperation() {
final Map<String, String> model = new LinkedHashMap<String, String>();
return model;
}
Now what I am trying to do is - suppose in the below method as soon as the call comes, I will extract IP Address from the headers where the call is coming, if the IP Address doesn't matches, then I would like to show error JSP page but if the IP Address matches then I would show testOperation jsp page.
#RequestMapping(value = "testOperation", method = RequestMethod.GET)
public Map<String, String> testOperation(final HttpServletRequest request) {
final Map<String, String> model = new LinkedHashMap<String, String>();
//is client behind something?
String ipAddress = request.getHeader("X-FORWARDED-FOR");
if (ipAddress == null) {
ipAddress = request.getRemoteAddr();
}
if(ipAddress.equals("something_here")) {
// then load testOperation jsp page
} else {
// otherwise load some error jsp page
}
return model;
}
Is this possible to do somehow?
As noted in another answer, you can definitely do what you are asking just by returning a different ModelAndView (or even just the model name will do), but if are planning to use the IP lookup strategy I would suggest you take a look at Spring MVC's HandlerInterceptor.
Take a look at this blog post for more details
EDIT
Actually I am revising my thinking... I am now suggesting that you should use a HandlerMethodArgumentResolver to inject the a boolean that shows whether or not the user is behind something, into your controller method. The relevant code would be :
#Target(ElementType.PARAMETER)
#Retention(RetentionPolicy.RUNTIME)
public #interface BehindSomething{
}
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
#Component
public class IsBehindSomethingHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
#Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.getParameterAnnotation(RemoteAddress.class) != null
&& methodParameter.getParameterType().equals(Boolean.class);
}
#Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
final String ipAddress = nativeWebRequest.getHeader("X-FORWARDED-FOR");
if (ipAddress == null) {
ipAddress =(((ServletWebRequest) nativeWebRequest).getRequest()).getRemoteAddr();
}
return ipAddress.equals("something_here");
}
}
#RequestMapping(value = "testOperation", method = RequestMethod.GET)
public Map<String, String> testOperation(#BehindSomething Boolean behindSomething) {
final Map<String, String> model = new LinkedHashMap<String, String>();
if(behindSomething) {
// then load testOperation jsp page
} else {
// otherwise load some error jsp page
}
return model;
}
Also, dependending on how you have setup Spring, you will have to register IsBehindSomethingHandlerMethodArgumentResolver (if you need tips on that, let me know)
Just return respective pages:
if(ipAddress.equals("something_here")) {
return new ModelAndView("testOperation.jsp");
} else {
return new ModelAndView("error.jsp");
}

Categories