Refactor spaghetti code I wrote + save source code in file system instead than in db

This commit is contained in:
Francois G 2023-02-25 19:40:16 +01:00
parent 64a88f7282
commit 4b5d21345c
6 changed files with 287 additions and 162 deletions

View file

@ -0,0 +1,62 @@
package be.jeffcheasey88.peeratcode.model;
public class Completion {
private int puzzleId;
private int playerId;
private int tries;
private String fileName;
private byte[] code;
private int score;
public Completion(int playerId, int puzzleId, String fileName, int score) {
this(playerId, puzzleId, -1, 1, fileName, score, null);
}
public Completion(int playerId, int puzzleId, int idCompletion, int tries, String fileName, int score) {
this(playerId, puzzleId, idCompletion, tries, fileName, score, null);
}
public Completion(int playerId, int puzzleId, int idCompletion, int tries, String fileName, int score,
byte[] file) {
this.playerId = playerId;
this.puzzleId = puzzleId;
this.tries = tries;
this.fileName = fileName;
this.score = score;
this.code = file;
}
public int getPuzzleId() {
return puzzleId;
}
public int getPlayerId() {
return playerId;
}
public int getTries() {
return tries;
}
public void addTry() {
this.tries++;
updateScore();
}
private void updateScore() {
if (tries > 1) {
score = score * (1-((tries-1)/10));
}
}
public String getFileName() {
return fileName;
}
public byte[] getCode() {
return code;
}
public int getScore() {
return score;
}
}

View file

@ -1,15 +1,16 @@
package be.jeffcheasey88.peeratcode.model; package be.jeffcheasey88.peeratcode.model;
public class Player { public class Player {
public static final String PATH_TO_CODE = "/home/%s/peer-at-source/";
private String pseudo; private String pseudo;
private String email; private String email;
private String firstname; private String firstname;
private String lastname; private String lastname;
private String description; private String description;
private String sgroup; private String sgroup;
public Player(String pseudo, String email, String firstname, String lastname, String description, String sgroup){ public Player(String pseudo, String email, String firstname, String lastname, String description, String sgroup) {
this.pseudo = pseudo; this.pseudo = pseudo;
this.email = email; this.email = email;
this.firstname = firstname; this.firstname = firstname;
@ -17,29 +18,32 @@ public class Player {
this.description = description; this.description = description;
this.sgroup = sgroup; this.sgroup = sgroup;
} }
public String getPseudo(){ public String getPseudo() {
return this.pseudo; return this.pseudo;
} }
public String getEmail(){ public String getEmail() {
return this.email; return this.email;
} }
public String getFirstname(){ public String getFirstname() {
return this.firstname; return this.firstname;
} }
public String getLastname(){ public String getLastname() {
return this.lastname; return this.lastname;
} }
public String getDescription(){ public String getDescription() {
return this.description; return this.description;
} }
public String getGroup(){ public String getGroup() {
return this.sgroup; return this.sgroup;
} }
public String getPathToSourceCode() {
return String.format(PATH_TO_CODE, pseudo);
}
} }

View file

@ -58,7 +58,7 @@ public class Puzzle {
this.verify = regex; this.verify = regex;
} }
private int getScoreMax(){ public int getScoreMax(){
return this.scoreMax; return this.scoreMax;
} }

View file

