How to eliminate a repeat performance of bean in spring boot? - java

Good day to all, there is a problem, my bean is executed twice, and I can not understand why. I'm new to spring boot and I'm afraid it's about misused annotations.
package com.Alfa.controllers;
import com.Alfa.tools.JsonParser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.io.FileNotFoundException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Map;
#SpringBootApplication
#Controller
public class MainController {
private final RankClient rank;
private final GifClient gifClient;
#Autowired
public MainController(RankClient rank, GifClient gifClient) {
this.rank = rank;
this.gifClient = gifClient;
}
#GetMapping("/{currency}")
public String getGif(#PathVariable String currency, Model model) {
JsonParser jsonParser=new JsonParser();
System.out.println(currency);
boolean res = jsonParser.isRankHigherToday(rank.getYesterdayJson(getYesterdayDate(), currency).getBody(), rank.getJson(currency).getBody());
Map gif;
if (res == false) gif = gifClient.getBrokeGif().getBody();
else gif = gifClient.getRichGif().getBody();
gif = (Map) gif.get("data");
gif = (Map) gif.get("images");
gif = (Map) gif.get("downsized_large");
String GifSrc = (String) gif.get("url");
model.addAttribute("src", GifSrc);
return "index";
}
private String getYesterdayDate() {
final Calendar cal = Calendar.getInstance();
cal.add(Calendar.DATE, -1);
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
return dateFormat.format(cal.getTime());
}
}
#FeignClient(name = "RankClient", url = "${feign.client.rank.url}")
interface RankClient {
#RequestMapping(method = RequestMethod.GET, value = "${feign.client.rank.json.latest}"+"${feign.client.rank.token}&base={currency}")
ResponseEntity<Map> getJson(#PathVariable("currency") String currency);
#RequestMapping(method = RequestMethod.GET, value = "${feign.client.rank.json.historical}" +
"{date}" + "${feign.client.rank.json.historical.end}" + "${feign.client.rank.token}&base={currency}")
ResponseEntity<Map> getYesterdayJson(#PathVariable("date") String date, #PathVariable("currency") String currency);
}
#FeignClient(name = "GifClient", url = "${feign.client.gif.url}")
interface GifClient {
#RequestMapping(method = RequestMethod.GET, value = "${feign.client.gif.token}" + "${feign.client.gif.tag.broke}")
ResponseEntity<Map> getBrokeGif();
#RequestMapping(method = RequestMethod.GET, value = "${feign.client.gif.token}" + "${feign.client.gif.tag.rich}")
ResponseEntity<Map> getRichGif();
}
System.out.println(currency); in my case returns two values, the first is what I need, but then returns favicon. ico.
I do not know where favicon.ico comes from and would like to understand what I am doing wrong.

A web browser will make a request to /favicon.ico to retrieve the icon used to represent your web site in tabs, bookmark lists, etc. I suspect that's what's happening here.
You could avoid the problem by changing the URI so that your #GetMapping doesn't match anything beneath /. For example, you could use something like currencies/{currency}.
Alternatively, if you want or need to use /{currency}, you could validate that currency is a known currency code and return a 404 if it is not. Some input validation is generally a good idea, so that change is probably worth making no matter what URI the method is mapped to.

Related

WARNING: Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/json' not supported]

Hi Guys Please advice me on how to resolve this issue
I am trying to consume a rest web service
see the code below
import java.sql.ResultSet;
import java.util.Date;
import java.util.Map;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
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.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.cwg.entrust.entities.InputString;
import com.cwg.entrust.entities.TokenObject;
import com.cwg.entrust.services.MyConnectionProvider;
import com.cwg.entrust.services.TolenDAO;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
import com.mysql.jdbc.Statement;[![enter image description here][3]][3]
#RestController
#RequestMapping("/test")
public class TfaServiceController implements TolenDAO {
java.sql.Connection con = null;
java.sql.PreparedStatement ps = null;
Date date = new Date();
String the_date = date.toString();
#PostMapping(value = { "/validateToken" },
consumes = { MediaType.APPLICATION_JSON_VALUE }
, produces = { MediaType.APPLICATION_JSON_VALUE })
public Boolean getIsValidToken(#RequestBody Map<String, String> json_Input) throws Exception {
String str = json_Input.get("str1") ;
String token = json_Input.get("str2") ;
Boolean result = false;
if (str.equalsIgnoreCase(token)) {
result = true;
}
return result;
}
}
see the payload below
{
"str1": "test one",
"str2": "two test"
}
Both Content-Type and Accept on Postman are set to application/json
But we keep getting below error
WARNING: Resolved
[org.springframework.web.HttpMediaTypeNotSupportedException: Content
type 'application/json' not supported]
Kindly advice me on how to consume this webservice without issues
Thanks all.
Since you are using the #RestController annotation at the class level , you do not have to use the #ResponseBody annotation at the method level to indicate that it is a Rest endpoint and that the response type of the controller method will be a json(by default for Rest in springboot) .Change your controller method to :
#RequestMapping(value = "/validateToken", method = RequestMethod.POST)
public Boolean getIsValidToken(#RequestBody Map<String, String> json_Input) throws Exception {
String str = json_Input.get("str1") ;
String token = json_Input.get("str2") ;
Boolean result = false;
if (str.equalsIgnoreCase(token)) {
result = true;
}
return result;
}
Also instead of the #RequestMapping(value = "/validateToken", method = RequestMethod.POST) you could use the #PostMapping("/validateToken") annotation if your springboot version supports it .In addition to that you could specify the type of data that the endpoint expects or produces using like :
#PostMapping(value = { "/validateToken" }, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE )
public Boolean getIsValidToken(#RequestBody Map<String, String> json_Input) throws Exception {
String str = json_Input.get("str1") ;
String token = json_Input.get("str2") ;
Boolean result = false;
if (str.equalsIgnoreCase(token)) {
result = true;
}
return result;
}
Note : The consumes/produces can also be used with #RequestMapping.
This issue happened to me too. It worked when I introduced the type String before the property name (json_Input in your case) and don't when I tried with my custom type.
At the end it was that I was referencing with the types of the properties instead of String type(as I am using mongodb).
So, Instead of
#DBRef
private CustomType customProperty
use:
#DBRef
private String customProperty
Hope it helps!

Pretty JSON import when filtering but not when returning whole lot + ugly brackets in ID

I'm trying to achieve these 2 things:
Method getData() to return nicely formed JSON like getById() & getBetween return already.
How to get rid of those ugly brackets (original csv file I'm reading from comes with them) around ID so I could return UUID for Id, rather than a String as I currently do.
Here's the code:
import java.io.InputStreamReader;
import java.time.LocalDate;
import java.util.List;
import java.util.stream.Collectors;
import com.opencsv.bean.CsvToBean;
import com.opencsv.bean.CsvToBeanBuilder;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.foobar.hotovo.Domain.PricePaid;
import com.foobar.hotovo.Exceptions.PriceNotFoundException;
#Service
public class MainService {
private static final String URL = "http://prod.publicdata.landregistry.gov.uk.s3-website-eu-west-1.amazonaws.com/pp-monthly-update-new-version.csv";
private List<PricePaid> getData() {
RestTemplate restTemplate = new RestTemplate();
return restTemplate.execute(URL, HttpMethod.GET, null, clientHttpResponse -> {
InputStreamReader reader = new InputStreamReader(clientHttpResponse.getBody());
CsvToBean<PricePaid> csvToBean = new CsvToBeanBuilder<PricePaid>(reader)
.withType(PricePaid.class)
.withSeparator(',')
.withIgnoreLeadingWhiteSpace(true)
.build();
return csvToBean.stream().collect(Collectors.toList());
});
}
private boolean isBetween(PricePaid pricePaid, LocalDate from, LocalDate to) {
LocalDate date = pricePaid.getDateOfTransfer();
return date.isAfter(from) && date.isBefore(to);
}
public List<PricePaid> getAll() {
return getData();
}
public PricePaid getById(String id) throws PriceNotFoundException {
return getData().stream()
.filter(pricePaid -> pricePaid.getId().equals(id))
.findFirst()
.orElseThrow(() -> new PriceNotFoundException("Item not found!"));
}
public List<PricePaid> getBetween(LocalDate from, LocalDate to) {
return getData().stream()
.filter(pricePaid -> isBetween(pricePaid, from, to))
.collect(Collectors.toList());
}
}
Here's an example of the output from getData():
[{"id":"{9DBAD221-7F8E-6EB3-E053-6B04A8C0F257}","price":96000,"dateOfTransfer":"2002-05-31","postCode":"SA62 3JW","propertyType":"F","oldNew":"Y","duration":"L","paon":"THE COACH HOUSE, 29","saon":"FLAT 5","street":"ENFIELD ROAD","locality":"BROAD HAVEN","city":"HAVERFORDWEST","district":"PEMBROKESHIRE","county":"PEMBROKESHIRE","ppd":"A","recordStatus":"A"},{"id":"{9DBAD221-8683-6EB3-E053-6B04A8C0F257}","price":59500,"dateOfTransfer":"2002-12-05","postCode":"EX31 2BS","propertyType":"F","oldNew":"N","duration":"L","paon":"16","saon":"FLAT 3","street":"STICKLEPATH HILL","locality":"STICKLEPATH","city":"BARNSTAPLE","district":"NORTH DEVON","county":"DEVON","ppd":"A","recordStatus":"A"},{"id":"{9DBAD221-B238-6EB3-E053-6B04A8C0F257}","price":240000,"dateOfTransfer":"2002-02-15","postCode":"GL7 5BL","propertyType":"S","oldNew":"N","duration":"F","paon":"76","saon":"","street":"CHURCH ROAD","locality":"QUENINGTON","city":"CIRENCESTER","district":"COTSWOLD","county":"GLOUCESTERSHIRE","ppd":"A","recordStatus":"A"},{"id":"{9DBAD221-CBFB-6EB3-E053-6B04A8C0F257}","price":292500,"dateOfTransfer":"2002-09-27","postCode":"WR11 8QH","propertyType":"T","oldNew":"N","duration":"F","paon":"BIG BARN","saon":"","street":"","locality":"ULLINGTON","city":"EVESHAM","district":"WYCHAVON","county":"WORCESTERSHIRE","ppd":"A","recordStatus":"A"},{"id":"{9DBAD221-E1D3-6EB3-E053-6B04A8C0F257}","price":145000,"dateOfTransfer":"2002-01-25","postCode":"PE12 8SN","propertyType":"D","oldNew":"N","duration":"F","paon":"SILVERCROFT","saon":"","street":"RAVENS DROVE","locality":"HOLBEACH FEN","city":"SPALDING","district":"SOUTH HOLLAND","county":"LINCOLNSHIRE","ppd":"A","recordStatus":"A"},{"id":"{9DBAD222-5429-6EB3-E053-6B04A8C0F257}","price":79950,"dateOfTransfer":"2002-07-17","postCode":"NE29 6XJ","propertyType":"S","oldNew":"N","duration":"F","paon":"54","saon":"","street":"BLUCHER ROAD","locality":"","city":"NORTH SHIELDS","district":"NORTH TYNESIDE","county":"TYNE AND WEAR","ppd":"A","recordStatus":"A"},{"id":"{9DBAD222-5451-6EB3-E053-6B04A8C0F257}","price":65000,"dateOfTransfer":"2002-11-13","postCode":"NE6 5XY","propertyType":"F","oldNew":"N","duration":"L","paon":"71","saon":"","street":"KING JOHN TERRACE","locality":"","city":"NEWCASTLE UPON TYNE","district":"NEWCASTLE UPON TYNE","county":"TYNE AND WEAR","ppd":"A","recordStatus":"A"},{"id":"{9DBAD222-5F1E-6EB3-E053-6B04A8C0F257}","price":17000,"dateOfTransfer":"2002-07-01","postCode":"SY23 5NJ","propertyType":"D","oldNew":"N","duration":"F","paon":"TYNEWYDD","saon":"","street":"","locality":"BETHANIA","city":"LLANON","district":"CEREDIGION","county":"CEREDIGION","ppd":"A","recordStatus":"A"},{"id":"{9DBAD222-7BB6-6EB3-E053-6B04A8C0F257}","price":33000,"dateOfTransfer":"2002-01-31","postCode":"HD3 4QJ","propertyType":"T","oldNew":"N","duration":"L","paon":"26 - 28","saon":"","street":"SCAR LANE","locality":"","city":"HUDDERSFIELD","district":"KIRKLEES","county":"WEST YORKSHIRE","ppd":"A","recordStatus":"A"},{"id":"{9DBAD221-5212-6EB3-E053-6B04A8C0F257}","price":127000,"dateOfTransfer":"2002-11-28","postCode":"BS6 5QZ","propertyType":"T","oldNew":"N","duration":"F","paon":"200","saon":"","street":"CHELTENHAM ROAD","locality":"","city":"BRISTOL","district":"CITY OF BRISTOL","county":"CITY OF BRISTOL","ppd":"A","recordStatus":"A"},{"id":"{9DBAD221-65C4-6EB3-E053-6B04A8C0F257}","price":105000,"dateOfTransfer":"2002-11-01","postCode":"PE19 7BH","propertyType":"D","oldNew":"Y","duration":"F","paon":"287A","saon":"","street":"GREAT NORTH ROAD","locality":"EATON FORD","city":"ST NEOTS","district":"HUNTINGDONSHIRE","county":"CAMBRIDGESHIRE","ppd":"A","recordStatus":"A"},{"id":"{9DBAD221-79A7-6EB3-E053-6B04A8C0F257}","price":365000,"dateOfTransfer":"2002-05-31","postCode":"LA23 2HB","propertyType":"D","oldNew":"N","duration":"F","paon":"30","saon":"","street":"CRAIG WALK","locality":"","city":"WINDERMERE","district":"SOUTH LAKELAND","county":"CUMBRIA","ppd":"A","recordStatus":"A"},{"id":"{9DBAD221-8270-6EB3-E053-6B04A8C0F257}","price":58000,"dateOfTransfer":"2002-05-13","postCode":"SA62 3JW","propertyType":"F","oldNew":"Y","duration":"L","paon":"THE COACH HOUSE, 29","saon":"FLAT 3","street":"ENFIELD ROAD","locality":"BROAD HAVEN","city":"HAVERFORDWEST","district":"PEMBROKESHIRE","county":"PEMBROKESHIRE","ppd":"A","recordStatus":"A"},{"id":"{9DBAD221-9E52-6EB3-E053-6B04A8C0F257}","price":173000,"dateOfTransfer":"2002-09-16","postCode":"BN27 4BP","propertyType":"D","oldNew":"N","duration":"F","paon":"SUNNYSIDE","saon":"","street":"HACKHURST LANE","locality":"LOWER DICKER","city":"HAILSHAM","district":"WEALDEN","county":"EAST SUSSEX","ppd":"A","recordStatus":"A"},{"id":"{9DBAD221-A6F1-6EB3-E053-6B04A8C0F257}","price":110200,"dateOfTransfer":"2002-02-28","postCode":"RM16 6LW","propertyType":"F","oldNew":"Y","duration":"L","paon":"5","saon":"","street":"SAN MARCOS DRIVE","locality":"CHAFFORD HUNDRED","city":"GRAYS","district":"THURROCK","county":"THURROCK","ppd":"A","recordStatus":"A"},{"id":"{9DBAD221-B31F-6EB3-E053-6B04A8C0F257}","price":475000,"dateOfTransfer":"2002-03-28","postCode":"GL50 4LB","propertyType":"D","oldNew":"Y","duration":"F","paon":"PARK WAY","saon":"","street":"WEST DRIVE","locality":"","city":"CHELTENHAM","district":"CHELTENHAM","county":"GLOUCESTERS
You could use a library like Gson or Jackson to pretty print the json string:
Gson method
Jackson method

Updating specific part of value in hash map dynamically

I have a spring boot app with a HTTP post request handler. It accepts a payload that I parse and outputs a JSON. I have handled it that it needs to accept a payload of certain parameters(18).
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
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 com.google.gson.Gson;
#Validated
#RestController
public class MockController {
#Autowired
MockConfig mockconfig;
private static final Logger LOGGER = LoggerFactory.getLogger(MockController.class);
#RequestMapping(value = "/", method = RequestMethod.GET)
public String index() {
return "hello!";
}
String[] parse;
#PostMapping(value = "/")
public String payloader(#RequestBody String params ) throws IOException{
LOGGER.debug("code is hitting");
parse = params.split("\\|");
String key;
String value;
String dyn;
Map<String, String> predictionFeatureMap = mockconfig.getPredictionFeatureMap();
if(parse.length!=18) {
key = "Not_enough_parameters";
value = predictionFeatureMap.get(key);
Map<?, ?> resultJsonObj = new Gson().fromJson(value, Map.class);
}
else {
key = params;
value = predictionFeatureMap.get(key);
}
return value;
}
}
My config class is where I get the input and output from a file and put them into a hashmap.
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import org.springframework.context.annotation.Configuration;
#Configuration
public class MockConfig {
private Map<String, String> predictionFeatureMap = new HashMap<String, String>();
public Map<String,String> getPredictionFeatureMap() throws IOException {
return predictionFeatureMap;
}
public MockConfig() throws IOException {
init();
}
private Map<String, String> init() throws IOException {
Scanner sc = new Scanner (new File("src/test/resources/Payload1.txt"));
int counter = 1;
String key = "";
while (sc.hasNextLine()) {
if(counter % 2 != 0) {
key = sc.nextLine();
}else {
predictionFeatureMap.put(key, sc.nextLine());
}
counter++;
}
sc.close();
return predictionFeatureMap;
}
}
This is the key and value in the file that I'm trying to work with specifically.
Not_enough_parameters
{"status": false, "errorMessage": "Payload has incorrect amount of parts: expecting: 18, actual:8", "version": "0.97", "coreName": "Patient_Responsibility"}
(The JSON string is the response to too much or too little parameters... the paramter length should be 18.)
Example input:
ncs|56-2629193|1972-03-28|20190218|77067|6208|3209440|self|-123|-123|-123|0.0|0.0|0.0|0.0|0.0|0.0|0.0
This input would pass because it has 18 parameters...
What I want to do is if a user curls for example 5 parameters
ncs|56-2629193|1972-03-28|20190218|77067
I want the value(JSON error message) to have the 'actual' field updated like:
{"status": false, "errorMessage": "Payload has incorrect amount of parts: expecting: 18, actual:5", "version": "0.97", "coreName": "Patient_Responsibility"}
without hardcoding it into the txt file or hashmap...
I have tried getting the index of the string and replacing the '8' character with parse.length() and casting it as a char but it just gives me this output:
{"status": false, "errorMessage": "Payload has incorrect amount of parts: expecting:1 actual:", "version": "0.97", "coreName": "Nulogix_Patient_Responsibility"}
How do I parse or index the JSON to update this value? Or is there a hashmap method to deal with this?
When working with a framework, you usually handle errors using the frameworks way of handling errors.
To handle errors in spring boot you typically use a controller advice that will assist in handling errors. This is created by annotating a class with #ControllerAdvice.
There you can catch thrown exceptions and build responses that will be returned to the calling client.
#PostMapping(value = "/")
public String payloader(#RequestBody String params ) throws IOException{
LOGGER.debug("code is hitting");
parse = params.split("\\|");
String key;
String value;
String dyn;
Map<String, String> predictionFeatureMap = mockconfig.getPredictionFeatureMap();
if(parse.length!=18) {
// Here you throw a custom runtime exception and pass what
// parameters you want that will help you build your error
// message you are passing to your client.
final String errorMessage = String.format(
"Payload has incorrect amount of parts: expecting:%d actual:%d",
predictionFeatureMap.size(),
parse.length);
throw new MyException(errorMessage);
}
else {
key = params;
value = predictionFeatureMap.get(key);
}
return value;
}
Then in a controller advice class
#ControllerAdvice
public class Foo extends ResponseEntityExceptionHandler {
#ExceptionHandler(MyException.class)
public ResponseEntity<MyCustomErrorBody> handleControllerException(HttpServletRequest request, MyException ex) {
// Build your error response here and return it.
// Create a class that will represent the json error body
// and pass it as body and jackson will deserialize it for
// you into json automatically.
final MyCustomErrorBody body = new MyCustomErrorBody(false, ex.getMessage(), "0.97", "Patient_Responsibility")
return ResponseEntity.unprocessableEntity().body(myCustomErrorBody).build();
}
}
public class MyCustomErrorBody {
private boolean status;
private String errorMessage;
private String version;
private String coreName;
// constructor and getters setters ommitted
}
Links about spring boot error handling:
Official spring boot documentation
Baeldung exception-handling-for-rest-with-spring

Bitbucket Api with ssh access key as header to get total number of pull requests in java

I want to make a rest call to bitbucket api with ssh private key as header.For example the url is (http://bitbucket.com/rest/api/1.0/repos/testProject/pull-requests?state=OPEN).
Is there a way call this url with spring rest template and how to pass ssl access key as header.
Instead of using SSH keys use Personal Access Tokens:
https://confluence.atlassian.com/bitbucketserver/personal-access-tokens-939515499.html
(Introduced in Bitbucket 5.5)
Then you could use code like this:
package com.company.bitbucket.tools.application;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.stream.Collectors;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;
import com.company.bitbucket.tools.HttpRequestInterceptor;
import com.company.bitbucket.tools.ProjectValue;
import com.company.bitbucket.tools.Projects;
import com.company.bitbucket.tools.UserValue;
import com.company.bitbucket.tools.Users;
#Controller
public class ProjectController {
public static String BITBUCKET_URL = "https://bitbucket.company.com/rest/api/latest/";
public static String PROJECTS = "projects";
public static String PERMISSIONS = "permissions/users?permission=PROJECT_ADMIN";
public static String PAT = "<put your generated token in here>";
#RequestMapping(value={"/projects"}, method = RequestMethod.GET)
public ModelAndView listProjects(){
HashMap<String, String> list = getAdmins();
ModelAndView model = new ModelAndView("projects");
model.addObject("adminMap", list);
return model;
}
private HashMap<String, String> getAdmins(){
HashMap<String, String> projectMap = new HashMap<>();
RestTemplate restTemplate = new RestTemplate();
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>();
interceptors.add(new HttpRequestInterceptor("Authorization", "Bearer ".concat(PAT)));
restTemplate.setInterceptors(interceptors);
Projects projects = restTemplate.getForObject(BITBUCKET_URL.concat("projects?limit=100"), Projects.class);
for(ProjectValue projectValue: projects.getValues()) {
String projectUrl = String.format("%s/%s/%s/%s", BITBUCKET_URL, PROJECTS, projectValue.getKey(), PERMISSIONS);
Users users = restTemplate.getForObject(projectUrl, Users.class);
List<String> names = new ArrayList<>();
for (UserValue value: users.getValues()) {
names.add(value.getUser().getDisplayName());
}
String commaSeparatedNames = String.join(", ", names);
projectMap.put(projectValue.getName(), commaSeparatedNames);
}
return projectMap;
}
}
This code gets a list of project admins using the rest api, but you could change to make whatever rest request you wish.

j2ee spring mvc best practice for small application

I am working with small app that uses spring-hibernate but I am a newcomer to field of spring MVC, I have some questions:
1) using single controller for multiple pages is good practice or should I create separate cont. class for each page.
2) I don't want to use form tag of spring I'm using html forms.
My controller is as follows:
package com.servlets.controllers;
import com.utils.generalUtils;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
#Controller
public class signin{
#RequestMapping(value = "/login", method={RequestMethod.POST,RequestMethod.GET})
public ModelAndView loginForm(HttpServletRequest req,HttpServletResponse response){
HashMap<String,String> lsMsg = new HashMap<String,String>();
lsMsg = generalUtils.getInstance().LoginCheck(req);
for (Map.Entry<String, String> entry : lsMsg.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
System.out.println(" key -- "+key+" value -- "+value);
}
if((lsMsg.get("Authorized")).equals("true")){
return new ModelAndView("landing", "message", lsMsg);
}
return new ModelAndView("login", "message", lsMsg);
}
#RequestMapping(value = "/fergot", method={RequestMethod.POST,RequestMethod.GET})
public ModelAndView fergotForm(HttpServletRequest req) { // Not implemented yet
HashMap<String,String> lsMsg = new HashMap<String,String>();
return new ModelAndView("fergot", "message", lsMsg);
}
#RequestMapping("/register")
public ModelAndView registerForm(HttpServletRequest req,HttpServletResponse response) throws IOException{
HashMap<String,String> lsMsgs = new HashMap<String,String>();
lsMsgs.put("Authorized", "false");
lsMsgs = generalUtils.getInstance().addUser(req);
if((lsMsgs.get("Authorized")).equals("true")){
response.sendRedirect("login.html");
}
return new ModelAndView("register", "message", lsMsgs);
}
}
1) Both way are ok. But you want best practise, so my suggestion is create separate controller class for each page . This is common choice in most cases. On the other hand, if your app is very very small, even if you using single controller is also not a big problem.
Chose which way's core problem is which way can maintain easier in the future and which way is more readable for others.
2) You say you don't want to use spring form tag, ofcourse you can. Take it easy, You can not use any part of spring you don't want to use, it is ok.

Categories