@ -14,6 +14,8 @@ import com.password4j.Password;
import be.jeffcheasey88.peeratcode.Configuration; import be.jeffcheasey88.peeratcode.Configuration;
import be.jeffcheasey88.peeratcode.model.Chapter; import be.jeffcheasey88.peeratcode.model.Chapter;
import be.jeffcheasey88.peeratcode.model.Completion;
import be.jeffcheasey88.peeratcode.model.Player;
import be.jeffcheasey88.peeratcode.model.Puzzle; import be.jeffcheasey88.peeratcode.model.Puzzle;
public class DatabaseRepository { public class DatabaseRepository {
@ -26,34 +28,47 @@ public class DatabaseRepository {
private static final String REGISTER_QUERY = "INSERT INTO players (pseudo, email, passwd, firstname, lastname, description, sgroup, avatar) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; private static final String REGISTER_QUERY = "INSERT INTO players (pseudo, email, passwd, firstname, lastname, description, sgroup, avatar) VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
private static final String CHECK_PASSWORD = "SELECT id_player, passwd FROM players WHERE pseudo=?"; private static final String CHECK_PASSWORD = "SELECT id_player, passwd FROM players WHERE pseudo=?";
private static final String SCORE = "SELECT score FROM completions WHERE fk_player = ? AND fk_puzzle = ?"; private static final String SCORE = "SELECT score FROM completions WHERE fk_player = ? AND fk_puzzle = ?";
private static final String GET_PUZZLE_SOLUTION = "SELECT soluce FROM puzzles WHERE id_puzzle=?"; private static final String GET_COMPLETION = "SELECT id_completion, tries, fileName, score FROM completions WHERE fk_puzzle = ? AND fk_player = ?";
private static final String GET_PUZZLE_SCORE_MAX = "SELECT score_max FROM puzzles WHERE id_puzzle=?"; private static final String GET_PLAYER = "SELECT * FROM players WHERE id_player = ?";
private static final String GET_PLAYER_ID_BY_PSEUDO = "SELECT id_player FROM players WHERE pseudo=?";
private static final String GET_PUZZLE_NB_TRIES_AND_SCORE_BY_PLAYER = "SELECT tries, score FROM completions WHERE fk_puzzle = ? AND fk_player = ?";
private static final String INSERT_COMPLETION = "INSERT INTO completions (fk_puzzle, fk_player, tries, code, fileName, score) values (?, ?, ?, ?, ?, ?)"; private static final String INSERT_COMPLETION = "INSERT INTO completions (fk_puzzle, fk_player, tries, code, fileName, score) values (?, ?, ?, ?, ?, ?)";
private static final String UPDATE_COMPLETION = "UPDATE completions SET tries = ?, code = ?, filename = ?, score = ?"; private static final String UPDATE_COMPLETION = "UPDATE completions SET tries = ?, filename = ?, score = ? WHERE fk_puzzle = ? AND fk_player = ?";
private Connection con; private Connection con;
private Configuration config; private Configuration config;
public DatabaseRepository(Configuration config){ public DatabaseRepository(Configuration config) {
this.config = config; this.config = config;
} }
private void ensureConnection() throws SQLException{ private void ensureConnection() throws SQLException {
if(con == null || (!con.isValid(5))){ if (con == null || (!con.isValid(5))) {
this.con = DriverManager.getConnection("jdbc:mysql://"+config.getDbHost()+":"+config.getDbPort()+"/"+config.getDbDatabase()+"",config.getDbUser(), config.getDbPassword()); this.con = DriverManager.getConnection(
"jdbc:mysql://" + config.getDbHost() + ":" + config.getDbPort() + "/" + config.getDbDatabase() + "",
config.getDbUser(), config.getDbPassword());
} }
} }
private Puzzle makePuzzle(ResultSet puzzleResult) throws SQLException { private Puzzle makePuzzle(ResultSet puzzleResult) throws SQLException {
return new Puzzle(puzzleResult.getInt("id_puzzle"), puzzleResult.getString("name"), puzzleResult.getString("content"), null,"",0); return new Puzzle(puzzleResult.getInt("id_puzzle"), puzzleResult.getString("name"),
puzzleResult.getString("content"), null, "", 0);
} }
private Chapter makeChapter(ResultSet chapterResult) throws SQLException { private Chapter makeChapter(ResultSet chapterResult) throws SQLException {
return new Chapter(chapterResult.getInt("id_chapter"), chapterResult.getString("name")); return new Chapter(chapterResult.getInt("id_chapter"), chapterResult.getString("name"));
} }
private Completion makeCompletion(int playerId, int puzzleId, ResultSet completionResult) throws SQLException {
return new Completion(playerId, puzzleId, completionResult.getInt("id_completion"),
completionResult.getInt("tries"), completionResult.getString("fileName"),
completionResult.getInt("score"), null);
}
private Player makePlayer(ResultSet playerResult) throws SQLException {
return new Player(playerResult.getString("pseudo"), playerResult.getString("email"),
playerResult.getString("firstName"), playerResult.getString("LastName"),
playerResult.getString("description"), playerResult.getString("sgroup"));
}
private List<Puzzle> getPuzzlesInChapter(int id) throws SQLException { private List<Puzzle> getPuzzlesInChapter(int id) throws SQLException {
List<Puzzle> puzzles = new ArrayList<>(); List<Puzzle> puzzles = new ArrayList<>();
ensureConnection(); ensureConnection();
@ -86,21 +101,52 @@ public class DatabaseRepository {
} }
return null; return null;
} }
public int getScore(int user, int puzzle){ public int getScore(int user, int puzzle) {
try { try {
ensureConnection();
PreparedStatement stmt = this.con.prepareStatement(SCORE); PreparedStatement stmt = this.con.prepareStatement(SCORE);
stmt.setInt(1, user); stmt.setInt(1, user);
stmt.setInt(2, puzzle); stmt.setInt(2, puzzle);
ResultSet result = stmt.executeQuery(); ResultSet result = stmt.executeQuery();
if(result.next()) result.getInt("score"); if (result.next())
}catch(Exception e){ result.getInt("score");
} catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
return -1; return -1;
} }
public Completion getCompletion(int playerId, int puzzleId) {
try {
PreparedStatement completionsStmt = con.prepareStatement(GET_COMPLETION);
completionsStmt.setInt(1, puzzleId);
completionsStmt.setInt(2, playerId);
ResultSet result = completionsStmt.executeQuery();
if (result.next()) {
return makeCompletion(playerId, puzzleId, result);
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public Player getPlayer(int idPlayer) {
try {
PreparedStatement completionsStmt = con.prepareStatement(GET_PLAYER);
completionsStmt.setInt(1, idPlayer);
ResultSet result = completionsStmt.executeQuery();
if (result.next()) {
return makePlayer(result);
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/** /**
* Get a specific chapter * Get a specific chapter
* *
@ -190,11 +236,12 @@ public class DatabaseRepository {
* @param firstname The firstname of the user * @param firstname The firstname of the user
* @param lastname The lastname of the user * @param lastname The lastname of the user
* @param description The description of the user * @param description The description of the user
* @param sgroup The group of the user * @param sgroup The group of the user
* @param avatar The avatar of the user * @param avatar The avatar of the user
* @return True if the user was registered, false if an error occurred * @return True if the user was registered, false if an error occurred
*/ */
public int register(String pseudo, String email, String password, String firstname, String lastname, String description, String sgroup, String avatar) { public int register(String pseudo, String email, String password, String firstname, String lastname,
String description, String sgroup, String avatar) {
Hash hash = Password.hash(password).withArgon2(); Hash hash = Password.hash(password).withArgon2();
try { try {
ensureConnection(); ensureConnection();
@ -207,9 +254,10 @@ public class DatabaseRepository {
statement.setString(6, description); statement.setString(6, description);
statement.setString(7, sgroup); statement.setString(7, sgroup);
statement.setString(8, avatar); statement.setString(8, avatar);
if(statement.executeUpdate() == 1){ if (statement.executeUpdate() == 1) {
ResultSet inserted = statement.getGeneratedKeys(); ResultSet inserted = statement.getGeneratedKeys();
if(inserted.next()) return inserted.getInt("id_player"); if (inserted.next())
return inserted.getInt("id_player");
} }
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
@ -220,7 +268,7 @@ public class DatabaseRepository {
/** /**
* Login a user * Login a user
* *
* @param username The username of the user * @param username The username of the user
* @param password The password of the user * @param password The password of the user
* @return id the id of the user, -1 if not login successefuly * @return id the id of the user, -1 if not login successefuly
*/ */
@ -232,97 +280,51 @@ public class DatabaseRepository {
ResultSet result = statement.executeQuery(); ResultSet result = statement.executeQuery();
if (result.next()) { if (result.next()) {
String hashedPassword = result.getString("passwd"); String hashedPassword = result.getString("passwd");
if(Password.check(password, hashedPassword).withArgon2()) return result.getInt("id_player"); if (Password.check(password, hashedPassword).withArgon2())
return result.getInt("id_player");
} }
} catch (SQLException e) { } catch (SQLException e) {
} }
return -1; return -1;
} }
public byte[] getPuzzleSolution(int puzzleId) { public Completion insertOrUpdatePuzzleResponse(int puzzleId, int userId, String fileName, byte[] code) {
try { try {
PreparedStatement puzzleStmt = con.prepareStatement(GET_PUZZLE_SOLUTION); Puzzle currentPuzzle = getPuzzle(puzzleId);
puzzleStmt.setInt(1, puzzleId); Completion completion = getCompletion(userId, puzzleId);
ResultSet result = puzzleStmt.executeQuery(); if (completion == null) {
if (result.next()) { insertCompletion(new Completion(userId, puzzleId, fileName, currentPuzzle.getScoreMax()));
return result.getBytes("soluce");
}
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public int insertOrUpdatePuzzleResponse(int puzzleId, String pseudo, String fileName, byte[] code) {
try {
ensureConnection();
int[] triesAndScore = getPuzzleNbTriesAndScore(puzzleId, pseudo);
int playerId = getPlayerIdByPseudo(pseudo);
int puzzleScoreMax = getPuzzleScoreMax(puzzleId);
if (triesAndScore[0] < 0) {
// Insert completions
PreparedStatement statement = con.prepareStatement(INSERT_COMPLETION);
statement.setInt(1, puzzleId);
statement.setInt(2, playerId);
statement.setInt(3, 0);
statement.setBytes(4, code);
statement.setString(5, fileName);
statement.setInt(6, puzzleScoreMax);
return puzzleScoreMax;
} else { } else {
// Update completions completion.addTry();
int score = puzzleScoreMax * (((triesAndScore[0]-1)*10)/100); updateCompletion(completion);
PreparedStatement statement = con.prepareStatement(UPDATE_COMPLETION);
statement.setInt(1, triesAndScore[0]+1);
statement.setBytes(2, code);
statement.setString(3, fileName);
statement.setInt(4, score);
return score;
}
} catch (SQLException e) {
e.printStackTrace();
}
return -1;
}
public int getPuzzleScoreMax(int puzzleId) {
try {
PreparedStatement puzzleStmt = con.prepareStatement(GET_PUZZLE_SCORE_MAX);
puzzleStmt.setInt(1, puzzleId);
ResultSet result = puzzleStmt.executeQuery();
if (result.next()) {
return result.getInt("score_max");
}
} catch (SQLException e) {
e.printStackTrace();
}
return -1;
}
public int[] getPuzzleNbTriesAndScore(int puzzleId, String pseudo) {
try {
PreparedStatement puzzleStmt = con.prepareStatement(GET_PUZZLE_NB_TRIES_AND_SCORE_BY_PLAYER);
puzzleStmt.setInt(1, puzzleId);
ResultSet result = puzzleStmt.executeQuery();
int[] res = new int[2];
if (result.next()) {
res[0] = result.getInt("tries");
res[1] = result.getInt("score");
} }
return completion;
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
return null; return null;
} }
private int getPlayerIdByPseudo(String pseudo) {
try { private void insertCompletion(Completion newCompletion) throws SQLException {
PreparedStatement puzzleStmt = con.prepareStatement(GET_PLAYER_ID_BY_PSEUDO); // Insert completions
puzzleStmt.setString(1, pseudo); PreparedStatement statement = con.prepareStatement(INSERT_COMPLETION);
ResultSet result = puzzleStmt.executeQuery(); statement.setInt(1, newCompletion.getPuzzleId());
if (result.next()) { statement.setInt(2, newCompletion.getPlayerId());
return result.getInt("id_player"); statement.setInt(3, newCompletion.getTries());
} statement.setBytes(4, newCompletion.getCode());
} catch (SQLException e) { statement.setString(5, newCompletion.getFileName());
e.printStackTrace(); statement.setInt(6, newCompletion.getScore());
} statement.executeUpdate();
return -1; }
private void updateCompletion(Completion completionToUpdate) throws SQLException {
// Update completions
PreparedStatement statement = con.prepareStatement(UPDATE_COMPLETION);
statement.setInt(1, completionToUpdate.getTries());
statement.setString(2, completionToUpdate.getFileName());
statement.setInt(3, completionToUpdate.getScore());
statement.setInt(4, completionToUpdate.getPuzzleId());
statement.setInt(5, completionToUpdate.getPlayerId());
statement.executeUpdate();
} }
} }

View file

@ -1,11 +1,17 @@
package be.jeffcheasey88.peeratcode.routes; package be.jeffcheasey88.peeratcode.routes;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays; import java.util.Arrays;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import be.jeffcheasey88.peeratcode.model.Completion;
import be.jeffcheasey88.peeratcode.model.Player;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository; import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
import be.jeffcheasey88.peeratcode.webserver.HttpReader; import be.jeffcheasey88.peeratcode.webserver.HttpReader;
import be.jeffcheasey88.peeratcode.webserver.HttpUtil; import be.jeffcheasey88.peeratcode.webserver.HttpUtil;
@ -22,54 +28,39 @@ public class PuzzleResponse implements Response {
@Override @Override
public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception { public void exec(Matcher matcher, User user, HttpReader reader, HttpWriter writer) throws Exception {
if(user == null){ if (user == null) {
HttpUtil.responseHeaders(writer, 403, "Access-Control-Allow-Origin: *"); HttpUtil.responseHeaders(writer, 403, "Access-Control-Allow-Origin: *");
return; return;
} }
HttpUtil.skipHeaders(reader); HttpUtil.skipHeaders(reader);
int puzzleId = Integer.parseInt(matcher.group(1));
byte[] response;
byte[] fileName;
byte[] sourceCode;
// Response ReceivedResponse received = new ReceivedResponse(matcher, reader);
int hSize = reader.readInt(); saveSourceCode(received, databaseRepo.getPlayer(user.getId()));
response = new byte[hSize];
if (hSize == reader.read(response)) {
// File Name
hSize = reader.readInt();
fileName = new byte[hSize];
if (hSize == reader.read(fileName)) {
// Source Code
hSize = reader.readInt();
sourceCode = new byte[hSize];
if (hSize == reader.read(sourceCode)) {
int score = databaseRepo.insertOrUpdatePuzzleResponse(puzzleId, "Pseudo", fileName.toString(), sourceCode);
if (Arrays.equals(response, databaseRepo.getPuzzleSolution(puzzleId))) {
HttpUtil.responseHeaders(writer, 200,
"Access-Control-Allow-Origin: *",
"Content-Type: application/json");
JSONObject responseJSON = new JSONObject();
responseJSON.put("id", puzzleId);
responseJSON.put("score", score);
writer.write(responseJSON.toJSONString());
writer.flush();
writer.close();
} else {
HttpUtil.responseHeaders(writer, 406, "Access-Control-Allow-Origin: *");
}
}
else {
HttpUtil.responseHeaders(writer, 400, "Access-Control-Allow-Origin: *");
}
}
else {
HttpUtil.responseHeaders(writer, 400, "Access-Control-Allow-Origin: *");
}
JSONObject responseJSON = new JSONObject();
Completion completion = databaseRepo.insertOrUpdatePuzzleResponse(received.getPuzzleId(), 3,
received.getFileName(), received.getSourceCode());
if (Arrays.equals(received.getResponse(), databaseRepo.getPuzzle(received.getPuzzleId()).getSoluce())) {
HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *", "Content-Type: application/json");
responseJSON.put("score", completion.getScore());
responseJSON.put("tries", completion.getTries());
} else if (completion != null) {
HttpUtil.responseHeaders(writer, 406, "Access-Control-Allow-Origin: *", "Content-Type: application/json");
responseJSON.put("tries", completion.getTries());
} else {
HttpUtil.responseHeaders(writer, 403, "Access-Control-Allow-Origin: *");
return;
} }
HttpUtil.responseHeaders(writer, 403, "Access-Control-Allow-Origin: *"); writer.write(responseJSON.toJSONString());
writer.flush();
writer.close();
}
private void saveSourceCode(ReceivedResponse received, Player player) throws IOException {
Path path = Paths.get(player.getPathToSourceCode() + received.getFileName());
Files.write(path, received.getSourceCode());
} }
@Override @Override
@ -82,3 +73,60 @@ public class PuzzleResponse implements Response {
return "POST"; return "POST";
} }
} }
class ReceivedResponse {
private int puzzleId;
private byte[] response;
private String fileName;
private byte[] sourceCode;
private HttpReader reader;
public ReceivedResponse(Matcher matcher, HttpReader reader) throws Exception {
this.reader = reader;
puzzleId = Integer.parseInt(matcher.group(1));
readResponse();
readFileName();
readSourceCode();
}
private void readResponse() throws Exception {
int hSize = reader.readInt();
response = new byte[hSize];
if (hSize != reader.read(response))
response = null;
}
private void readFileName() throws Exception {
byte[] tmpFileName;
int hSize = reader.readInt();
tmpFileName = new byte[hSize];
if (hSize == reader.read(tmpFileName))
fileName = tmpFileName.toString();
else
fileName = null;
}
private void readSourceCode() throws Exception {
int hSize = reader.readInt();
sourceCode = new byte[hSize];
if (hSize != reader.read(sourceCode))
sourceCode = null;
}
public int getPuzzleId() {
return puzzleId;
}
public byte[] getResponse() {
return response;
}
public String getFileName() {
return fileName;
}
public byte[] getSourceCode() {
return sourceCode;
}
}

View file

@ -1,10 +1,14 @@
package be.jeffcheasey88.peeratcode.routes; package be.jeffcheasey88.peeratcode.routes;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.json.simple.JSONObject; import org.json.simple.JSONObject;
import be.jeffcheasey88.peeratcode.model.Player;
import be.jeffcheasey88.peeratcode.repository.DatabaseRepository; import be.jeffcheasey88.peeratcode.repository.DatabaseRepository;
import be.jeffcheasey88.peeratcode.webserver.HttpReader; import be.jeffcheasey88.peeratcode.webserver.HttpReader;
import be.jeffcheasey88.peeratcode.webserver.HttpUtil; import be.jeffcheasey88.peeratcode.webserver.HttpUtil;
@ -49,10 +53,11 @@ public class Register implements Response {
boolean emailAvailable = databaseRepo.checkEmailAvailability(email); boolean emailAvailable = databaseRepo.checkEmailAvailability(email);
if (pseudoAvailable && emailAvailable) { if (pseudoAvailable && emailAvailable) {
int id; int id;
if ((id = databaseRepo.register(pseudo, email, password, firstname, lastname, description, group, avatar)) >= 0){ if ((id = databaseRepo.register(pseudo, email, password, firstname, lastname, description, group,
HttpUtil.responseHeaders(writer, 200, avatar)) >= 0) {
"Access-Control-Allow-Origin: *", HttpUtil.responseHeaders(writer, 200, "Access-Control-Allow-Origin: *",
"Authorization: Bearer "+this.router.createAuthUser(id)); "Authorization: Bearer " + this.router.createAuthUser(id));
createFolderToSaveSourceCode(pseudo);
return; return;
} }
} else { } else {
@ -67,13 +72,17 @@ public class Register implements Response {
HttpUtil.responseHeaders(writer, 403, "Access-Control-Allow-Origin: *"); HttpUtil.responseHeaders(writer, 403, "Access-Control-Allow-Origin: *");
} }
private void createFolderToSaveSourceCode(String pseudo) throws IOException {
Files.createDirectories(Paths.get(String.format(Player.PATH_TO_CODE, pseudo)));
}
@Override @Override
public Pattern getPattern() { public Pattern getPattern() {
return Pattern.compile("^\\/register$"); return Pattern.compile("^\\/register$");
} }
@Override @Override
public String getType(){ public String getType() {
return "POST"; return "POST";
} }